From 6c17734e73818cb2b562470dd71063169fbe1ac7 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Wed, 27 May 2015 21:15:36 +0200 Subject: rewrite EncryptActivity data flow --- .../keychain/ui/CertifyKeyFragment.java | 16 +- .../keychain/ui/EncryptActivity.java | 77 +++++++++ .../keychain/ui/EncryptFilesActivity.java | 79 +--------- .../keychain/ui/EncryptFilesFragment.java | 173 +++++++++------------ .../keychain/ui/EncryptModeAsymmetricFragment.java | 111 +++++-------- .../keychain/ui/EncryptModeFragment.java | 19 +++ .../keychain/ui/EncryptModeSymmetricFragment.java | 86 +++++----- .../keychain/ui/EncryptTextActivity.java | 70 +-------- .../keychain/ui/EncryptTextFragment.java | 167 ++++++++------------ .../keychain/ui/widget/KeySpinner.java | 25 +-- 10 files changed, 346 insertions(+), 477 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptModeFragment.java (limited to 'OpenKeychain/src/main') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java index 59623a610..df755edef 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java @@ -77,8 +77,6 @@ public class CertifyKeyFragment extends CryptoOperationFragment private long[] mPubMasterKeyIds; - private long mSignMasterKeyId = Constants.key.none; - public static final String[] USER_IDS_PROJECTION = new String[]{ UserPackets._ID, UserPackets.MASTER_KEY_ID, @@ -149,19 +147,13 @@ public class CertifyKeyFragment extends CryptoOperationFragment vActionCertifyImage.setColorFilter(getResources().getColor(R.color.tertiary_text_light), PorterDuff.Mode.SRC_IN); - mCertifyKeySpinner.setOnKeyChangedListener(new KeySpinner.OnKeyChangedListener() { - @Override - public void onKeyChanged(long masterKeyId) { - mSignMasterKeyId = masterKeyId; - } - }); - View vCertifyButton = view.findViewById(R.id.certify_key_certify_button); vCertifyButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - if (mSignMasterKeyId == Constants.key.none) { + long selectedKeyId = mCertifyKeySpinner.getSelectedKeyId(); + if (selectedKeyId == Constants.key.none) { Notify.create(getActivity(), getString(R.string.select_key_to_certify), Notify.Style.ERROR).show(); } else { @@ -307,8 +299,10 @@ public class CertifyKeyFragment extends CryptoOperationFragment Bundle data = new Bundle(); { + long selectedKeyId = mCertifyKeySpinner.getSelectedKeyId(); + // fill values for this action - CertifyActionsParcel parcel = new CertifyActionsParcel(mSignMasterKeyId); + CertifyActionsParcel parcel = new CertifyActionsParcel(selectedKeyId); parcel.mCertifyActions.addAll(certifyActions); data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java new file mode 100644 index 000000000..9fd3a4988 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2015 Vincent Breitmoser + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.sufficientlysecure.keychain.ui; + +import android.content.Intent; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentTransaction; + +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.ui.base.BaseActivity; + +public class EncryptActivity extends BaseActivity { + + // preselect ids, for internal use + public static final String EXTRA_SIGNATURE_KEY_ID = Constants.EXTRA_PREFIX + "EXTRA_SIGNATURE_KEY_ID"; + public static final String EXTRA_ENCRYPTION_KEY_IDS = Constants.EXTRA_PREFIX + "EXTRA_SIGNATURE_KEY_IDS"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Intent intent = getIntent(); + Bundle extras = intent.getExtras(); + + if (extras == null) { + extras = new Bundle(); + } + + if (savedInstanceState == null) { + FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); + + // preselect keys given by intent + long signingKeyId = extras.getLong(EXTRA_SIGNATURE_KEY_ID); + long[] encryptionKeyIds = extras.getLongArray(EXTRA_ENCRYPTION_KEY_IDS); + + Fragment modeFragment = EncryptModeAsymmetricFragment.newInstance(signingKeyId, encryptionKeyIds); + transaction.replace(R.id.encrypt_mode_container, modeFragment); + transaction.commit(); + } + } + + public void toggleModeFragment() { + boolean symmetric = getModeFragment() instanceof EncryptModeAsymmetricFragment; + + FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); + transaction.replace(R.id.encrypt_mode_container, + symmetric + ? EncryptModeSymmetricFragment.newInstance() + : EncryptModeAsymmetricFragment.newInstance(0, null) + ); + + // doesn't matter if the user doesn't look at the activity + transaction.commitAllowingStateLoss(); + } + + public EncryptModeFragment getModeFragment() { + return (EncryptModeFragment) + getSupportFragmentManager().findFragmentById(R.id.encrypt_mode_container); + } +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java index b3ec60890..45700f978 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java @@ -18,39 +18,25 @@ package org.sufficientlysecure.keychain.ui; -import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; -import android.support.v4.app.Fragment; import android.support.v4.app.FragmentTransaction; import android.view.View; -import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.intents.OpenKeychainIntents; -import org.sufficientlysecure.keychain.ui.base.BaseActivity; -import org.sufficientlysecure.keychain.util.Passphrase; import java.util.ArrayList; -public class EncryptFilesActivity extends BaseActivity implements - EncryptModeAsymmetricFragment.IAsymmetric, EncryptModeSymmetricFragment.ISymmetric, - EncryptFilesFragment.IMode { +public class EncryptFilesActivity extends EncryptActivity { - /* Intents */ + // Intents public static final String ACTION_ENCRYPT_DATA = OpenKeychainIntents.ENCRYPT_DATA; // enables ASCII Armor for file encryption when uri is given public static final String EXTRA_ASCII_ARMOR = OpenKeychainIntents.ENCRYPT_EXTRA_ASCII_ARMOR; - // preselect ids, for internal use - public static final String EXTRA_SIGNATURE_KEY_ID = Constants.EXTRA_PREFIX + "EXTRA_SIGNATURE_KEY_ID"; - public static final String EXTRA_ENCRYPTION_KEY_IDS = Constants.EXTRA_PREFIX + "EXTRA_ENCRYPTION_IDS"; - - Fragment mModeFragment; - EncryptFilesFragment mEncryptFragment; - @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -62,19 +48,7 @@ public class EncryptFilesActivity extends BaseActivity implements } }, false); - // Handle intent actions - handleActions(getIntent(), savedInstanceState); - } - - @Override - protected void initLayout() { - setContentView(R.layout.encrypt_files_activity); - } - - /** - * Handles all actions with this intent - */ - private void handleActions(Intent intent, Bundle savedInstanceState) { + Intent intent = getIntent(); String action = intent.getAction(); Bundle extras = intent.getExtras(); String type = intent.getType(); @@ -88,10 +62,6 @@ public class EncryptFilesActivity extends BaseActivity implements uris.add(intent.getData()); } - /* - * Android's Action - */ - // When sending to OpenKeychain Encrypt via share menu if (Intent.ACTION_SEND.equals(action) && type != null) { // Files via content provider, override uri and action @@ -103,56 +73,21 @@ public class EncryptFilesActivity extends BaseActivity implements uris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); } - long mSigningKeyId = extras.getLong(EXTRA_SIGNATURE_KEY_ID); - long[] mEncryptionKeyIds = extras.getLongArray(EXTRA_ENCRYPTION_KEY_IDS); boolean useArmor = extras.getBoolean(EXTRA_ASCII_ARMOR, false); if (savedInstanceState == null) { FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); - mModeFragment = EncryptModeAsymmetricFragment.newInstance(mSigningKeyId, mEncryptionKeyIds); - transaction.replace(R.id.encrypt_mode_container, mModeFragment, "mode"); - - mEncryptFragment = EncryptFilesFragment.newInstance(uris, useArmor); - transaction.replace(R.id.encrypt_file_container, mEncryptFragment, "files"); - + EncryptFilesFragment encryptFragment = EncryptFilesFragment.newInstance(uris, useArmor); + transaction.replace(R.id.encrypt_file_container, encryptFragment); transaction.commit(); - - getSupportFragmentManager().executePendingTransactions(); } - } - @Override - public void onModeChanged(boolean symmetric) { - // switch fragments - getSupportFragmentManager().beginTransaction() - .replace(R.id.encrypt_mode_container, - symmetric - ? EncryptModeSymmetricFragment.newInstance() - : EncryptModeAsymmetricFragment.newInstance(0, null) - ) - .commitAllowingStateLoss(); - getSupportFragmentManager().executePendingTransactions(); } @Override - public void onSignatureKeyIdChanged(long signatureKeyId) { - mEncryptFragment.setSigningKeyId(signatureKeyId); - } - - @Override - public void onEncryptionKeyIdsChanged(long[] encryptionKeyIds) { - mEncryptFragment.setEncryptionKeyIds(encryptionKeyIds); - } - - @Override - public void onEncryptionUserIdsChanged(String[] encryptionUserIds) { - mEncryptFragment.setEncryptionUserIds(encryptionUserIds); - } - - @Override - public void onPassphraseChanged(Passphrase passphrase) { - mEncryptFragment.setPassphrase(passphrase); + protected void initLayout() { + setContentView(R.layout.encrypt_files_activity); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java index 458810541..fa35cc9ac 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java @@ -72,19 +72,12 @@ import java.util.Set; public class EncryptFilesFragment extends CryptoOperationFragment { - public interface IMode { - public void onModeChanged(boolean symmetric); - } - public static final String ARG_USE_ASCII_ARMOR = "use_ascii_armor"; public static final String ARG_URIS = "uris"; private static final int REQUEST_CODE_INPUT = 0x00007003; private static final int REQUEST_CODE_OUTPUT = 0x00007007; - private IMode mModeInterface; - - private boolean mSymmetricMode = false; private boolean mUseArmor = false; private boolean mUseCompression = true; private boolean mDeleteAfterEncrypt = false; @@ -92,11 +85,6 @@ public class EncryptFilesFragment extends CryptoOperationFragment { private boolean mEncryptFilenames = true; private boolean mHiddenRecipients = false; - private long mEncryptionKeyIds[] = null; - private String mEncryptionUserIds[] = null; - private long mSigningKeyId = Constants.key.none; - private Passphrase mPassphrase = new Passphrase(); - private ArrayList mOutputUris = new ArrayList<>(); private RecyclerView mSelectedFiles; @@ -118,29 +106,11 @@ public class EncryptFilesFragment extends CryptoOperationFragment { return frag; } - public void setEncryptionKeyIds(long[] encryptionKeyIds) { - mEncryptionKeyIds = encryptionKeyIds; - } - - public void setEncryptionUserIds(String[] encryptionUserIds) { - mEncryptionUserIds = encryptionUserIds; - } - - public void setSigningKeyId(long signingKeyId) { - mSigningKeyId = signingKeyId; - } - - public void setPassphrase(Passphrase passphrase) { - mPassphrase = passphrase; - } - @Override public void onAttach(Activity activity) { super.onAttach(activity); - try { - mModeInterface = (IMode) activity; - } catch (ClassCastException e) { - throw new ClassCastException(activity + " must be IMode"); + if ( ! (activity instanceof EncryptActivity) ) { + throw new AssertionError(activity + " must inherit from EncryptionActivity"); } } @@ -293,8 +263,8 @@ public class EncryptFilesFragment extends CryptoOperationFragment { break; } case R.id.check_use_symmetric: { - mSymmetricMode = item.isChecked(); - mModeInterface.onModeChanged(mSymmetricMode); + EncryptActivity encryptActivity = (EncryptActivity) getActivity(); + encryptActivity.toggleModeFragment(); break; } case R.id.check_use_armor: { @@ -325,53 +295,6 @@ public class EncryptFilesFragment extends CryptoOperationFragment { return true; } - protected boolean inputIsValid() { - // file checks - - if (mFilesModels.isEmpty()) { - Notify.create(getActivity(), R.string.no_file_selected, Notify.Style.ERROR) - .show(this); - return false; - } else if (mFilesModels.size() > 1 && !mShareAfterEncrypt) { - Log.e(Constants.TAG, "Aborting: mInputUris.size() > 1 && !mShareAfterEncrypt"); - // This should be impossible... - return false; - } else if (mFilesModels.size() != mOutputUris.size()) { - Log.e(Constants.TAG, "Aborting: mInputUris.size() != mOutputUris.size()"); - // This as well - return false; - } - - if (mSymmetricMode) { - // symmetric encryption checks - - if (mPassphrase == null) { - Notify.create(getActivity(), R.string.passphrases_do_not_match, Notify.Style.ERROR) - .show(this); - return false; - } - if (mPassphrase.isEmpty()) { - Notify.create(getActivity(), R.string.passphrase_must_not_be_empty, Notify.Style.ERROR) - .show(this); - return false; - } - - } else { - // asymmetric encryption checks - - boolean gotEncryptionKeys = (mEncryptionKeyIds != null - && mEncryptionKeyIds.length > 0); - - // Files must be encrypted, only text can be signed-only right now - if (!gotEncryptionKeys) { - Notify.create(getActivity(), R.string.select_encryption_key, Notify.Style.ERROR) - .show(this); - return false; - } - } - return true; - } - public void onEncryptSuccess(final SignEncryptResult result) { if (mDeleteAfterEncrypt) { DeleteFileDialogFragment deleteFileDialog = @@ -403,6 +326,21 @@ public class EncryptFilesFragment extends CryptoOperationFragment { } protected SignEncryptParcel createEncryptBundle() { + + if (mFilesModels.isEmpty()) { + Notify.create(getActivity(), R.string.no_file_selected, Notify.Style.ERROR) + .show(this); + return null; + } else if (mFilesModels.size() > 1 && !mShareAfterEncrypt) { + Log.e(Constants.TAG, "Aborting: mInputUris.size() > 1 && !mShareAfterEncrypt"); + // This should be impossible... + return null; + } else if (mFilesModels.size() != mOutputUris.size()) { + Log.e(Constants.TAG, "Aborting: mInputUris.size() != mOutputUris.size()"); + // This as well + return null; + } + // fill values for this action SignEncryptParcel data = new SignEncryptParcel(); @@ -419,17 +357,39 @@ public class EncryptFilesFragment extends CryptoOperationFragment { data.setSymmetricEncryptionAlgorithm(PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED); data.setSignatureHashAlgorithm(PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED); - if (mSymmetricMode) { - Log.d(Constants.TAG, "Symmetric encryption enabled!"); - Passphrase passphrase = mPassphrase; + EncryptActivity encryptActivity = (EncryptActivity) getActivity(); + EncryptModeFragment modeFragment = encryptActivity.getModeFragment(); + + if (modeFragment.isAsymmetric()) { + long[] encryptionKeyIds = modeFragment.getAsymmetricEncryptionKeyIds(); + long signingKeyId = modeFragment.getAsymmetricSigningKeyId(); + + boolean gotEncryptionKeys = (encryptionKeyIds != null + && encryptionKeyIds.length > 0); + + if (!gotEncryptionKeys && signingKeyId == 0) { + Notify.create(getActivity(), R.string.select_encryption_or_signature_key, Notify.Style.ERROR) + .show(this); + return null; + } + + data.setEncryptionMasterKeyIds(encryptionKeyIds); + data.setSignatureMasterKeyId(signingKeyId); + } else { + Passphrase passphrase = modeFragment.getSymmetricPassphrase(); + if (passphrase == null) { + Notify.create(getActivity(), R.string.passphrases_do_not_match, Notify.Style.ERROR) + .show(this); + return null; + } if (passphrase.isEmpty()) { - passphrase = null; + Notify.create(getActivity(), R.string.passphrase_must_not_be_empty, Notify.Style.ERROR) + .show(this); + return null; } data.setSymmetricPassphrase(passphrase); - } else { - data.setEncryptionMasterKeyIds(mEncryptionKeyIds); - data.setSignatureMasterKeyId(mSigningKeyId); } + return data; } @@ -461,16 +421,27 @@ public class EncryptFilesFragment extends CryptoOperationFragment { } sendIntent.setType(Constants.ENCRYPTED_FILES_MIME); - if (!mSymmetricMode && mEncryptionUserIds != null) { - Set users = new HashSet<>(); - for (String user : mEncryptionUserIds) { - KeyRing.UserId userId = KeyRing.splitUserId(user); - if (userId.email != null) { - users.add(userId.email); - } + EncryptActivity modeInterface = (EncryptActivity) getActivity(); + EncryptModeFragment modeFragment = modeInterface.getModeFragment(); + if (!modeFragment.isAsymmetric()) { + return sendIntent; + } + + String[] encryptionUserIds = modeFragment.getAsymmetricEncryptionUserIds(); + if (encryptionUserIds == null) { + return sendIntent; + } + + Set users = new HashSet<>(); + for (String user : encryptionUserIds) { + KeyRing.UserId userId = KeyRing.splitUserId(user); + if (userId.email != null) { + users.add(userId.email); } - sendIntent.putExtra(Intent.EXTRA_EMAIL, users.toArray(new String[users.size()])); } + // pass trough email addresses as extra for email applications + sendIntent.putExtra(Intent.EXTRA_EMAIL, users.toArray(new String[users.size()])); + return sendIntent; } @@ -482,19 +453,17 @@ public class EncryptFilesFragment extends CryptoOperationFragment { @Override protected void cryptoOperation(CryptoInputParcel cryptoInput) { - if (!inputIsValid()) { + final SignEncryptParcel input = createEncryptBundle(); + // this is null if invalid, just return in that case + if (input == null) { // Notify was created by inputIsValid. - Log.d(Constants.TAG, "Input not valid!"); return; } - Log.d(Constants.TAG, "Input valid!"); // Send all information needed to service to edit key in other thread Intent intent = new Intent(getActivity(), KeychainIntentService.class); intent.setAction(KeychainIntentService.ACTION_SIGN_ENCRYPT); - final SignEncryptParcel input = createEncryptBundle(); - Bundle data = new Bundle(); data.putParcelable(KeychainIntentService.SIGN_ENCRYPT_PARCEL, input); data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput); @@ -727,7 +696,7 @@ public class EncryptFilesFragment extends CryptoOperationFragment { for (Uri inputUri : inputUris) { ViewModel newModel = new ViewModel(mActivity, inputUri); if (mDataset.contains(newModel)) { - Log.e(Constants.TAG, "Skipped duplicate " + inputUri.toString()); + Log.e(Constants.TAG, "Skipped duplicate " + inputUri); } else { mDataset.add(newModel); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptModeAsymmetricFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptModeAsymmetricFragment.java index 6f56f2dc4..758d5f51a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptModeAsymmetricFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptModeAsymmetricFragment.java @@ -17,18 +17,13 @@ package org.sufficientlysecure.keychain.ui; -import android.app.Activity; import android.os.Bundle; -import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import com.tokenautocomplete.TokenCompleteTextView; - import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKey; import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing; import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing; @@ -39,38 +34,19 @@ import org.sufficientlysecure.keychain.ui.adapter.KeyAdapter.KeyItem; import org.sufficientlysecure.keychain.ui.widget.EncryptKeyCompletionView; import org.sufficientlysecure.keychain.ui.widget.KeySpinner; import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.Passphrase; import java.util.ArrayList; import java.util.Iterator; import java.util.List; -public class EncryptModeAsymmetricFragment extends Fragment { - - public interface IAsymmetric { - - public void onSignatureKeyIdChanged(long signatureKeyId); - - public void onEncryptionKeyIdsChanged(long[] encryptionKeyIds); - - public void onEncryptionUserIdsChanged(String[] encryptionUserIds); - } +public class EncryptModeAsymmetricFragment extends EncryptModeFragment { ProviderHelper mProviderHelper; - // view - private KeySpinner mSign; + private KeySpinner mSignKeySpinner; private EncryptKeyCompletionView mEncryptKeyView; - // model - private IAsymmetric mEncryptInterface; - -// @Override -// public void updateUi() { -// if (mSign != null) { -// mSign.setSelectedKeyId(mEncryptInterface.getSignatureKey()); -// } -// } - public static final String ARG_SINGATURE_KEY_ID = "signature_key_id"; public static final String ARG_ENCRYPTION_KEY_IDS = "encryption_key_ids"; @@ -89,16 +65,6 @@ public class EncryptModeAsymmetricFragment extends Fragment { return frag; } - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - try { - mEncryptInterface = (IAsymmetric) activity; - } catch (ClassCastException e) { - throw new ClassCastException(activity + " must implement IAsymmetric"); - } - } - /** * Inflate the layout for this fragment */ @@ -106,13 +72,7 @@ public class EncryptModeAsymmetricFragment extends Fragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.encrypt_asymmetric_fragment, container, false); - mSign = (KeySpinner) view.findViewById(R.id.sign); - mSign.setOnKeyChangedListener(new KeySpinner.OnKeyChangedListener() { - @Override - public void onKeyChanged(long masterKeyId) { - mEncryptInterface.onSignatureKeyIdChanged(masterKeyId); - } - }); + mSignKeySpinner = (KeySpinner) view.findViewById(R.id.sign); mEncryptKeyView = (EncryptKeyCompletionView) view.findViewById(R.id.recipient_list); mEncryptKeyView.setThreshold(1); // Start working from first character @@ -128,22 +88,6 @@ public class EncryptModeAsymmetricFragment extends Fragment { long signatureKeyId = getArguments().getLong(ARG_SINGATURE_KEY_ID); long[] encryptionKeyIds = getArguments().getLongArray(ARG_ENCRYPTION_KEY_IDS); preselectKeys(signatureKeyId, encryptionKeyIds); - - mEncryptKeyView.setTokenListener(new TokenCompleteTextView.TokenListener() { - @Override - public void onTokenAdded(Object token) { - if (token instanceof KeyItem) { - updateEncryptionKeys(); - } - } - - @Override - public void onTokenRemoved(Object token) { - if (token instanceof KeyItem) { - updateEncryptionKeys(); - } - } - }); } /** @@ -155,8 +99,7 @@ public class EncryptModeAsymmetricFragment extends Fragment { CachedPublicKeyRing keyring = mProviderHelper.getCachedPublicKeyRing( KeyRings.buildUnifiedKeyRingUri(signatureKeyId)); if (keyring.hasAnySecret()) { - mEncryptInterface.onSignatureKeyIdChanged(keyring.getMasterKeyId()); - mSign.setSelectedKeyId(signatureKeyId); + mSignKeySpinner.setSelectedKeyId(signatureKeyId); } } catch (PgpKeyNotFoundException e) { Log.e(Constants.TAG, "key not found!", e); @@ -175,27 +118,55 @@ public class EncryptModeAsymmetricFragment extends Fragment { } // This is to work-around a rendering bug in TokenCompleteTextView mEncryptKeyView.requestFocus(); - updateEncryptionKeys(); } } - private void updateEncryptionKeys() { - List objects = mEncryptKeyView.getObjects(); + @Override + public boolean isAsymmetric() { + return true; + } + + @Override + public long getAsymmetricSigningKeyId() { + return mSignKeySpinner.getSelectedItemId(); + } + + @Override + public long[] getAsymmetricEncryptionKeyIds() { List keyIds = new ArrayList<>(); - List userIds = new ArrayList<>(); - for (Object object : objects) { + for (Object object : mEncryptKeyView.getObjects()) { if (object instanceof KeyItem) { keyIds.add(((KeyItem) object).mKeyId); - userIds.add(((KeyItem) object).mUserIdFull); } } + long[] keyIdsArr = new long[keyIds.size()]; Iterator iterator = keyIds.iterator(); for (int i = 0; i < keyIds.size(); i++) { keyIdsArr[i] = iterator.next(); } - mEncryptInterface.onEncryptionKeyIdsChanged(keyIdsArr); - mEncryptInterface.onEncryptionUserIdsChanged(userIds.toArray(new String[userIds.size()])); + + return keyIdsArr; + } + + @Override + public String[] getAsymmetricEncryptionUserIds() { + + List userIds = new ArrayList<>(); + for (Object object : mEncryptKeyView.getObjects()) { + if (object instanceof KeyItem) { + userIds.add(((KeyItem) object).mUserIdFull); + } + } + + return userIds.toArray(new String[userIds.size()]); + } + + @Override + public Passphrase getSymmetricPassphrase() { + throw new UnsupportedOperationException("should never happen, this is a programming error!"); + } + } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptModeFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptModeFragment.java new file mode 100644 index 000000000..0b9672654 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptModeFragment.java @@ -0,0 +1,19 @@ +package org.sufficientlysecure.keychain.ui; + + +import android.support.v4.app.Fragment; + +import org.sufficientlysecure.keychain.util.Passphrase; + + +public abstract class EncryptModeFragment extends Fragment { + + public abstract boolean isAsymmetric(); + + public abstract long getAsymmetricSigningKeyId(); + public abstract long[] getAsymmetricEncryptionKeyIds(); + public abstract String[] getAsymmetricEncryptionUserIds(); + + public abstract Passphrase getSymmetricPassphrase(); + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptModeSymmetricFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptModeSymmetricFragment.java index 48b1f4983..b92a73731 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptModeSymmetricFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptModeSymmetricFragment.java @@ -17,11 +17,7 @@ package org.sufficientlysecure.keychain.ui; -import android.app.Activity; import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.text.Editable; -import android.text.TextWatcher; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -30,14 +26,7 @@ import android.widget.EditText; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.util.Passphrase; -public class EncryptModeSymmetricFragment extends Fragment { - - public interface ISymmetric { - - public void onPassphraseChanged(Passphrase passphrase); - } - - private ISymmetric mEncryptInterface; +public class EncryptModeSymmetricFragment extends EncryptModeFragment { private EditText mPassphrase; private EditText mPassphraseAgain; @@ -54,53 +43,54 @@ public class EncryptModeSymmetricFragment extends Fragment { return frag; } - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - try { - mEncryptInterface = (ISymmetric) activity; - } catch (ClassCastException e) { - throw new ClassCastException(activity.toString() + " must implement ISymmetric"); - } - } - - /** - * Inflate the layout for this fragment - */ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.encrypt_symmetric_fragment, container, false); mPassphrase = (EditText) view.findViewById(R.id.passphrase); mPassphraseAgain = (EditText) view.findViewById(R.id.passphraseAgain); - TextWatcher textWatcher = new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - } + return view; + } + + @Override + public boolean isAsymmetric() { + return false; + } - @Override - public void afterTextChanged(Editable s) { - // update passphrase in EncryptActivity - Passphrase p1 = new Passphrase(mPassphrase.getText()); - Passphrase p2 = new Passphrase(mPassphraseAgain.getText()); - boolean passesEquals = (p1.equals(p2)); + @Override + public long getAsymmetricSigningKeyId() { + throw new UnsupportedOperationException("should never happen, this is a programming error!"); + } + + @Override + public long[] getAsymmetricEncryptionKeyIds() { + throw new UnsupportedOperationException("should never happen, this is a programming error!"); + } + + @Override + public String[] getAsymmetricEncryptionUserIds() { + throw new UnsupportedOperationException("should never happen, this is a programming error!"); + } + + @Override + public Passphrase getSymmetricPassphrase() { + Passphrase p1 = null, p2 = null; + try { + p1 = new Passphrase(mPassphrase.getText()); + p2 = new Passphrase(mPassphraseAgain.getText()); + if (!p1.equals(p2)) { + return null; + } + return new Passphrase(mPassphrase.getText()); + } finally { + if (p1 != null) { p1.removeFromMemory(); + } + if (p2 != null) { p2.removeFromMemory(); - if (passesEquals) { - mEncryptInterface.onPassphraseChanged(new Passphrase(mPassphrase.getText())); - } else { - mEncryptInterface.onPassphraseChanged(null); - } } - }; - mPassphrase.addTextChangedListener(textWatcher); - mPassphraseAgain.addTextChangedListener(textWatcher); - - return view; + } } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java index 82f057895..cb26ea452 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java @@ -20,20 +20,14 @@ package org.sufficientlysecure.keychain.ui; import android.content.Intent; import android.os.Bundle; -import android.support.v4.app.Fragment; import android.support.v4.app.FragmentTransaction; import android.view.View; -import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.intents.OpenKeychainIntents; -import org.sufficientlysecure.keychain.ui.base.BaseActivity; import org.sufficientlysecure.keychain.util.Log; -import org.sufficientlysecure.keychain.util.Passphrase; -public class EncryptTextActivity extends BaseActivity implements - EncryptModeAsymmetricFragment.IAsymmetric, EncryptModeSymmetricFragment.ISymmetric, - EncryptTextFragment.IMode { +public class EncryptTextActivity extends EncryptActivity { /* Intents */ public static final String ACTION_ENCRYPT_TEXT = OpenKeychainIntents.ENCRYPT_TEXT; @@ -41,13 +35,6 @@ public class EncryptTextActivity extends BaseActivity implements /* EXTRA keys for input */ public static final String EXTRA_TEXT = OpenKeychainIntents.ENCRYPT_EXTRA_TEXT; - // preselect ids, for internal use - public static final String EXTRA_SIGNATURE_KEY_ID = Constants.EXTRA_PREFIX + "EXTRA_SIGNATURE_KEY_ID"; - public static final String EXTRA_ENCRYPTION_KEY_IDS = Constants.EXTRA_PREFIX + "EXTRA_SIGNATURE_KEY_IDS"; - - Fragment mModeFragment; - EncryptTextFragment mEncryptFragment; - @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -89,23 +76,14 @@ public class EncryptTextActivity extends BaseActivity implements textData = ""; } - // preselect keys given by intent - long mSigningKeyId = extras.getLong(EXTRA_SIGNATURE_KEY_ID); - long[] mEncryptionKeyIds = extras.getLongArray(EXTRA_ENCRYPTION_KEY_IDS); - if (savedInstanceState == null) { FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); - mModeFragment = EncryptModeAsymmetricFragment.newInstance(mSigningKeyId, mEncryptionKeyIds); - transaction.replace(R.id.encrypt_mode_container, mModeFragment, "mode"); - - mEncryptFragment = EncryptTextFragment.newInstance(textData); - transaction.replace(R.id.encrypt_text_container, mEncryptFragment, "text"); - + EncryptTextFragment encryptFragment = EncryptTextFragment.newInstance(textData); + transaction.replace(R.id.encrypt_text_container, encryptFragment); transaction.commit(); - - getSupportFragmentManager().executePendingTransactions(); } + } @Override @@ -113,44 +91,4 @@ public class EncryptTextActivity extends BaseActivity implements setContentView(R.layout.encrypt_text_activity); } - @Override - public void onModeChanged(boolean symmetric) { - // switch fragments - getSupportFragmentManager().beginTransaction() - .replace(R.id.encrypt_mode_container, - symmetric - ? EncryptModeSymmetricFragment.newInstance() - : EncryptModeAsymmetricFragment.newInstance(0, null) - ) - .commitAllowingStateLoss(); - getSupportFragmentManager().executePendingTransactions(); - } - - @Override - public void onSignatureKeyIdChanged(long signatureKeyId) { - if (mEncryptFragment != null) { - mEncryptFragment.setSigningKeyId(signatureKeyId); - } - } - - @Override - public void onEncryptionKeyIdsChanged(long[] encryptionKeyIds) { - if (mEncryptFragment != null) { - mEncryptFragment.setEncryptionKeyIds(encryptionKeyIds); - } - } - - @Override - public void onEncryptionUserIdsChanged(String[] encryptionUserIds) { - if (mEncryptFragment != null) { - mEncryptFragment.setEncryptionUserIds(encryptionUserIds); - } - } - - @Override - public void onPassphraseChanged(Passphrase passphrase) { - if (mEncryptFragment != null) { - mEncryptFragment.setSymmetricPassphrase(passphrase); - } - } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java index 3f9147cc4..89bc97e16 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextFragment.java @@ -47,7 +47,6 @@ import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.ui.base.CryptoOperationFragment; import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment; import org.sufficientlysecure.keychain.ui.util.Notify; -import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Passphrase; import org.sufficientlysecure.keychain.util.ShareHelper; @@ -56,44 +55,14 @@ import java.util.Set; public class EncryptTextFragment extends CryptoOperationFragment { - public interface IMode { - public void onModeChanged(boolean symmetric); - } - public static final String ARG_TEXT = "text"; - private IMode mModeInterface; - - private boolean mSymmetricMode = false; private boolean mShareAfterEncrypt = false; private boolean mUseCompression = true; private boolean mHiddenRecipients = false; - private long mEncryptionKeyIds[] = null; - private String mEncryptionUserIds[] = null; - // TODO Constants.key.none? What's wrong with a null value? - private long mSigningKeyId = Constants.key.none; - private Passphrase mSymmetricPassphrase = new Passphrase(); private String mMessage = ""; - private TextView mText; - - public void setEncryptionKeyIds(long[] encryptionKeyIds) { - mEncryptionKeyIds = encryptionKeyIds; - } - - public void setEncryptionUserIds(String[] encryptionUserIds) { - mEncryptionUserIds = encryptionUserIds; - } - - public void setSigningKeyId(long signingKeyId) { - mSigningKeyId = signingKeyId; - } - - public void setSymmetricPassphrase(Passphrase passphrase) { - mSymmetricPassphrase = passphrase; - } - /** * Creates new instance of this fragment */ @@ -110,10 +79,8 @@ public class EncryptTextFragment extends CryptoOperationFragment { @Override public void onAttach(Activity activity) { super.onAttach(activity); - try { - mModeInterface = (IMode) activity; - } catch (ClassCastException e) { - throw new ClassCastException(activity.toString() + " must implement IMode"); + if ( ! (activity instanceof EncryptActivity) ) { + throw new AssertionError(activity + " must inherit from EncryptionActivity"); } } @@ -124,8 +91,8 @@ public class EncryptTextFragment extends CryptoOperationFragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.encrypt_text_fragment, container, false); - mText = (TextView) view.findViewById(R.id.encrypt_text_text); - mText.addTextChangedListener(new TextWatcher() { + TextView textView = (TextView) view.findViewById(R.id.encrypt_text_text); + textView.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { @@ -144,7 +111,7 @@ public class EncryptTextFragment extends CryptoOperationFragment { // set initial text if (mMessage != null) { - mText.setText(mMessage); + textView.setText(mMessage); } return view; @@ -171,8 +138,8 @@ public class EncryptTextFragment extends CryptoOperationFragment { } switch (item.getItemId()) { case R.id.check_use_symmetric: { - mSymmetricMode = item.isChecked(); - mModeInterface.onModeChanged(mSymmetricMode); + EncryptActivity modeInterface = (EncryptActivity) getActivity(); + modeInterface.toggleModeFragment(); break; } case R.id.check_enable_compression: { @@ -185,11 +152,11 @@ public class EncryptTextFragment extends CryptoOperationFragment { // break; // } case R.id.encrypt_copy: { - startEncrypt(false); + cryptoOperation(false); break; } case R.id.encrypt_share: { - startEncrypt(true); + cryptoOperation(true); break; } default: { @@ -199,7 +166,6 @@ public class EncryptTextFragment extends CryptoOperationFragment { return true; } - protected void onEncryptSuccess(SignEncryptResult result) { if (mShareAfterEncrypt) { // Share encrypted message/file @@ -215,6 +181,13 @@ public class EncryptTextFragment extends CryptoOperationFragment { } protected SignEncryptParcel createEncryptBundle() { + + if (mMessage == null || mMessage.isEmpty()) { + Notify.create(getActivity(), R.string.error_empty_text, Notify.Style.ERROR) + .show(this); + return null; + } + // fill values for this action SignEncryptParcel data = new SignEncryptParcel(); @@ -227,22 +200,45 @@ public class EncryptTextFragment extends CryptoOperationFragment { data.setCompressionId(CompressionAlgorithmTags.UNCOMPRESSED); } data.setHiddenRecipients(mHiddenRecipients); - data.setSymmetricEncryptionAlgorithm(PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED); - data.setSignatureHashAlgorithm(PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED); + data.setSymmetricEncryptionAlgorithm( + PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED); + data.setSignatureHashAlgorithm( + PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED); // Always use armor for messages data.setEnableAsciiArmorOutput(true); - if (mSymmetricMode) { - Log.d(Constants.TAG, "Symmetric encryption enabled!"); - Passphrase passphrase = mSymmetricPassphrase; + EncryptActivity modeInterface = (EncryptActivity) getActivity(); + EncryptModeFragment modeFragment = modeInterface.getModeFragment(); + + if (modeFragment.isAsymmetric()) { + long[] encryptionKeyIds = modeFragment.getAsymmetricEncryptionKeyIds(); + long signingKeyId = modeFragment.getAsymmetricSigningKeyId(); + + boolean gotEncryptionKeys = (encryptionKeyIds != null + && encryptionKeyIds.length > 0); + + if (!gotEncryptionKeys && signingKeyId == 0L) { + Notify.create(getActivity(), R.string.select_encryption_or_signature_key, Notify.Style.ERROR) + .show(this); + return null; + } + + data.setEncryptionMasterKeyIds(encryptionKeyIds); + data.setSignatureMasterKeyId(signingKeyId); + } else { + Passphrase passphrase = modeFragment.getSymmetricPassphrase(); + if (passphrase == null) { + Notify.create(getActivity(), R.string.passphrases_do_not_match, Notify.Style.ERROR) + .show(this); + return null; + } if (passphrase.isEmpty()) { - passphrase = null; + Notify.create(getActivity(), R.string.passphrase_must_not_be_empty, Notify.Style.ERROR) + .show(this); + return null; } data.setSymmetricPassphrase(passphrase); - } else { - data.setEncryptionMasterKeyIds(mEncryptionKeyIds); - data.setSignatureMasterKeyId(mSigningKeyId); } return data; } @@ -273,65 +269,41 @@ public class EncryptTextFragment extends CryptoOperationFragment { sendIntent.setType(Constants.ENCRYPTED_TEXT_MIME); sendIntent.putExtra(Intent.EXTRA_TEXT, new String(resultBytes)); - if (!mSymmetricMode && mEncryptionUserIds != null) { - Set users = new HashSet<>(); - for (String user : mEncryptionUserIds) { - KeyRing.UserId userId = KeyRing.splitUserId(user); - if (userId.email != null) { - users.add(userId.email); - } - } - // pass trough email addresses as extra for email applications - sendIntent.putExtra(Intent.EXTRA_EMAIL, users.toArray(new String[users.size()])); + EncryptActivity modeInterface = (EncryptActivity) getActivity(); + EncryptModeFragment modeFragment = modeInterface.getModeFragment(); + if (!modeFragment.isAsymmetric()) { + return sendIntent; } - return sendIntent; - } - protected boolean inputIsValid() { - if (mMessage == null || mMessage.isEmpty()) { - Notify.create(getActivity(), R.string.error_empty_text, Notify.Style.ERROR) - .show(this); - return false; + String[] encryptionUserIds = modeFragment.getAsymmetricEncryptionUserIds(); + if (encryptionUserIds == null) { + return sendIntent; } - if (mSymmetricMode) { - // symmetric encryption checks - - if (mSymmetricPassphrase == null) { - Notify.create(getActivity(), R.string.passphrases_do_not_match, Notify.Style.ERROR) - .show(this); - return false; - } - if (mSymmetricPassphrase.isEmpty()) { - Notify.create(getActivity(), R.string.passphrase_must_not_be_empty, Notify.Style.ERROR) - .show(this); - return false; - } - - } else { - // asymmetric encryption checks - - boolean gotEncryptionKeys = (mEncryptionKeyIds != null - && mEncryptionKeyIds.length > 0); - - if (!gotEncryptionKeys && mSigningKeyId == 0) { - Notify.create(getActivity(), R.string.select_encryption_or_signature_key, Notify.Style.ERROR) - .show(this); - return false; + Set users = new HashSet<>(); + for (String user : encryptionUserIds) { + KeyRing.UserId userId = KeyRing.splitUserId(user); + if (userId.email != null) { + users.add(userId.email); } } - return true; - } + // pass trough email addresses as extra for email applications + sendIntent.putExtra(Intent.EXTRA_EMAIL, users.toArray(new String[users.size()])); + return sendIntent; + } - public void startEncrypt(boolean share) { + public void cryptoOperation(boolean share) { mShareAfterEncrypt = share; cryptoOperation(); } @Override protected void cryptoOperation(CryptoInputParcel cryptoInput) { - if (!inputIsValid()) { + + final SignEncryptParcel input = createEncryptBundle(); + // this is null if invalid, just return in that case + if (input == null) { // Notify was created by inputIsValid. return; } @@ -340,7 +312,6 @@ public class EncryptTextFragment extends CryptoOperationFragment { Intent intent = new Intent(getActivity(), KeychainIntentService.class); intent.setAction(KeychainIntentService.ACTION_SIGN_ENCRYPT); - final SignEncryptParcel input = createEncryptBundle(); final Bundle data = new Bundle(); data.putParcelable(KeychainIntentService.SIGN_ENCRYPT_PARCEL, input); data.putParcelable(KeychainIntentService.EXTRA_CRYPTO_INPUT, cryptoInput); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java index aecc81604..579f37db2 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java @@ -20,12 +20,14 @@ package org.sufficientlysecure.keychain.ui.widget; import android.content.Context; import android.database.Cursor; import android.graphics.Color; +import android.os.Bundle; +import android.os.Parcelable; +import android.support.annotation.NonNull; import android.support.v4.app.FragmentActivity; import android.support.v4.app.LoaderManager; import android.support.v4.content.Loader; import android.support.v4.widget.CursorAdapter; import android.support.v7.widget.AppCompatSpinner; -import android.text.format.DateFormat; import android.text.format.DateUtils; import android.util.AttributeSet; import android.view.View; @@ -42,17 +44,18 @@ import org.sufficientlysecure.keychain.pgp.KeyRing; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.util.Log; -import java.util.Calendar; -import java.util.Date; -import java.util.TimeZone; - /** * Use AppCompatSpinner from AppCompat lib instead of Spinner. Fixes white dropdown icon. * Related: http://stackoverflow.com/a/27713090 */ -public abstract class KeySpinner extends AppCompatSpinner implements LoaderManager.LoaderCallbacks { +public abstract class KeySpinner extends AppCompatSpinner implements + LoaderManager.LoaderCallbacks { + + public static final String ARG_SUPER_STATE = "super_state"; + public static final String ARG_SELECTED_KEY_ID = "select_key_id"; + public interface OnKeyChangedListener { - public void onKeyChanged(long masterKeyId); + void onKeyChanged(long masterKeyId); } protected long mSelectedKeyId = Constants.key.none; @@ -82,15 +85,17 @@ public abstract class KeySpinner extends AppCompatSpinner implements LoaderManag super.setOnItemSelectedListener(new OnItemSelectedListener() { @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { + mSelectedKeyId = id; if (mListener != null) { - mListener.onKeyChanged(id); + mListener.onKeyChanged(mSelectedKeyId); } } @Override public void onNothingSelected(AdapterView parent) { + mSelectedKeyId = Constants.key.none; if (mListener != null) { - mListener.onKeyChanged(Constants.key.none); + mListener.onKeyChanged(mSelectedKeyId); } } }); @@ -138,7 +143,7 @@ public abstract class KeySpinner extends AppCompatSpinner implements LoaderManag } public void setSelectedKeyId(long selectedKeyId) { - this.mSelectedKeyId = selectedKeyId; + mSelectedKeyId = selectedKeyId; } protected class SelectKeyAdapter extends BaseAdapter implements SpinnerAdapter { -- cgit v1.2.3