preserve state in CertifyKeyFragment

This commit is contained in:
Vincent Breitmoser 2015-05-29 21:07:56 +02:00
parent dd94c70fbe
commit c9f9af6603
2 changed files with 72 additions and 29 deletions

View File

@ -69,6 +69,9 @@ import java.util.ArrayList;
public class CertifyKeyFragment extends CryptoOperationFragment public class CertifyKeyFragment extends CryptoOperationFragment
implements LoaderManager.LoaderCallbacks<Cursor> { implements LoaderManager.LoaderCallbacks<Cursor> {
public static final String ARG_CHECK_STATES = "check_states";
public static final String ARG_CACHED_ACTIONS = "cached_actions";
private CheckBox mUploadKeyCheckbox; private CheckBox mUploadKeyCheckbox;
ListView mUserIds; ListView mUserIds;
@ -76,6 +79,8 @@ public class CertifyKeyFragment extends CryptoOperationFragment
private long[] mPubMasterKeyIds; private long[] mPubMasterKeyIds;
private CertifyActionsParcel mCachedActionsParcel;
public static final String[] USER_IDS_PROJECTION = new String[]{ public static final String[] USER_IDS_PROJECTION = new String[]{
UserPackets._ID, UserPackets._ID,
UserPackets.MASTER_KEY_ID, UserPackets.MASTER_KEY_ID,
@ -104,22 +109,36 @@ public class CertifyKeyFragment extends CryptoOperationFragment
mPassthroughMessenger = getActivity().getIntent().getParcelableExtra( mPassthroughMessenger = getActivity().getIntent().getParcelableExtra(
KeychainIntentService.EXTRA_MESSENGER); KeychainIntentService.EXTRA_MESSENGER);
mPassthroughMessenger = null; // TODO remove, development hack mPassthroughMessenger = null; // TODO doesn't work with CryptoOperationFragment, disabled for now
// preselect certify key id if given ArrayList<Boolean> checkedStates;
long certifyKeyId = getActivity().getIntent().getLongExtra(CertifyKeyActivity.EXTRA_CERTIFY_KEY_ID, Constants.key.none); if (savedInstanceState != null) {
if (certifyKeyId != Constants.key.none) { mCachedActionsParcel = savedInstanceState.getParcelable(ARG_CACHED_ACTIONS);
try { checkedStates = (ArrayList<Boolean>) savedInstanceState.getSerializable(ARG_CHECK_STATES);
CachedPublicKeyRing key = (new ProviderHelper(getActivity())).getCachedPublicKeyRing(certifyKeyId);
if (key.canCertify()) { // key spinner and the checkbox keep their own state
mCertifyKeySpinner.setPreSelectedKeyId(certifyKeyId);
} else {
mCachedActionsParcel = null;
checkedStates = null;
// preselect certify key id if given
long certifyKeyId = getActivity().getIntent()
.getLongExtra(CertifyKeyActivity.EXTRA_CERTIFY_KEY_ID, Constants.key.none);
if (certifyKeyId != Constants.key.none) {
try {
CachedPublicKeyRing key = (new ProviderHelper(getActivity())).getCachedPublicKeyRing(certifyKeyId);
if (key.canCertify()) {
mCertifyKeySpinner.setPreSelectedKeyId(certifyKeyId);
}
} catch (PgpKeyNotFoundException e) {
Log.e(Constants.TAG, "certify certify check failed", e);
} }
} catch (PgpKeyNotFoundException e) {
Log.e(Constants.TAG, "certify certify check failed", e);
} }
} }
mUserIdsAdapter = new MultiUserIdsAdapter(getActivity(), null, 0); mUserIdsAdapter = new MultiUserIdsAdapter(getActivity(), null, 0, checkedStates);
mUserIds.setAdapter(mUserIdsAdapter); mUserIds.setAdapter(mUserIdsAdapter);
mUserIds.setDividerHeight(0); mUserIds.setDividerHeight(0);
@ -132,6 +151,16 @@ public class CertifyKeyFragment extends CryptoOperationFragment
} }
} }
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
ArrayList<Boolean> states = mUserIdsAdapter.getCheckStates();
// no proper parceling method available :(
outState.putSerializable(ARG_CHECK_STATES, states);
outState.putParcelable(ARG_CACHED_ACTIONS, mCachedActionsParcel);
}
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup superContainer, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup superContainer, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.certify_key_fragment, null); View view = inflater.inflate(R.layout.certify_key_fragment, null);
@ -288,24 +317,28 @@ public class CertifyKeyFragment extends CryptoOperationFragment
@Override @Override
protected void cryptoOperation(CryptoInputParcel cryptoInput) { protected void cryptoOperation(CryptoInputParcel cryptoInput) {
// Bail out if there is not at least one user id selected
ArrayList<CertifyAction> certifyActions = mUserIdsAdapter.getSelectedCertifyActions();
if (certifyActions.isEmpty()) {
Notify.create(getActivity(), "No identities selected!",
Notify.Style.ERROR).show();
return;
}
Bundle data = new Bundle(); Bundle data = new Bundle();
{ {
long selectedKeyId = mCertifyKeySpinner.getSelectedKeyId();
// fill values for this action if (mCachedActionsParcel == null) {
CertifyActionsParcel parcel = new CertifyActionsParcel(selectedKeyId); // Bail out if there is not at least one user id selected
parcel.mCertifyActions.addAll(certifyActions); ArrayList<CertifyAction> certifyActions = mUserIdsAdapter.getSelectedCertifyActions();
if (certifyActions.isEmpty()) {
Notify.create(getActivity(), "No identities selected!",
Notify.Style.ERROR).show();
return;
}
long selectedKeyId = mCertifyKeySpinner.getSelectedKeyId();
// fill values for this action
mCachedActionsParcel = new CertifyActionsParcel(selectedKeyId);
mCachedActionsParcel.mCertifyActions.addAll(certifyActions);
}
data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput); data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput);
data.putParcelable(KeychainIntentService.CERTIFY_PARCEL, parcel); data.putParcelable(KeychainIntentService.CERTIFY_PARCEL, mCachedActionsParcel);
if (mUploadKeyCheckbox.isChecked()) { if (mUploadKeyCheckbox.isChecked()) {
String keyserver = Preferences.getPreferences(getActivity()).getPreferredKeyserver(); String keyserver = Preferences.getPreferences(getActivity()).getPreferredKeyserver();
data.putString(KeychainIntentService.UPLOAD_KEY_SERVER, keyserver); data.putString(KeychainIntentService.UPLOAD_KEY_SERVER, keyserver);
@ -368,4 +401,11 @@ public class CertifyKeyFragment extends CryptoOperationFragment
} }
@Override
protected void onCryptoOperationCancelled() {
super.onCryptoOperationCancelled();
// forget this ever happened
mCachedActionsParcel = null;
}
} }

