Load key data in tabs independently from advanced activity. This decouples the fragments from the activity and allows to init the tabs before loading key data in the advanced activity. Fixes switching to the first tab when key has been edited.

This commit is contained in:
Dominik Schürmann
2015-12-29 19:57:01 +01:00
parent ea3b258469
commit 621f8c2c70
3 changed files with 119 additions and 63 deletions

View File

@@ -25,7 +25,6 @@ import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
@@ -41,6 +40,7 @@ import android.view.animation.OvershootInterpolator;
import android.widget.Toast;
import com.astuetz.PagerSlidingTabStrip;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.operations.results.OperationResult;
@@ -113,6 +113,7 @@ public class ViewKeyAdvActivity extends BaseActivity implements
// or start new ones.
getSupportLoaderManager().initLoader(LOADER_ID_UNIFIED, null, this);
initTabs(mDataUri);
}
@Override
@@ -120,10 +121,7 @@ public class ViewKeyAdvActivity extends BaseActivity implements
setContentView(R.layout.view_key_adv_activity);
}
private void initTabs(Uri dataUri, boolean hasSecret, long masterKeyId, byte[] fingerprint) {
mHasSecret = hasSecret;
private void initTabs(Uri dataUri) {
mTabAdapter = new PagerTabStripAdapter(this);
mViewPager.setAdapter(mTabAdapter);
@@ -138,18 +136,12 @@ public class ViewKeyAdvActivity extends BaseActivity implements
Bundle userIdsBundle = new Bundle();
userIdsBundle.putParcelable(ViewKeyAdvUserIdsFragment.ARG_DATA_URI, dataUri);
userIdsBundle.putBoolean(ViewKeyAdvUserIdsFragment.ARG_HAS_SECRET, hasSecret);
userIdsBundle.putLong(ViewKeyAdvUserIdsFragment.ARG_MASTER_KEY_ID, masterKeyId);
userIdsBundle.putByteArray(ViewKeyAdvUserIdsFragment.ARG_FINGERPRINT, fingerprint);
mTabAdapter.addTab(ViewKeyAdvUserIdsFragment.class,
userIdsBundle, getString(R.string.section_user_ids));
mTabsWithActionMode[1] = true;
Bundle keysBundle = new Bundle();
keysBundle.putParcelable(ViewKeyAdvSubkeysFragment.ARG_DATA_URI, dataUri);
keysBundle.putBoolean(ViewKeyAdvSubkeysFragment.ARG_HAS_SECRET, hasSecret);
keysBundle.putLong(ViewKeyAdvSubkeysFragment.ARG_MASTER_KEY_ID, masterKeyId);
keysBundle.putByteArray(ViewKeyAdvSubkeysFragment.ARG_FINGERPRINT, fingerprint);
mTabAdapter.addTab(ViewKeyAdvSubkeysFragment.class,
keysBundle, getString(R.string.key_view_tab_keys));
mTabsWithActionMode[2] = true;
@@ -229,7 +221,7 @@ public class ViewKeyAdvActivity extends BaseActivity implements
long masterKeyId = data.getLong(INDEX_MASTER_KEY_ID);
getSupportActionBar().setSubtitle(KeyFormattingUtils.beautifyKeyIdWithPrefix(this, masterKeyId));
boolean isSecret = data.getInt(INDEX_HAS_ANY_SECRET) != 0;
mHasSecret = data.getInt(INDEX_HAS_ANY_SECRET) != 0;
boolean isRevoked = data.getInt(INDEX_IS_REVOKED) > 0;
boolean isExpired = data.getInt(INDEX_IS_EXPIRED) != 0;
boolean isVerified = data.getInt(INDEX_VERIFIED) > 0;
@@ -238,7 +230,7 @@ public class ViewKeyAdvActivity extends BaseActivity implements
int color;
if (isRevoked || isExpired) {
color = getResources().getColor(R.color.key_flag_red);
} else if (isSecret) {
} else if (mHasSecret) {
color = getResources().getColor(R.color.android_green_light);
} else {
if (isVerified) {
@@ -251,8 +243,6 @@ public class ViewKeyAdvActivity extends BaseActivity implements
mStatusBar.setBackgroundColor(ViewKeyActivity.getStatusBarBackgroundColor(color));
mSlidingTabLayout.setBackgroundColor(color);
initTabs(mDataUri, isSecret, masterKeyId, fingerprint);
break;
}
}
@@ -284,7 +274,7 @@ public class ViewKeyAdvActivity extends BaseActivity implements
// always add the item, switch its visibility depending on fragment
getMenuInflater().inflate(R.menu.action_mode_edit, menu);
final MenuItem vActionModeItem = menu.findItem(R.id.menu_action_mode_edit);
final MenuItem vActionModeItem = menu.findItem(R.id.menu_action_mode_edit);
boolean isCurrentActionFragment = mTabsWithActionMode[mViewPager.getCurrentItem()];

View File

@@ -60,11 +60,9 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements
LoaderManager.LoaderCallbacks<Cursor> {
public static final String ARG_DATA_URI = "data_uri";
public static final String ARG_HAS_SECRET = "has_secret";
public static final String ARG_MASTER_KEY_ID = "master_key_id";
public static final String ARG_FINGERPRINT = "fingerprint";
public static final int LOADER_ID_SUBKEYS = 0;
private static final int LOADER_ID_UNIFIED = 0;
private static final int LOADER_ID_SUBKEYS = 1;
private ListView mSubkeysList;
private ListView mSubkeysAddedList;
@@ -76,7 +74,7 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements
private CryptoOperationHelper<SaveKeyringParcel, EditKeyResult> mEditKeyHelper;
private Uri mDataUriSubkeys;
private Uri mDataUri;
private long mMasterKeyId;
private byte[] mFingerprint;
@@ -133,9 +131,6 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements
getActivity().finish();
return;
}
mHasSecret = getArguments().getBoolean(ARG_HAS_SECRET);
mMasterKeyId = getArguments().getLong(ARG_MASTER_KEY_ID);
mFingerprint = getArguments().getByteArray(ARG_FINGERPRINT);
loadData(dataUri);
}
@@ -150,7 +145,7 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements
}
private void loadData(Uri dataUri) {
mDataUriSubkeys = KeychainContract.Keys.buildKeysUri(dataUri);
mDataUri = dataUri;
// Create an empty adapter we will use to display the loaded data.
mSubkeysAdapter = new SubkeysAdapter(getActivity(), null, 0);
@@ -158,14 +153,42 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements
// Prepare the loaders. Either re-connect with an existing ones,
// or start new ones.
getLoaderManager().initLoader(LOADER_ID_UNIFIED, null, this);
getLoaderManager().initLoader(LOADER_ID_SUBKEYS, null, this);
}
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
setContentShown(false);
// These are the rows that we will retrieve.
static final String[] PROJECTION = new String[]{
KeychainContract.KeyRings._ID,
KeychainContract.KeyRings.MASTER_KEY_ID,
KeychainContract.KeyRings.HAS_ANY_SECRET,
KeychainContract.KeyRings.FINGERPRINT,
};
return new CursorLoader(getActivity(), mDataUriSubkeys,
SubkeysAdapter.SUBKEYS_PROJECTION, null, null, null);
static final int INDEX_MASTER_KEY_ID = 1;
static final int INDEX_HAS_ANY_SECRET = 2;
static final int INDEX_FINGERPRINT = 3;
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
switch (id) {
case LOADER_ID_UNIFIED: {
Uri baseUri = KeychainContract.KeyRings.buildUnifiedKeyRingUri(mDataUri);
return new CursorLoader(getActivity(), baseUri,
PROJECTION, null, null, null);
}
case LOADER_ID_SUBKEYS: {
setContentShown(false);
Uri subkeysUri = KeychainContract.Keys.buildKeysUri(mDataUri);
return new CursorLoader(getActivity(), subkeysUri,
SubkeysAdapter.SUBKEYS_PROJECTION, null, null, null);
}
default:
return null;
}
}
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
@@ -174,12 +197,26 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements
return;
}
// Swap the new cursor in. (The framework will take care of closing the
// old cursor once we return.)
mSubkeysAdapter.swapCursor(data);
switch (loader.getId()) {
case LOADER_ID_UNIFIED: {
data.moveToFirst();
mMasterKeyId = data.getLong(INDEX_MASTER_KEY_ID);
mHasSecret = data.getInt(INDEX_HAS_ANY_SECRET) != 0;
mFingerprint = data.getBlob(INDEX_FINGERPRINT);
break;
}
case LOADER_ID_SUBKEYS: {
// Swap the new cursor in. (The framework will take care of closing the
// old cursor once we return.)
mSubkeysAdapter.swapCursor(data);
// TODO: maybe show not before both are loaded!
setContentShown(true);
break;
}
}
// TODO: maybe show not before both are loaded!
setContentShown(true);
}
/**
@@ -244,7 +281,7 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements
mSubkeysAdapter.setEditMode(null);
mSubkeysAddedLayout.setVisibility(View.GONE);
mSubkeyAddFabLayout.setDisplayedChild(0);
getLoaderManager().restartLoader(0, null, ViewKeyAdvSubkeysFragment.this);
getLoaderManager().restartLoader(LOADER_ID_SUBKEYS, null, ViewKeyAdvSubkeysFragment.this);
}
});
}
@@ -422,12 +459,13 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements
@Override
public void onCryptoOperationCancelled() {
mode.finish();
}
@Override
public void onCryptoOperationError(EditKeyResult result) {
mode.finish();
result.createNotify(getActivity()).show();
}
@Override

View File

@@ -44,6 +44,7 @@ import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround;
import org.sufficientlysecure.keychain.operations.results.EditKeyResult;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter;
@@ -59,11 +60,9 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements
LoaderManager.LoaderCallbacks<Cursor> {
public static final String ARG_DATA_URI = "uri";
public static final String ARG_HAS_SECRET = "has_secret";
public static final String ARG_MASTER_KEY_ID = "master_key_id";
public static final String ARG_FINGERPRINT = "fingerprint";
private static final int LOADER_ID_USER_IDS = 0;
private static final int LOADER_ID_UNIFIED = 0;
private static final int LOADER_ID_USER_IDS = 1;
private ListView mUserIds;
private ListView mUserIdsAddedList;
@@ -226,9 +225,6 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements
getActivity().finish();
return;
}
mHasSecret = getArguments().getBoolean(ARG_HAS_SECRET);
mMasterKeyId = getArguments().getLong(ARG_MASTER_KEY_ID);
mFingerprint = getArguments().getByteArray(ARG_FINGERPRINT);
loadData(dataUri);
}
@@ -252,36 +248,67 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements
// Prepare the loaders. Either re-connect with an existing ones,
// or start new ones.
getLoaderManager().initLoader(LOADER_ID_UNIFIED, null, this);
getLoaderManager().initLoader(LOADER_ID_USER_IDS, null, this);
}
// These are the rows that we will retrieve.
static final String[] PROJECTION = new String[]{
KeychainContract.KeyRings._ID,
KeychainContract.KeyRings.MASTER_KEY_ID,
KeychainContract.KeyRings.HAS_ANY_SECRET,
KeychainContract.KeyRings.FINGERPRINT,
};
static final int INDEX_MASTER_KEY_ID = 1;
static final int INDEX_HAS_ANY_SECRET = 2;
static final int INDEX_FINGERPRINT = 3;
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
setContentShown(false);
switch (id) {
case LOADER_ID_UNIFIED: {
Uri baseUri = KeychainContract.KeyRings.buildUnifiedKeyRingUri(mDataUri);
return new CursorLoader(getActivity(), baseUri,
PROJECTION, null, null, null);
}
if (id != LOADER_ID_USER_IDS) {
return null;
case LOADER_ID_USER_IDS: {
setContentShown(false);
Uri userIdUri = UserPackets.buildUserIdsUri(mDataUri);
return new CursorLoader(getActivity(), userIdUri,
UserIdsAdapter.USER_PACKETS_PROJECTION, null, null, null);
}
default:
return null;
}
Uri baseUri = UserPackets.buildUserIdsUri(mDataUri);
return new CursorLoader(getActivity(), baseUri,
UserIdsAdapter.USER_PACKETS_PROJECTION, null, null, null);
}
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
if (loader.getId() != LOADER_ID_USER_IDS) {
return;
}
/* TODO better error handling? May cause problems when a key is deleted,
* because the notification triggers faster than the activity closes.
*/
// Avoid NullPointerExceptions...
// Avoid NullPointerExceptions, if we get an empty result set.
if (data.getCount() == 0) {
return;
}
mUserIdsAdapter.swapCursor(data);
setContentShown(true);
switch (loader.getId()) {
case LOADER_ID_UNIFIED: {
data.moveToFirst();
mMasterKeyId = data.getLong(INDEX_MASTER_KEY_ID);
mHasSecret = data.getInt(INDEX_HAS_ANY_SECRET) != 0;
mFingerprint = data.getBlob(INDEX_FINGERPRINT);
break;
}
case LOADER_ID_USER_IDS: {
// Swap the new cursor in. (The framework will take care of closing the
// old cursor once we return.)
mUserIdsAdapter.swapCursor(data);
setContentShown(true);
break;
}
}
}
/**
@@ -371,12 +398,13 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements
@Override
public void onCryptoOperationCancelled() {
mode.finish();
}
@Override
public void onCryptoOperationError(EditKeyResult result) {
mode.finish();
result.createNotify(getActivity()).show();
}
@Override