View File

@ -40,20 +40,19 @@ public class MultiUserIdsAdapter extends CursorAdapter {
private LayoutInflater mInflater; private LayoutInflater mInflater;
private final ArrayList<Boolean> mCheckStates; private final ArrayList<Boolean> mCheckStates;
public MultiUserIdsAdapter(Context context, Cursor c, int flags) { public MultiUserIdsAdapter(Context context, Cursor c, int flags, ArrayList<Boolean> preselectStates) {
super(context, c, flags); super(context, c, flags);
mInflater = LayoutInflater.from(context); mInflater = LayoutInflater.from(context);
mCheckStates = new ArrayList<>(); mCheckStates = preselectStates == null ? new ArrayList<Boolean>() : preselectStates;
} }
@Override @Override
public Cursor swapCursor(Cursor newCursor) { public Cursor swapCursor(Cursor newCursor) {
mCheckStates.clear();
if (newCursor != null) { if (newCursor != null) {
int count = newCursor.getCount(); int count = newCursor.getCount();
mCheckStates.ensureCapacity(count); mCheckStates.ensureCapacity(count);
// initialize to true (use case knowledge: we usually want to sign all uids) // initialize new fields to true (use case knowledge: we usually want to sign all uids)
for (int i = 0; i < count; i++) { for (int i = mCheckStates.size(); i < count; i++) {
mCheckStates.add(true); mCheckStates.add(true);
} }
} }
@ -151,6 +150,10 @@ public class MultiUserIdsAdapter extends CursorAdapter {
} }
public ArrayList<Boolean> getCheckStates() {
return mCheckStates;
}
public ArrayList<CertifyAction> getSelectedCertifyActions() { public ArrayList<CertifyAction> getSelectedCertifyActions() {
LongSparseArray<CertifyAction> actions = new LongSparseArray<>(); LongSparseArray<CertifyAction> actions = new LongSparseArray<>();
for (int i = 0; i < mCheckStates.size(); i++) { for (int i = 0; i < mCheckStates.size(); i++) {