From 9c9f95c7acb92aad1f02e65271610fb3dca6c0dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 19 Mar 2015 03:03:46 +0100 Subject: New Passphrase class for safer passphrase handling in memory --- .../keychain/ui/CertifyKeyFragment.java | 4 ++-- .../keychain/ui/CreateKeyActivity.java | 11 ++++++++++- .../keychain/ui/CreateKeyEmailFragment.java | 2 +- .../keychain/ui/CreateKeyFinalFragment.java | 9 +++++---- .../keychain/ui/CreateKeyNameFragment.java | 15 +-------------- .../keychain/ui/CreateKeyPassphraseFragment.java | 13 ++++++++----- .../keychain/ui/DecryptFilesFragment.java | 6 +++--- .../keychain/ui/DecryptFragment.java | 5 +++-- .../keychain/ui/DecryptTextFragment.java | 4 ++-- .../keychain/ui/EditKeyFragment.java | 11 ++++++----- .../keychain/ui/EncryptActivity.java | 7 ++++--- .../keychain/ui/EncryptActivityInterface.java | 4 +++- .../keychain/ui/EncryptFilesActivity.java | 9 +++++---- .../keychain/ui/EncryptSymmetricFragment.java | 10 ++++++++-- .../keychain/ui/EncryptTextActivity.java | 10 ++++++---- .../keychain/ui/PassphraseDialogActivity.java | 5 +++-- .../ui/dialog/SetPassphraseDialogFragment.java | 21 +++++++++++---------- 17 files changed, 81 insertions(+), 65 deletions(-) (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui') 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 9cb4e5f65..a0f89b06a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyFragment.java @@ -62,6 +62,7 @@ import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.ui.widget.CertifyKeySpinner; import org.sufficientlysecure.keychain.ui.widget.KeySpinner; import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.Passphrase; import org.sufficientlysecure.keychain.util.Preferences; import java.lang.reflect.Method; @@ -318,7 +319,7 @@ public class CertifyKeyFragment extends LoaderFragment */ private void initiateCertifying() { // get the user's passphrase for this key (if required) - String passphrase; + Passphrase passphrase; try { passphrase = PassphraseCacheService.getCachedPassphrase(getActivity(), mSignMasterKeyId, mSignMasterKeyId); } catch (PassphraseCacheService.KeyNotFoundException e) { @@ -341,7 +342,6 @@ public class CertifyKeyFragment extends LoaderFragment switch (requestCode) { case REQUEST_CODE_PASSPHRASE: { if (resultCode == Activity.RESULT_OK && data != null) { - String passphrase = data.getStringExtra(PassphraseDialogActivity.MESSAGE_DATA_PASSPHRASE); startCertifying(); } return; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java index 2da5511b8..0eb9e948a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java @@ -23,11 +23,20 @@ import android.support.v4.app.FragmentTransaction; import org.sufficientlysecure.keychain.R; +import java.util.ArrayList; + public class CreateKeyActivity extends BaseActivity { public static final String EXTRA_NAME = "name"; public static final String EXTRA_EMAIL = "email"; + public class State { + String name; + String email; + ArrayList additionalEmails; + char[] passphrase; + } + public static enum FragAction { START, TO_RIGHT, @@ -44,7 +53,7 @@ public class CreateKeyActivity extends BaseActivity { getIntent().getStringExtra(EXTRA_NAME), getIntent().getStringExtra(EXTRA_EMAIL) ); - loadFragment(null, frag, FragAction.START); + loadFragment(savedInstanceState, frag, FragAction.START); } @Override diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java index 66424e012..6a4dd7a41 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java @@ -85,7 +85,7 @@ public class CreateKeyEmailFragment extends Fragment { */ private static boolean isEditTextNotEmpty(Context context, EditText editText) { boolean output = true; - if (editText.getText().toString().length() == 0) { + if (editText.getText().length() == 0) { editText.setError(context.getString(R.string.create_key_empty)); editText.requestFocus(); output = false; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java index 4871b5ae2..5f6bfdb11 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java @@ -45,6 +45,7 @@ import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.ChangeUnlockParcel; import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction; import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.Passphrase; import org.sufficientlysecure.keychain.util.Preferences; import java.util.ArrayList; @@ -72,7 +73,7 @@ public class CreateKeyFinalFragment extends Fragment { String mName; String mEmail; ArrayList mAdditionalEmails; - String mPassphrase; + Passphrase mPassphrase; SaveKeyringParcel mSaveKeyringParcel; @@ -81,14 +82,14 @@ public class CreateKeyFinalFragment extends Fragment { */ public static CreateKeyFinalFragment newInstance(String name, String email, ArrayList additionalEmails, - String passphrase) { + Passphrase passphrase) { CreateKeyFinalFragment frag = new CreateKeyFinalFragment(); Bundle args = new Bundle(); args.putString(ARG_NAME, name); args.putString(ARG_EMAIL, email); args.putStringArrayList(ARG_ADDITIONAL_EMAILS, additionalEmails); - args.putString(ARG_PASSPHRASE, passphrase); + args.putParcelable(ARG_PASSPHRASE, passphrase); frag.setArguments(args); @@ -111,7 +112,7 @@ public class CreateKeyFinalFragment extends Fragment { mName = getArguments().getString(ARG_NAME); mEmail = getArguments().getString(ARG_EMAIL); mAdditionalEmails = getArguments().getStringArrayList(ARG_ADDITIONAL_EMAILS); - mPassphrase = getArguments().getString(ARG_PASSPHRASE); + mPassphrase = getArguments().getParcelable(ARG_PASSPHRASE); // set values mNameEdit.setText(mName); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyNameFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyNameFragment.java index 50a3bd655..093d427b7 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyNameFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyNameFragment.java @@ -68,7 +68,7 @@ public class CreateKeyNameFragment extends Fragment { */ private static boolean isEditTextNotEmpty(Context context, EditText editText) { boolean output = true; - if (editText.getText().toString().length() == 0) { + if (editText.getText().length() == 0) { editText.setError(context.getString(R.string.create_key_empty)); editText.requestFocus(); output = false; @@ -79,19 +79,6 @@ public class CreateKeyNameFragment extends Fragment { return output; } - private static boolean areEditTextsEqual(Context context, EditText editText1, EditText editText2) { - boolean output = true; - if (!editText1.getText().toString().equals(editText2.getText().toString())) { - editText2.setError(context.getString(R.string.create_key_passphrases_not_equal)); - editText2.requestFocus(); - output = false; - } else { - editText2.setError(null); - } - - return output; - } - @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.create_key_name_fragment, container, false); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyPassphraseFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyPassphraseFragment.java index 055ea608b..a10c94093 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyPassphraseFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyPassphraseFragment.java @@ -34,6 +34,7 @@ import android.widget.EditText; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction; import org.sufficientlysecure.keychain.ui.widget.PassphraseEditText; +import org.sufficientlysecure.keychain.util.Passphrase; import java.util.ArrayList; @@ -83,7 +84,7 @@ public class CreateKeyPassphraseFragment extends Fragment { */ private static boolean isEditTextNotEmpty(Context context, EditText editText) { boolean output = true; - if (editText.getText().toString().length() == 0) { + if (editText.getText().length() == 0) { editText.setError(context.getString(R.string.create_key_empty)); editText.requestFocus(); output = false; @@ -95,11 +96,13 @@ public class CreateKeyPassphraseFragment extends Fragment { } private static boolean areEditTextsEqual(Context context, EditText editText1, EditText editText2) { - boolean output = true; - if (!editText1.getText().toString().equals(editText2.getText().toString())) { + Passphrase p1 = new Passphrase(editText1); + Passphrase p2 = new Passphrase(editText2); + boolean output = (p1.equals(p2)); + + if (!output) { editText2.setError(context.getString(R.string.create_key_passphrases_not_equal)); editText2.requestFocus(); - output = false; } else { editText2.setError(null); } @@ -171,7 +174,7 @@ public class CreateKeyPassphraseFragment extends Fragment { mName, mEmail, mAdditionalEmails, - mPassphraseEdit.getText().toString() + new Passphrase(mPassphraseEdit.getText()) ); hideKeyboard(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java index 7e33843ea..71832daa5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java @@ -191,7 +191,7 @@ public class DecryptFilesFragment extends DecryptFragment { data.putInt(KeychainIntentService.TARGET, IOType.URI.ordinal()); data.putParcelable(KeychainIntentService.ENCRYPT_DECRYPT_OUTPUT_URI, mOutputUri); - data.putString(KeychainIntentService.DECRYPT_PASSPHRASE, mPassphrase); + data.putParcelable(KeychainIntentService.DECRYPT_PASSPHRASE, mPassphrase); data.putByteArray(KeychainIntentService.DECRYPT_NFC_DECRYPTED_SESSION_KEY, mNfcDecryptedSessionKey); intent.putExtra(KeychainIntentService.EXTRA_DATA, data); @@ -265,7 +265,7 @@ public class DecryptFilesFragment extends DecryptFragment { data.putInt(KeychainIntentService.TARGET, IOType.URI.ordinal()); data.putParcelable(KeychainIntentService.ENCRYPT_DECRYPT_OUTPUT_URI, mOutputUri); - data.putString(KeychainIntentService.DECRYPT_PASSPHRASE, mPassphrase); + data.putParcelable(KeychainIntentService.DECRYPT_PASSPHRASE, mPassphrase); data.putByteArray(KeychainIntentService.DECRYPT_NFC_DECRYPTED_SESSION_KEY, mNfcDecryptedSessionKey); intent.putExtra(KeychainIntentService.EXTRA_DATA, data); @@ -341,7 +341,7 @@ public class DecryptFilesFragment extends DecryptFragment { switch (requestCode) { case REQUEST_CODE_PASSPHRASE: { if (resultCode == Activity.RESULT_OK && data != null) { - mPassphrase = data.getStringExtra(PassphraseDialogActivity.MESSAGE_DATA_PASSPHRASE); + mPassphrase = data.getParcelableExtra(PassphraseDialogActivity.MESSAGE_DATA_PASSPHRASE); decryptOriginalFilename(); } return; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java index 513300cc5..63508e530 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java @@ -32,6 +32,7 @@ import org.sufficientlysecure.keychain.pgp.KeyRing; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State; +import org.sufficientlysecure.keychain.util.Passphrase; public abstract class DecryptFragment extends Fragment { private static final int RESULT_CODE_LOOKUP_KEY = 0x00007006; @@ -57,7 +58,7 @@ public abstract class DecryptFragment extends Fragment { // State - protected String mPassphrase; + protected Passphrase mPassphrase; protected byte[] mNfcDecryptedSessionKey; @Override @@ -100,7 +101,7 @@ public abstract class DecryptFragment extends Fragment { startActivityForResult(intent, REQUEST_CODE_PASSPHRASE); } - protected void startNfcDecrypt(long subKeyId, String pin, byte[] encryptedSessionKey) { + protected void startNfcDecrypt(long subKeyId, Passphrase pin, byte[] encryptedSessionKey) { // build PendingIntent for Yubikey NFC operations Intent intent = new Intent(getActivity(), NfcActivity.class); intent.setAction(NfcActivity.ACTION_DECRYPT_SESSION_KEY); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java index 1b34f6bf0..30cf739fc 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java @@ -161,7 +161,7 @@ public class DecryptTextFragment extends DecryptFragment { // data data.putInt(KeychainIntentService.TARGET, IOType.BYTES.ordinal()); data.putByteArray(KeychainIntentService.DECRYPT_CIPHERTEXT_BYTES, mCiphertext.getBytes()); - data.putString(KeychainIntentService.DECRYPT_PASSPHRASE, mPassphrase); + data.putParcelable(KeychainIntentService.DECRYPT_PASSPHRASE, mPassphrase); data.putByteArray(KeychainIntentService.DECRYPT_NFC_DECRYPTED_SESSION_KEY, mNfcDecryptedSessionKey); intent.putExtra(KeychainIntentService.EXTRA_DATA, data); @@ -247,7 +247,7 @@ public class DecryptTextFragment extends DecryptFragment { case REQUEST_CODE_PASSPHRASE: { if (resultCode == Activity.RESULT_OK && data != null) { - mPassphrase = data.getStringExtra(PassphraseDialogActivity.MESSAGE_DATA_PASSPHRASE); + mPassphrase = data.getParcelableExtra(PassphraseDialogActivity.MESSAGE_DATA_PASSPHRASE); decryptStart(); } else { getActivity().finish(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java index 8d16fe47e..d2c1ab74c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java @@ -67,6 +67,7 @@ import org.sufficientlysecure.keychain.ui.dialog.EditUserIdDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.SetPassphraseDialogFragment; import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.Passphrase; public class EditKeyFragment extends LoaderFragment implements LoaderManager.LoaderCallbacks { @@ -100,7 +101,7 @@ public class EditKeyFragment extends LoaderFragment implements private SaveKeyringParcel mSaveKeyringParcel; private String mPrimaryUserId; - private String mCurrentPassphrase; + private Passphrase mCurrentPassphrase; /** * Creates new instance of this fragment @@ -267,7 +268,7 @@ public class EditKeyFragment extends LoaderFragment implements switch (requestCode) { case REQUEST_CODE_PASSPHRASE: { if (resultCode == Activity.RESULT_OK && data != null) { - mCurrentPassphrase = data.getStringExtra(PassphraseDialogActivity.MESSAGE_DATA_PASSPHRASE); + mCurrentPassphrase = data.getParcelableExtra(PassphraseDialogActivity.MESSAGE_DATA_PASSPHRASE); // Prepare the loaders. Either re-connect with an existing ones, // or start new ones. getLoaderManager().initLoader(LOADER_ID_USER_IDS, null, EditKeyFragment.this); @@ -386,7 +387,7 @@ public class EditKeyFragment extends LoaderFragment implements // cache new returned passphrase! mSaveKeyringParcel.mNewUnlock = new ChangeUnlockParcel( - data.getString(SetPassphraseDialogFragment.MESSAGE_NEW_PASSPHRASE), + (Passphrase) data.getParcelable(SetPassphraseDialogFragment.MESSAGE_NEW_PASSPHRASE), null ); } @@ -593,7 +594,7 @@ public class EditKeyFragment extends LoaderFragment implements getActivity().finish(); } - private void saveInDatabase(String passphrase) { + private void saveInDatabase(Passphrase passphrase) { Log.d(Constants.TAG, "mSaveKeyringParcel:\n" + mSaveKeyringParcel.toString()); KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler( @@ -640,7 +641,7 @@ public class EditKeyFragment extends LoaderFragment implements // fill values for this action Bundle data = new Bundle(); - data.putString(KeychainIntentService.EDIT_KEYRING_PASSPHRASE, passphrase); + data.putParcelable(KeychainIntentService.EDIT_KEYRING_PASSPHRASE, passphrase); data.putParcelable(KeychainIntentService.EDIT_KEYRING_PARCEL, mSaveKeyringParcel); intent.putExtra(KeychainIntentService.EXTRA_DATA, data); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java index 35dfcb87c..5438f667c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java @@ -32,6 +32,7 @@ import org.sufficientlysecure.keychain.operations.results.SignEncryptResult; import org.sufficientlysecure.keychain.pgp.SignEncryptParcel; import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; +import org.sufficientlysecure.keychain.util.Passphrase; import java.util.Date; @@ -41,7 +42,7 @@ public abstract class EncryptActivity extends BaseActivity { public static final int REQUEST_CODE_NFC = 0x00008002; // For NFC data - protected String mSigningKeyPassphrase = null; + protected Passphrase mSigningKeyPassphrase = null; protected Date mNfcTimestamp = null; protected byte[] mNfcHash = null; @@ -64,7 +65,7 @@ public abstract class EncryptActivity extends BaseActivity { startActivityForResult(intent, REQUEST_CODE_PASSPHRASE); } - protected void startNfcSign(long keyId, String pin, byte[] hashToSign, int hashAlgo) { + protected void startNfcSign(long keyId, Passphrase pin, byte[] hashToSign, int hashAlgo) { // build PendingIntent for Yubikey NFC operations Intent intent = new Intent(this, NfcActivity.class); intent.setAction(NfcActivity.ACTION_SIGN_HASH); @@ -84,7 +85,7 @@ public abstract class EncryptActivity extends BaseActivity { switch (requestCode) { case REQUEST_CODE_PASSPHRASE: { if (resultCode == RESULT_OK && data != null) { - mSigningKeyPassphrase = data.getStringExtra(PassphraseDialogActivity.MESSAGE_DATA_PASSPHRASE); + mSigningKeyPassphrase = data.getParcelableExtra(PassphraseDialogActivity.MESSAGE_DATA_PASSPHRASE); startEncrypt(); return; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivityInterface.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivityInterface.java index c89707c34..2a102c6c4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivityInterface.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivityInterface.java @@ -19,6 +19,8 @@ package org.sufficientlysecure.keychain.ui; import android.net.Uri; +import org.sufficientlysecure.keychain.util.Passphrase; + import java.util.ArrayList; public interface EncryptActivityInterface { @@ -39,7 +41,7 @@ public interface EncryptActivityInterface { public void setEncryptionKeys(long[] encryptionKeys); public void setEncryptionUsers(String[] encryptionUsers); - public void setPassphrase(String passphrase); + public void setPassphrase(Passphrase passphrase); // ArrayList on purpose as only those are parcelable public ArrayList getInputUris(); 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 f1784fab3..0dd672c90 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesActivity.java @@ -36,6 +36,7 @@ import org.sufficientlysecure.keychain.pgp.SignEncryptParcel; import org.sufficientlysecure.keychain.ui.dialog.DeleteFileDialogFragment; 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; import java.util.ArrayList; @@ -72,7 +73,7 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi private long mEncryptionKeyIds[] = null; private String mEncryptionUserIds[] = null; private long mSigningKeyId = Constants.key.none; - private String mPassphrase = ""; + private Passphrase mPassphrase = new Passphrase(); private ArrayList mInputUris; private ArrayList mOutputUris; @@ -136,7 +137,7 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi } @Override - public void setPassphrase(String passphrase) { + public void setPassphrase(Passphrase passphrase) { mPassphrase = passphrase; } @@ -243,8 +244,8 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi if (isModeSymmetric()) { Log.d(Constants.TAG, "Symmetric encryption enabled!"); - String passphrase = mPassphrase; - if (passphrase.length() == 0) { + Passphrase passphrase = mPassphrase; + if (passphrase.isEmpty()) { passphrase = null; } data.setSymmetricPassphrase(passphrase); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptSymmetricFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptSymmetricFragment.java index 86731b162..36b3c08f9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptSymmetricFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptSymmetricFragment.java @@ -28,6 +28,7 @@ import android.view.ViewGroup; import android.widget.EditText; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.util.Passphrase; public class EncryptSymmetricFragment extends Fragment implements EncryptActivityInterface.UpdateListener { @@ -67,8 +68,13 @@ public class EncryptSymmetricFragment extends Fragment implements EncryptActivit @Override public void afterTextChanged(Editable s) { // update passphrase in EncryptActivity - if (mPassphrase.getText().toString().equals(mPassphraseAgain.getText().toString())) { - mEncryptInterface.setPassphrase(s.toString()); + Passphrase p1 = new Passphrase(mPassphrase.getText()); + Passphrase p2 = new Passphrase(mPassphraseAgain.getText()); + boolean passesEquals = (p1.equals(p2)); + p1.removeFromMemory(); + p2.removeFromMemory(); + if (passesEquals) { + mEncryptInterface.setPassphrase(new Passphrase(mPassphrase.getText())); } else { mEncryptInterface.setPassphrase(null); } 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 14f2c492d..847f745d7 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java @@ -36,6 +36,7 @@ import org.sufficientlysecure.keychain.pgp.PgpConstants; import org.sufficientlysecure.keychain.pgp.SignEncryptParcel; 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; import java.util.ArrayList; @@ -70,7 +71,7 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv private String mEncryptionUserIds[] = null; // TODO Constants.key.none? What's wrong with a null value? private long mSigningKeyId = Constants.key.none; - private String mPassphrase = ""; + private Passphrase mPassphrase = new Passphrase(); private ArrayList mInputUris; private ArrayList mOutputUris; @@ -134,7 +135,8 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv } @Override - public void setPassphrase(String passphrase) { + public void setPassphrase(Passphrase passphrase) { + mPassphrase.removeFromMemory(); mPassphrase = passphrase; } @@ -223,8 +225,8 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv if (isModeSymmetric()) { Log.d(Constants.TAG, "Symmetric encryption enabled!"); - String passphrase = mPassphrase; - if (passphrase.length() == 0) { + Passphrase passphrase = mPassphrase; + if (passphrase.isEmpty()) { passphrase = null; } data.setSymmetricPassphrase(passphrase); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java index 48509710a..360d30c82 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java @@ -55,6 +55,7 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.PassphraseCacheService; import org.sufficientlysecure.keychain.ui.dialog.CustomAlertDialogBuilder; import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.Passphrase; import org.sufficientlysecure.keychain.util.Preferences; /** @@ -318,7 +319,7 @@ public class PassphraseDialogActivity extends FragmentActivity { positive.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - final String passphrase = mPassphraseEditText.getText().toString(); + final Passphrase passphrase = new Passphrase(mPassphraseEditText); // Early breakout if we are dealing with a symmetric key if (mSecretRing == null) { @@ -395,7 +396,7 @@ public class PassphraseDialogActivity extends FragmentActivity { }); } - private void finishCaching(String passphrase) { + private void finishCaching(Passphrase passphrase) { // any indication this isn't needed anymore, don't do it. if (mIsCancelled || getActivity() == null) { return; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java index b34dc2edc..947c316e0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java @@ -45,6 +45,7 @@ import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.ui.widget.PassphraseEditText; import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.Passphrase; public class SetPassphraseDialogFragment extends DialogFragment implements OnEditorActionListener { private static final String ARG_MESSENGER = "messenger"; @@ -67,12 +68,12 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi * @param messenger to communicate back after setting the passphrase * @return */ - public static SetPassphraseDialogFragment newInstance(Messenger messenger, String oldPassphrase, int title) { + public static SetPassphraseDialogFragment newInstance(Messenger messenger, Passphrase oldPassphrase, int title) { SetPassphraseDialogFragment frag = new SetPassphraseDialogFragment(); Bundle args = new Bundle(); args.putInt(ARG_TITLE, title); args.putParcelable(ARG_MESSENGER, messenger); - args.putString(ARG_OLD_PASSPHRASE, oldPassphrase); + args.putParcelable(ARG_OLD_PASSPHRASE, oldPassphrase); frag.setArguments(args); @@ -88,7 +89,7 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi int title = getArguments().getInt(ARG_TITLE); mMessenger = getArguments().getParcelable(ARG_MESSENGER); - String oldPassphrase = getArguments().getString(ARG_OLD_PASSPHRASE); + Passphrase oldPassphrase = getArguments().getParcelable(ARG_OLD_PASSPHRASE); CustomAlertDialogBuilder alert = new CustomAlertDialogBuilder(activity); @@ -103,7 +104,7 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi mNoPassphraseCheckBox = (CheckBox) view.findViewById(R.id.passphrase_no_passphrase); - if (TextUtils.isEmpty(oldPassphrase)) { + if (oldPassphrase.isEmpty()) { mNoPassphraseCheckBox.setChecked(true); mPassphraseEditText.setEnabled(false); mPassphraseAgainEditText.setEnabled(false); @@ -123,12 +124,12 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi public void onClick(DialogInterface dialog, int id) { dismiss(); - String passphrase1; + Passphrase passphrase1 = new Passphrase(); if (mNoPassphraseCheckBox.isChecked()) { - passphrase1 = ""; + passphrase1.setEmpty(); } else { - passphrase1 = mPassphraseEditText.getText().toString(); - String passphrase2 = mPassphraseAgainEditText.getText().toString(); + passphrase1 = new Passphrase(mPassphraseEditText); + Passphrase passphrase2 = new Passphrase(mPassphraseAgainEditText); if (!passphrase1.equals(passphrase2)) { Toast.makeText( activity, @@ -139,7 +140,7 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi return; } - if (passphrase1.equals("")) { + if (passphrase1.isEmpty()) { Toast.makeText( activity, getString(R.string.error_message, @@ -152,7 +153,7 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi // return resulting data back to activity Bundle data = new Bundle(); - data.putString(MESSAGE_NEW_PASSPHRASE, passphrase1); + data.putParcelable(MESSAGE_NEW_PASSPHRASE, passphrase1); sendMessageToHandler(MESSAGE_OKAY, data); } -- cgit v1.2.3 From d122d27ebadbc883ba85e2256f1a0a29f791ee60 Mon Sep 17 00:00:00 2001 From: Manoj Khanna Date: Wed, 18 Mar 2015 17:53:24 +0530 Subject: Fixed a crash on ViewKeyActivity This occurs when deleting a key with a stripped master key from the ViewKeyActivity. --- .../keychain/ui/ViewKeyActivity.java | 91 ++++++++++++---------- 1 file changed, 51 insertions(+), 40 deletions(-) (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index 13a5ac269..5834fa502 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -74,6 +74,8 @@ import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler.MessageStatus; +import org.sufficientlysecure.keychain.service.PassphraseCacheService; +import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment; import org.sufficientlysecure.keychain.ui.util.FormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State; @@ -310,31 +312,31 @@ public class ViewKeyActivity extends BaseActivity implements return true; } case R.id.menu_key_view_export_file: { - Intent mIntent = new Intent(this,PassphraseDialogActivity.class); - long keyId=0; try { - keyId = new ProviderHelper(this) - .getCachedPublicKeyRing(mDataUri) - .extractOrGetMasterKeyId(); - } catch (PgpKeyNotFoundException e) { - e.printStackTrace(); + if (PassphraseCacheService.getCachedPassphrase(this, mMasterKeyId, mMasterKeyId) != null) { + exportToFile(mDataUri, mExportHelper, mProviderHelper); + return true; + } + + startPassphraseActivity(REQUEST_EXPORT); + } catch (PassphraseCacheService.KeyNotFoundException e) { + // This happens when the master key is stripped + exportToFile(mDataUri, mExportHelper, mProviderHelper); } - mIntent.putExtra(PassphraseDialogActivity.EXTRA_SUBKEY_ID,keyId); - startActivityForResult(mIntent,REQUEST_EXPORT); return true; } case R.id.menu_key_view_delete: { - Intent mIntent = new Intent(this,PassphraseDialogActivity.class); - long keyId=0; try { - keyId = new ProviderHelper(this) - .getCachedPublicKeyRing(mDataUri) - .extractOrGetMasterKeyId(); - } catch (PgpKeyNotFoundException e) { - e.printStackTrace(); + if (PassphraseCacheService.getCachedPassphrase(this, mMasterKeyId, mMasterKeyId) != null) { + deleteKey(); + return true; + } + + startPassphraseActivity(REQUEST_DELETE); + } catch (PassphraseCacheService.KeyNotFoundException e) { + // This happens when the master key is stripped + deleteKey(); } - mIntent.putExtra(PassphraseDialogActivity.EXTRA_SUBKEY_ID,keyId); - startActivityForResult(mIntent,REQUEST_DELETE); return true; } case R.id.menu_key_view_advanced: { @@ -473,22 +475,32 @@ public class ViewKeyActivity extends BaseActivity implements ActivityCompat.startActivity(this, qrCodeIntent, opts); } - private void exportToFile(Uri dataUri, ExportHelper exportHelper, ProviderHelper providerHelper) - throws ProviderHelper.NotFoundException { - Uri baseUri = KeychainContract.KeyRings.buildUnifiedKeyRingUri(dataUri); - - HashMap data = providerHelper.getGenericData( - baseUri, - new String[]{KeychainContract.Keys.MASTER_KEY_ID, KeychainContract.KeyRings.HAS_SECRET}, - new int[]{ProviderHelper.FIELD_TYPE_INTEGER, ProviderHelper.FIELD_TYPE_INTEGER}); + private void startPassphraseActivity(int requestCode) { + Intent intent = new Intent(this, PassphraseDialogActivity.class); + intent.putExtra(PassphraseDialogActivity.EXTRA_SUBKEY_ID, mMasterKeyId); + startActivityForResult(intent, requestCode); + } - exportHelper.showExportKeysDialog( - new long[]{(Long) data.get(KeychainContract.KeyRings.MASTER_KEY_ID)}, - Constants.Path.APP_DIR_FILE, ((Long) data.get(KeychainContract.KeyRings.HAS_SECRET) != 0) - ); + private void exportToFile(Uri dataUri, ExportHelper exportHelper, ProviderHelper providerHelper) { + try { + Uri baseUri = KeychainContract.KeyRings.buildUnifiedKeyRingUri(dataUri); + + HashMap data = providerHelper.getGenericData( + baseUri, + new String[]{KeychainContract.Keys.MASTER_KEY_ID, KeychainContract.KeyRings.HAS_SECRET}, + new int[]{ProviderHelper.FIELD_TYPE_INTEGER, ProviderHelper.FIELD_TYPE_INTEGER}); + + exportHelper.showExportKeysDialog( + new long[]{(Long) data.get(KeychainContract.KeyRings.MASTER_KEY_ID)}, + Constants.Path.APP_DIR_FILE, ((Long) data.get(KeychainContract.KeyRings.HAS_SECRET) != 0) + ); + } catch (ProviderHelper.NotFoundException e) { + Notify.showNotify(this, R.string.error_key_not_found, Notify.Style.ERROR); + Log.e(Constants.TAG, "Key not found", e); + } } - private void deleteKey(Uri dataUri, ExportHelper exportHelper) { + private void deleteKey() { // Message is received after key is deleted Handler returnHandler = new Handler() { @Override @@ -500,7 +512,11 @@ public class ViewKeyActivity extends BaseActivity implements } }; - exportHelper.deleteKey(dataUri, returnHandler); + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(returnHandler); + DeleteKeyDialogFragment deleteKeyDialog = DeleteKeyDialogFragment.newInstance(messenger, + new long[]{ mMasterKeyId }); + deleteKeyDialog.show(getSupportFragmentManager(), "deleteKeyDialog"); } @Override @@ -531,18 +547,13 @@ public class ViewKeyActivity extends BaseActivity implements } if (requestCode == REQUEST_DELETE && resultCode == Activity.RESULT_OK){ - deleteKey(mDataUri, mExportHelper); + deleteKey(); } + if (requestCode == REQUEST_EXPORT && resultCode == Activity.RESULT_OK){ - try { - exportToFile(mDataUri, mExportHelper, mProviderHelper); - } catch (ProviderHelper.NotFoundException e) { - Notify.showNotify(this, R.string.error_key_not_found, Notify.Style.ERROR); - Log.e(Constants.TAG, "Key not found", e); - } + exportToFile(mDataUri, mExportHelper, mProviderHelper); } - if (data != null && data.hasExtra(OperationResult.EXTRA_RESULT)) { OperationResult result = data.getParcelableExtra(OperationResult.EXTRA_RESULT); result.createNotify(this).show(); -- cgit v1.2.3 From 6120365ee1e425acbc270b17c5cad621710777a9 Mon Sep 17 00:00:00 2001 From: Manoj Khanna Date: Thu, 19 Mar 2015 19:58:24 +0530 Subject: Fix for Issue #1114 Displays the snackbar above the keyboard on all activities. --- .../keychain/ui/util/Notify.java | 35 ++++++++++++++++++---- 1 file changed, 30 insertions(+), 5 deletions(-) (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/Notify.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/Notify.java index 3bc29edb6..9736b5765 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/Notify.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/Notify.java @@ -19,6 +19,11 @@ package org.sufficientlysecure.keychain.ui.util; import android.app.Activity; import android.content.res.Resources; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentActivity; +import android.support.v4.app.FragmentManager; +import android.view.View; +import android.view.ViewGroup; import com.nispok.snackbar.Snackbar; import com.nispok.snackbar.Snackbar.SnackbarDuration; @@ -61,11 +66,11 @@ public class Notify { break; } - SnackbarManager.show(bar); + showSnackbar(activity, bar); } - public static Showable createNotify (Activity activity, int resId, int duration, Style style) { + public static Showable createNotify (final Activity activity, int resId, int duration, Style style) { final Snackbar bar = getSnackbar(activity) .text(resId); @@ -90,7 +95,7 @@ public class Notify { return new Showable () { @Override public void show() { - SnackbarManager.show(bar); + showSnackbar(activity, bar); } }; } @@ -104,7 +109,7 @@ public class Notify { return createNotify(activity, msg, duration, style, null, 0); } - public static Showable createNotify(Activity activity, String msg, int duration, Style style, + public static Showable createNotify(final Activity activity, String msg, int duration, Style style, final ActionListener listener, int resIdAction) { final Snackbar bar = getSnackbar(activity) @@ -141,7 +146,7 @@ public class Notify { return new Showable () { @Override public void show() { - SnackbarManager.show(bar); + showSnackbar(activity, bar); } }; @@ -178,6 +183,26 @@ public class Notify { return bar; } + private static void showSnackbar(Activity activity, Snackbar snackbar) { + if (activity instanceof FragmentActivity) { + FragmentManager fragmentManager = ((FragmentActivity) activity).getSupportFragmentManager(); + + int count = fragmentManager.getBackStackEntryCount(); + Fragment fragment = fragmentManager.getFragments().get(count > 0 ? count - 1 : 0); + + if (fragment != null) { + View view = fragment.getView(); + + if (view != null) { + SnackbarManager.show(snackbar, (ViewGroup) view); + return; + } + } + } + + SnackbarManager.show(snackbar); + } + public interface Showable { public void show(); -- cgit v1.2.3 From 98817d13ee2e33b92f3a339df312709be027e964 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 19 Mar 2015 17:16:23 +0100 Subject: Manage my keys wizard --- .../keychain/ui/CreateKeyActivity.java | 92 ++++++++---- .../keychain/ui/CreateKeyEmailFragment.java | 60 ++++---- .../keychain/ui/CreateKeyFinalFragment.java | 60 ++++---- .../keychain/ui/CreateKeyNameFragment.java | 40 +++--- .../keychain/ui/CreateKeyPassphraseFragment.java | 45 +++--- .../keychain/ui/CreateKeyStartFragment.java | 157 +++++++++++++++++++++ .../keychain/ui/FirstTimeActivity.java | 110 --------------- .../keychain/ui/KeyListFragment.java | 3 +- .../keychain/ui/MainActivity.java | 4 +- .../keychain/ui/widget/EmailEditText.java | 9 +- .../keychain/ui/widget/NameEditText.java | 6 +- 11 files changed, 323 insertions(+), 263 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyStartFragment.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/FirstTimeActivity.java (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java index 0eb9e948a..eb484302c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java @@ -22,6 +22,7 @@ import android.support.v4.app.Fragment; import android.support.v4.app.FragmentTransaction; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.util.Passphrase; import java.util.ArrayList; @@ -29,31 +30,62 @@ public class CreateKeyActivity extends BaseActivity { public static final String EXTRA_NAME = "name"; public static final String EXTRA_EMAIL = "email"; + public static final String EXTRA_FIRST_TIME = "first_time"; + public static final String EXTRA_ADDITIONAL_EMAILS = "additional_emails"; + public static final String EXTRA_PASSPHRASE = "passphrase"; - public class State { - String name; - String email; - ArrayList additionalEmails; - char[] passphrase; - } + public static final String FRAGMENT_TAG = "currentFragment"; - public static enum FragAction { - START, - TO_RIGHT, - TO_LEFT - } + String mName; + String mEmail; + ArrayList mAdditionalEmails; + Passphrase mPassphrase; + boolean mFirstTime; + + Fragment mCurrentFragment; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - // pass extras into fragment - CreateKeyNameFragment frag = - CreateKeyNameFragment.newInstance( - getIntent().getStringExtra(EXTRA_NAME), - getIntent().getStringExtra(EXTRA_EMAIL) - ); - loadFragment(savedInstanceState, frag, FragAction.START); + // Check whether we're recreating a previously destroyed instance + if (savedInstanceState != null) { + // Restore value of members from saved state + mName = savedInstanceState.getString(EXTRA_NAME); + mEmail = savedInstanceState.getString(EXTRA_EMAIL); + mAdditionalEmails = savedInstanceState.getStringArrayList(EXTRA_ADDITIONAL_EMAILS); + mPassphrase = savedInstanceState.getParcelable(EXTRA_PASSPHRASE); + mFirstTime = savedInstanceState.getBoolean(EXTRA_FIRST_TIME); + + mCurrentFragment = getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG); + } else { + // Initialize members with default values for a new instance + mName = getIntent().getStringExtra(EXTRA_NAME); + mEmail = getIntent().getStringExtra(EXTRA_EMAIL); + mFirstTime = getIntent().getBooleanExtra(EXTRA_FIRST_TIME, false); + + // Start with first fragment of wizard + CreateKeyStartFragment frag = CreateKeyStartFragment.newInstance(); + loadFragment(frag, FragAction.START); + } + + if (mFirstTime) { + setTitle(R.string.app_name); + setActionBarIcon(R.drawable.ic_launcher); + } else { + setTitle(R.string.title_manage_my_keys); + } + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + + outState.putString(EXTRA_NAME, mName); + outState.putString(EXTRA_EMAIL, mEmail); + outState.putStringArrayList(EXTRA_ADDITIONAL_EMAILS, mAdditionalEmails); + outState.putParcelable(EXTRA_PASSPHRASE, mPassphrase); + outState.putBoolean(EXTRA_FIRST_TIME, mFirstTime); } @Override @@ -61,23 +93,23 @@ public class CreateKeyActivity extends BaseActivity { setContentView(R.layout.create_key_activity); } - public void loadFragment(Bundle savedInstanceState, Fragment fragment, FragAction action) { - // However, if we're being restored from a previous state, - // then we don't need to do anything and should return or else - // we could end up with overlapping fragments. - if (savedInstanceState != null) { - return; - } + public static enum FragAction { + START, + TO_RIGHT, + TO_LEFT + } + + public void loadFragment(Fragment fragment, FragAction action) { + mCurrentFragment = fragment; // Add the fragment to the 'fragment_container' FrameLayout - // NOTE: We use commitAllowingStateLoss() to prevent weird crashes! FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); switch (action) { case START: transaction.setCustomAnimations(0, 0); - transaction.replace(R.id.create_key_fragment_container, fragment) - .commitAllowingStateLoss(); + transaction.replace(R.id.create_key_fragment_container, fragment, FRAGMENT_TAG) + .commit(); break; case TO_LEFT: getSupportFragmentManager().popBackStackImmediate(); @@ -86,8 +118,8 @@ public class CreateKeyActivity extends BaseActivity { transaction.setCustomAnimations(R.anim.frag_slide_in_from_right, R.anim.frag_slide_out_to_left, R.anim.frag_slide_in_from_left, R.anim.frag_slide_out_to_right); transaction.addToBackStack(null); - transaction.replace(R.id.create_key_fragment_container, fragment) - .commitAllowingStateLoss(); + transaction.replace(R.id.create_key_fragment_container, fragment, FRAGMENT_TAG) + .commit(); break; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java index 6a4dd7a41..2e8a1f370 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java @@ -46,16 +46,12 @@ import java.util.List; public class CreateKeyEmailFragment extends Fragment { - public static final String ARG_NAME = "name"; - public static final String ARG_EMAIL = "email"; - CreateKeyActivity mCreateKeyActivity; EmailEditText mEmailEdit; RecyclerView mEmailsRecyclerView; View mBackButton; View mNextButton; - String mName; ArrayList mAdditionalEmailModels; EmailAdapter mEmailAdapter; @@ -63,13 +59,10 @@ public class CreateKeyEmailFragment extends Fragment { /** * Creates new instance of this fragment */ - public static CreateKeyEmailFragment newInstance(String name, String email) { + public static CreateKeyEmailFragment newInstance() { CreateKeyEmailFragment frag = new CreateKeyEmailFragment(); Bundle args = new Bundle(); - args.putString(ARG_NAME, name); - args.putString(ARG_EMAIL, email); - frag.setArguments(args); return frag; @@ -106,31 +99,33 @@ public class CreateKeyEmailFragment extends Fragment { mEmailsRecyclerView = (RecyclerView) view.findViewById(R.id.create_key_emails); // initial values - mName = getArguments().getString(ARG_NAME); - String email = getArguments().getString(ARG_EMAIL); - mEmailEdit.setText(email); + mEmailEdit.setText(mCreateKeyActivity.mEmail); // focus empty edit fields - if (email == null) { + if (mCreateKeyActivity.mEmail == null) { mEmailEdit.requestFocus(); } mBackButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - mCreateKeyActivity.loadFragment(null, null, FragAction.TO_LEFT); + mCreateKeyActivity.loadFragment(null, FragAction.TO_LEFT); } }); mNextButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - createKeyCheck(); + nextClicked(); } }); mEmailsRecyclerView.setHasFixedSize(true); mEmailsRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); mEmailsRecyclerView.setItemAnimator(new DefaultItemAnimator()); + // initial values mAdditionalEmailModels = new ArrayList<>(); + if (mCreateKeyActivity.mAdditionalEmails != null) { + setAdditionalEmails(mCreateKeyActivity.mAdditionalEmails); + } mEmailAdapter = new EmailAdapter(mAdditionalEmailModels, new View.OnClickListener() { @Override public void onClick(View v) { @@ -171,25 +166,38 @@ public class CreateKeyEmailFragment extends Fragment { mCreateKeyActivity = (CreateKeyActivity) getActivity(); } - private void createKeyCheck() { + private void nextClicked() { if (isEditTextNotEmpty(getActivity(), mEmailEdit)) { + // save state + mCreateKeyActivity.mEmail = mEmailEdit.getText().toString(); + mCreateKeyActivity.mAdditionalEmails = getAdditionalEmails(); - ArrayList emails = new ArrayList<>(); - for (EmailAdapter.ViewModel holder : mAdditionalEmailModels) { - emails.add(holder.toString()); - } + CreateKeyPassphraseFragment frag = CreateKeyPassphraseFragment.newInstance(); + mCreateKeyActivity.loadFragment(frag, FragAction.TO_RIGHT); + } + } - CreateKeyPassphraseFragment frag = - CreateKeyPassphraseFragment.newInstance( - mName, - mEmailEdit.getText().toString(), - emails - ); + private ArrayList getAdditionalEmails() { + ArrayList emails = new ArrayList<>(); + for (EmailAdapter.ViewModel holder : mAdditionalEmailModels) { + emails.add(holder.toString()); + } + return emails; + } - mCreateKeyActivity.loadFragment(null, frag, FragAction.TO_RIGHT); + private void setAdditionalEmails(ArrayList emails) { + for (String email : emails) { + mAdditionalEmailModels.add(new EmailAdapter.ViewModel(email)); } } + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + // save state in activity + mCreateKeyActivity.mAdditionalEmails = getAdditionalEmails(); + } + public static class EmailAdapter extends RecyclerView.Adapter { private List mDataset; private View.OnClickListener mFooterOnClickListener; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java index 5f6bfdb11..75f49a426 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java @@ -65,32 +65,15 @@ public class CreateKeyFinalFragment extends Fragment { TextView mEditText; View mEditButton; - public static final String ARG_NAME = "name"; - public static final String ARG_EMAIL = "email"; - public static final String ARG_ADDITIONAL_EMAILS = "emails"; - public static final String ARG_PASSPHRASE = "passphrase"; - - String mName; - String mEmail; - ArrayList mAdditionalEmails; - Passphrase mPassphrase; - SaveKeyringParcel mSaveKeyringParcel; /** * Creates new instance of this fragment */ - public static CreateKeyFinalFragment newInstance(String name, String email, - ArrayList additionalEmails, - Passphrase passphrase) { + public static CreateKeyFinalFragment newInstance() { CreateKeyFinalFragment frag = new CreateKeyFinalFragment(); Bundle args = new Bundle(); - args.putString(ARG_NAME, name); - args.putString(ARG_EMAIL, email); - args.putStringArrayList(ARG_ADDITIONAL_EMAILS, additionalEmails); - args.putParcelable(ARG_PASSPHRASE, passphrase); - frag.setArguments(args); return frag; @@ -108,17 +91,11 @@ public class CreateKeyFinalFragment extends Fragment { mEditText = (TextView) view.findViewById(R.id.create_key_edit_text); mEditButton = view.findViewById(R.id.create_key_edit_button); - // get args - mName = getArguments().getString(ARG_NAME); - mEmail = getArguments().getString(ARG_EMAIL); - mAdditionalEmails = getArguments().getStringArrayList(ARG_ADDITIONAL_EMAILS); - mPassphrase = getArguments().getParcelable(ARG_PASSPHRASE); - // set values - mNameEdit.setText(mName); - if (mAdditionalEmails != null && mAdditionalEmails.size() > 0) { - String emailText = mEmail + ", "; - Iterator it = mAdditionalEmails.iterator(); + mNameEdit.setText(mCreateKeyActivity.mName); + if (mCreateKeyActivity.mAdditionalEmails != null && mCreateKeyActivity.mAdditionalEmails.size() > 0) { + String emailText = mCreateKeyActivity.mEmail + ", "; + Iterator it = mCreateKeyActivity.mAdditionalEmails.iterator(); while (it.hasNext()) { Object next = it.next(); emailText += next; @@ -128,7 +105,7 @@ public class CreateKeyFinalFragment extends Fragment { } mEmailEdit.setText(emailText); } else { - mEmailEdit.setText(mEmail); + mEmailEdit.setText(mCreateKeyActivity.mEmail); } mCreateButton.setOnClickListener(new View.OnClickListener() { @@ -141,7 +118,7 @@ public class CreateKeyFinalFragment extends Fragment { mBackButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - mCreateKeyActivity.loadFragment(null, null, FragAction.TO_LEFT); + mCreateKeyActivity.loadFragment(null, FragAction.TO_LEFT); } }); @@ -157,6 +134,12 @@ public class CreateKeyFinalFragment extends Fragment { return view; } + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + mCreateKeyActivity = (CreateKeyActivity) getActivity(); + } + @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { @@ -187,17 +170,22 @@ public class CreateKeyFinalFragment extends Fragment { Algorithm.RSA, 4096, null, KeyFlags.SIGN_DATA, 0L)); mSaveKeyringParcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd( Algorithm.RSA, 4096, null, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE, 0L)); - String userId = KeyRing.createUserId(new KeyRing.UserId(mName, mEmail, null)); + String userId = KeyRing.createUserId( + new KeyRing.UserId(mCreateKeyActivity.mName, mCreateKeyActivity.mEmail, null) + ); mSaveKeyringParcel.mAddUserIds.add(userId); mSaveKeyringParcel.mChangePrimaryUserId = userId; - if (mAdditionalEmails != null && mAdditionalEmails.size() > 0) { - for (String email : mAdditionalEmails) { - String thisUserId = KeyRing.createUserId(new KeyRing.UserId(mName, email, null)); + if (mCreateKeyActivity.mAdditionalEmails != null + && mCreateKeyActivity.mAdditionalEmails.size() > 0) { + for (String email : mCreateKeyActivity.mAdditionalEmails) { + String thisUserId = KeyRing.createUserId( + new KeyRing.UserId(mCreateKeyActivity.mName, email, null) + ); mSaveKeyringParcel.mAddUserIds.add(thisUserId); } } - mSaveKeyringParcel.mNewUnlock = mPassphrase != null - ? new ChangeUnlockParcel(mPassphrase, null) + mSaveKeyringParcel.mNewUnlock = mCreateKeyActivity.mPassphrase != null + ? new ChangeUnlockParcel(mCreateKeyActivity.mPassphrase, null) : null; } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyNameFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyNameFragment.java index 093d427b7..7480367bb 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyNameFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyNameFragment.java @@ -24,34 +24,26 @@ import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.view.inputmethod.InputMethodManager; import android.widget.EditText; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction; -import org.sufficientlysecure.keychain.ui.widget.EmailEditText; import org.sufficientlysecure.keychain.ui.widget.NameEditText; public class CreateKeyNameFragment extends Fragment { - public static final String ARG_NAME = "name"; - public static final String ARG_EMAIL = "email"; - CreateKeyActivity mCreateKeyActivity; NameEditText mNameEdit; + View mBackButton; View mNextButton; - String mEmail; - /** * Creates new instance of this fragment */ - public static CreateKeyNameFragment newInstance(String name, String email) { + public static CreateKeyNameFragment newInstance() { CreateKeyNameFragment frag = new CreateKeyNameFragment(); Bundle args = new Bundle(); - args.putString(ARG_NAME, name); - args.putString(ARG_EMAIL, email); frag.setArguments(args); @@ -84,21 +76,26 @@ public class CreateKeyNameFragment extends Fragment { View view = inflater.inflate(R.layout.create_key_name_fragment, container, false); mNameEdit = (NameEditText) view.findViewById(R.id.create_key_name); + mBackButton = view.findViewById(R.id.create_key_back_button); mNextButton = view.findViewById(R.id.create_key_next_button); // initial values - String name = getArguments().getString(ARG_NAME); - mEmail = getArguments().getString(ARG_EMAIL); - mNameEdit.setText(name); + mNameEdit.setText(mCreateKeyActivity.mName); // focus empty edit fields - if (name == null) { + if (mCreateKeyActivity.mName == null) { mNameEdit.requestFocus(); } + mBackButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mCreateKeyActivity.loadFragment(null, FragAction.TO_LEFT); + } + }); mNextButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - createKeyCheck(); + nextClicked(); } }); @@ -111,16 +108,13 @@ public class CreateKeyNameFragment extends Fragment { mCreateKeyActivity = (CreateKeyActivity) getActivity(); } - private void createKeyCheck() { + private void nextClicked() { if (isEditTextNotEmpty(getActivity(), mNameEdit)) { + // save state + mCreateKeyActivity.mName = mNameEdit.getText().toString(); - CreateKeyEmailFragment frag = - CreateKeyEmailFragment.newInstance( - mNameEdit.getText().toString(), - mEmail - ); - - mCreateKeyActivity.loadFragment(null, frag, FragAction.TO_RIGHT); + CreateKeyEmailFragment frag = CreateKeyEmailFragment.newInstance(); + mCreateKeyActivity.loadFragment(frag, FragAction.TO_RIGHT); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyPassphraseFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyPassphraseFragment.java index a10c94093..32173edf7 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyPassphraseFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyPassphraseFragment.java @@ -21,6 +21,7 @@ import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.support.v4.app.Fragment; +import android.text.Editable; import android.text.method.HideReturnsTransformationMethod; import android.text.method.PasswordTransformationMethod; import android.view.LayoutInflater; @@ -37,18 +38,10 @@ import org.sufficientlysecure.keychain.ui.widget.PassphraseEditText; import org.sufficientlysecure.keychain.util.Passphrase; import java.util.ArrayList; +import java.util.Arrays; public class CreateKeyPassphraseFragment extends Fragment { - public static final String ARG_NAME = "name"; - public static final String ARG_EMAIL = "email"; - public static final String ARG_ADDITIONAL_EMAILS = "emails"; - - // model - String mName; - String mEmail; - ArrayList mAdditionalEmails; - // view CreateKeyActivity mCreateKeyActivity; PassphraseEditText mPassphraseEdit; @@ -60,15 +53,10 @@ public class CreateKeyPassphraseFragment extends Fragment { /** * Creates new instance of this fragment */ - public static CreateKeyPassphraseFragment newInstance(String name, String email, - ArrayList additionalEmails) { + public static CreateKeyPassphraseFragment newInstance() { CreateKeyPassphraseFragment frag = new CreateKeyPassphraseFragment(); Bundle args = new Bundle(); - args.putString(ARG_NAME, name); - args.putString(ARG_EMAIL, email); - args.putStringArrayList(ARG_ADDITIONAL_EMAILS, additionalEmails); - frag.setArguments(args); return frag; @@ -121,9 +109,12 @@ public class CreateKeyPassphraseFragment extends Fragment { mNextButton = view.findViewById(R.id.create_key_next_button); // initial values - mName = getArguments().getString(ARG_NAME); - mEmail = getArguments().getString(ARG_EMAIL); - mAdditionalEmails = getArguments().getStringArrayList(ARG_ADDITIONAL_EMAILS); + // TODO: using String here is unsafe... + if (mCreateKeyActivity.mPassphrase != null) { + mPassphraseEdit.setText(Arrays.toString(mCreateKeyActivity.mPassphrase.getCharArray())); + mPassphraseEditAgain.setText(Arrays.toString(mCreateKeyActivity.mPassphrase.getCharArray())); + } + mPassphraseEdit.requestFocus(); mBackButton.setOnClickListener(new View.OnClickListener() { @Override @@ -134,7 +125,7 @@ public class CreateKeyPassphraseFragment extends Fragment { mNextButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - createKeyCheck(); + nextClicked(); } }); mShowPassphrase.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @@ -162,23 +153,19 @@ public class CreateKeyPassphraseFragment extends Fragment { private void back() { hideKeyboard(); - mCreateKeyActivity.loadFragment(null, null, FragAction.TO_LEFT); + mCreateKeyActivity.loadFragment(null, FragAction.TO_LEFT); } - private void createKeyCheck() { + private void nextClicked() { if (isEditTextNotEmpty(getActivity(), mPassphraseEdit) && areEditTextsEqual(getActivity(), mPassphraseEdit, mPassphraseEditAgain)) { - CreateKeyFinalFragment frag = - CreateKeyFinalFragment.newInstance( - mName, - mEmail, - mAdditionalEmails, - new Passphrase(mPassphraseEdit.getText()) - ); + // save state + mCreateKeyActivity.mPassphrase = new Passphrase(mPassphraseEdit); + CreateKeyFinalFragment frag = CreateKeyFinalFragment.newInstance(); hideKeyboard(); - mCreateKeyActivity.loadFragment(null, frag, FragAction.TO_RIGHT); + mCreateKeyActivity.loadFragment(frag, FragAction.TO_RIGHT); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyStartFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyStartFragment.java new file mode 100644 index 000000000..180a52a1c --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyStartFragment.java @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * 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.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.os.Messenger; +import android.support.v4.app.Fragment; +import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageButton; +import android.widget.TextView; + +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction; +import org.sufficientlysecure.keychain.ui.dialog.AddEmailDialogFragment; +import org.sufficientlysecure.keychain.ui.dialog.SetPassphraseDialogFragment; +import org.sufficientlysecure.keychain.ui.widget.EmailEditText; +import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.Preferences; + +import java.util.ArrayList; +import java.util.List; + +public class CreateKeyStartFragment extends Fragment { + + CreateKeyActivity mCreateKeyActivity; + + View mCreateKey; + View mImportKey; + View mYubiKey; + TextView mCancel; + public static final int REQUEST_CODE_CREATE_OR_IMPORT_KEY = 0x00007012; + + /** + * Creates new instance of this fragment + */ + public static CreateKeyStartFragment newInstance() { + CreateKeyStartFragment frag = new CreateKeyStartFragment(); + + Bundle args = new Bundle(); + + frag.setArguments(args); + + return frag; + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.create_key_start_fragment, container, false); + + mCreateKey = view.findViewById(R.id.create_key_create_key_button); + mImportKey = view.findViewById(R.id.create_key_import_button); +// mYubiKey = view.findViewById(R.id.create_key_yubikey_button); + mCancel = (TextView) view.findViewById(R.id.create_key_cancel); + + if (mCreateKeyActivity.mFirstTime) { + mCancel.setText(R.string.first_time_skip); + } else { + mCancel.setText(R.string.btn_do_not_save); + } + + mCreateKey.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + CreateKeyNameFragment frag = CreateKeyNameFragment.newInstance(); + mCreateKeyActivity.loadFragment(frag, FragAction.TO_RIGHT); + } + }); + + mImportKey.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(mCreateKeyActivity, ImportKeysActivity.class); + intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_FILE_AND_RETURN); + startActivityForResult(intent, REQUEST_CODE_CREATE_OR_IMPORT_KEY); + } + }); + + mCancel.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finishSetup(null); + } + }); + + return view; + } + + + private void finishSetup(Intent srcData) { + if (mCreateKeyActivity.mFirstTime) { + Preferences prefs = Preferences.getPreferences(mCreateKeyActivity); + prefs.setFirstTime(false); + } + Intent intent = new Intent(mCreateKeyActivity, MainActivity.class); + // give intent through to display notify + if (srcData != null) { + intent.putExtras(srcData); + } + startActivity(intent); + mCreateKeyActivity.finish(); + } + + // workaround for https://code.google.com/p/android/issues/detail?id=61394 +// @Override +// public boolean onKeyDown(int keyCode, KeyEvent event) { +// return keyCode == KeyEvent.KEYCODE_MENU || super.onKeyDown(keyCode, event); +// } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + + if (requestCode == REQUEST_CODE_CREATE_OR_IMPORT_KEY) { + if (resultCode == Activity.RESULT_OK) { + finishSetup(data); + } + } else { + Log.e(Constants.TAG, "No valid request code!"); + } + } + + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + mCreateKeyActivity = (CreateKeyActivity) getActivity(); + } + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/FirstTimeActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/FirstTimeActivity.java deleted file mode 100644 index 393e15cfa..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/FirstTimeActivity.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2014 Dominik Schürmann - * - * 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.view.KeyEvent; -import android.view.View; -import android.view.Window; - -import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.util.Log; -import org.sufficientlysecure.keychain.util.Preferences; - -public class FirstTimeActivity extends BaseActivity { - - View mCreateKey; - View mImportKey; - View mSkipSetup; - - public static final int REQUEST_CODE_CREATE_OR_IMPORT_KEY = 0x00007012; - - @Override - protected void onCreate(Bundle savedInstanceState) { - supportRequestWindowFeature(Window.FEATURE_NO_TITLE); - - super.onCreate(savedInstanceState); - - mCreateKey = findViewById(R.id.first_time_create_key); - mImportKey = findViewById(R.id.first_time_import_key); - mSkipSetup = findViewById(R.id.first_time_cancel); - - mSkipSetup.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - finishSetup(null); - } - }); - - mImportKey.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Intent intent = new Intent(FirstTimeActivity.this, ImportKeysActivity.class); - intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_FILE_AND_RETURN); - startActivityForResult(intent, REQUEST_CODE_CREATE_OR_IMPORT_KEY); - } - }); - - mCreateKey.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Intent intent = new Intent(FirstTimeActivity.this, CreateKeyActivity.class); - startActivityForResult(intent, REQUEST_CODE_CREATE_OR_IMPORT_KEY); - } - }); - } - - @Override - protected void initLayout() { - setContentView(R.layout.first_time_activity); - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - - if (requestCode == REQUEST_CODE_CREATE_OR_IMPORT_KEY) { - if (resultCode == RESULT_OK) { - finishSetup(data); - } - } else { - Log.e(Constants.TAG, "No valid request code!"); - } - } - - private void finishSetup(Intent srcData) { - Preferences prefs = Preferences.getPreferences(this); - prefs.setFirstTime(false); - Intent intent = new Intent(this, MainActivity.class); - // give intent through to display notify - if (srcData != null) { - intent.putExtras(srcData); - } - startActivity(intent); - finish(); - } - - // workaround for https://code.google.com/p/android/issues/detail?id=61394 - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - return keyCode == KeyEvent.KEYCODE_MENU || super.onKeyDown(keyCode, event); - } - -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java index 4b604add8..f8939f3d1 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -489,7 +489,8 @@ public class KeyListFragment extends LoaderFragment case R.id.menu_key_list_debug_first_time: Preferences prefs = Preferences.getPreferences(getActivity()); prefs.setFirstTime(true); - Intent intent = new Intent(getActivity(), FirstTimeActivity.class); + Intent intent = new Intent(getActivity(), CreateKeyActivity.class); + intent.putExtra(CreateKeyActivity.EXTRA_FIRST_TIME, true); startActivity(intent); getActivity().finish(); return true; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java index b6b2fcb8a..5fa3edba4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java @@ -54,7 +54,9 @@ public class MainActivity extends MaterialNavigationDrawer implements FabContain // if this is the first time show first time activity Preferences prefs = Preferences.getPreferences(this); if (prefs.isFirstTime()) { - startActivity(new Intent(this, FirstTimeActivity.class)); + Intent intent = new Intent(this, CreateKeyActivity.class); + intent.putExtra(CreateKeyActivity.EXTRA_FIRST_TIME, true); + startActivity(intent); finish(); return; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EmailEditText.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EmailEditText.java index 1bdec7b84..e21c5d510 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EmailEditText.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EmailEditText.java @@ -58,9 +58,10 @@ public class EmailEditText extends AutoCompleteTextView { } private void init() { - this.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS); - this.addTextChangedListener(textWatcher); - removeFlag(); + setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS); + reenableKeyboardSuggestions(); + + addTextChangedListener(textWatcher); initAdapter(); } @@ -104,7 +105,7 @@ public class EmailEditText extends AutoCompleteTextView { * Hack to re-enable keyboard auto correction in AutoCompleteTextView. * From http://stackoverflow.com/a/22512858 */ - private void removeFlag() { + private void reenableKeyboardSuggestions() { int inputType = getInputType(); inputType &= ~EditorInfo.TYPE_TEXT_FLAG_AUTO_COMPLETE; setRawInputType(inputType); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/NameEditText.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/NameEditText.java index f086c5696..153bf2ff2 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/NameEditText.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/NameEditText.java @@ -50,7 +50,7 @@ public class NameEditText extends AutoCompleteTextView { } private void init() { - removeFlag(); + reenableKeyboardSuggestions(); initAdapter(); } @@ -62,10 +62,10 @@ public class NameEditText extends AutoCompleteTextView { } /** - * Hack to re-enable keyboard auto correction in AutoCompleteTextView. + * Hack to re-enable keyboard suggestions in AutoCompleteTextView. * From http://stackoverflow.com/a/22512858 */ - private void removeFlag() { + private void reenableKeyboardSuggestions() { int inputType = getInputType(); inputType &= ~EditorInfo.TYPE_TEXT_FLAG_AUTO_COMPLETE; setRawInputType(inputType); -- cgit v1.2.3 From cfef53be01f72da477d0cb66e40865d7dcd9b125 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Thu, 19 Mar 2015 17:21:26 +0100 Subject: Remove on click on icon --- .../main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java | 2 ++ 1 file changed, 2 insertions(+) (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java index eb484302c..ab76f693e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java @@ -20,6 +20,7 @@ package org.sufficientlysecure.keychain.ui; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentTransaction; +import android.view.View; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.util.Passphrase; @@ -72,6 +73,7 @@ public class CreateKeyActivity extends BaseActivity { if (mFirstTime) { setTitle(R.string.app_name); setActionBarIcon(R.drawable.ic_launcher); + mToolbar.setNavigationOnClickListener(null); } else { setTitle(R.string.title_manage_my_keys); } -- cgit v1.2.3 From 8d6d4328f23b527be9ea794433b3f160cd58e5a5 Mon Sep 17 00:00:00 2001 From: Kent Date: Fri, 20 Mar 2015 06:31:18 +0800 Subject: Implemented #1162: Invoke NFC in Advanced View - Extracted NFC code from ViewKeyActivity to NfcHelper to share code between classes - Changed the private anonymous Handler for NFC into a static private subclass, that uses WeakReference to avoid memory leaks - Added resources needed (retrieved from Graphics) for the NFC button inside ViewKeyAdvShareFragment. - Fixed the ripple boundary of the Share With... button to prevent it from bleeding to other buttons on the right (UX improvement) --- .../keychain/ui/ViewKeyActivity.java | 169 +++------------------ .../keychain/ui/ViewKeyAdvShareFragment.java | 21 ++- 2 files changed, 36 insertions(+), 154 deletions(-) (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index 5834fa502..45ad944c4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -21,18 +21,12 @@ package org.sufficientlysecure.keychain.ui; import android.animation.ArgbEvaluator; import android.animation.ObjectAnimator; import android.annotation.SuppressLint; -import android.annotation.TargetApi; import android.app.Activity; import android.app.ActivityOptions; import android.content.Intent; -import android.content.pm.PackageManager; import android.database.Cursor; import android.graphics.Bitmap; import android.net.Uri; -import android.nfc.NdefMessage; -import android.nfc.NdefRecord; -import android.nfc.NfcAdapter; -import android.nfc.NfcEvent; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; @@ -40,7 +34,6 @@ import android.os.Handler; import android.os.Message; import android.os.Messenger; import android.provider.ContactsContract; -import android.provider.Settings; import android.support.v4.app.ActivityCompat; import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; @@ -58,9 +51,7 @@ import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; - import com.getbase.floatingactionbutton.FloatingActionButton; - import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; @@ -84,6 +75,7 @@ import org.sufficientlysecure.keychain.ui.util.QrCodeUtils; import org.sufficientlysecure.keychain.util.ContactHelper; import org.sufficientlysecure.keychain.util.ExportHelper; import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.NfcHelper; import org.sufficientlysecure.keychain.util.Preferences; import java.util.ArrayList; @@ -93,8 +85,8 @@ public class ViewKeyActivity extends BaseActivity implements LoaderManager.LoaderCallbacks { static final int REQUEST_QR_FINGERPRINT = 1; - static final int REQUEST_DELETE= 2; - static final int REQUEST_EXPORT= 3; + static final int REQUEST_DELETE = 2; + static final int REQUEST_EXPORT = 3; ExportHelper mExportHelper; ProviderHelper mProviderHelper; @@ -115,11 +107,7 @@ public class ViewKeyActivity extends BaseActivity implements private CardView mQrCodeLayout; // NFC - private NfcAdapter mNfcAdapter; - private NfcAdapter.CreateNdefMessageCallback mNdefCallback; - private NfcAdapter.OnNdefPushCompleteCallback mNdefCompleteCallback; - private byte[] mNfcKeyringBytes; - private static final int NFC_SENT = 1; + private NfcHelper mNfcHelper; private static final int LOADER_ID_UNIFIED = 0; @@ -256,7 +244,7 @@ public class ViewKeyActivity extends BaseActivity implements mActionNfc.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - invokeNfcBeam(); + mNfcHelper.invokeNfcBeam(); } }); @@ -264,7 +252,8 @@ public class ViewKeyActivity extends BaseActivity implements // or start new ones. getSupportLoaderManager().initLoader(LOADER_ID_UNIFIED, null, this); - initNfc(mDataUri); + mNfcHelper = new NfcHelper(this, mProviderHelper); + mNfcHelper.initNfc(mDataUri); startFragment(savedInstanceState, mDataUri); } @@ -375,41 +364,6 @@ public class ViewKeyActivity extends BaseActivity implements return true; } - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - private void invokeNfcBeam() { - // Check if device supports NFC - if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC)) { - Notify.createNotify(this, R.string.no_nfc_support, Notify.LENGTH_LONG, Notify.Style.ERROR).show(); - return; - } - // Check for available NFC Adapter - mNfcAdapter = NfcAdapter.getDefaultAdapter(this); - if (mNfcAdapter == null || !mNfcAdapter.isEnabled()) { - Notify.createNotify(this, R.string.error_nfc_needed, Notify.LENGTH_LONG, Notify.Style.ERROR, new Notify.ActionListener() { - @Override - public void onAction() { - Intent intentSettings = new Intent(Settings.ACTION_NFC_SETTINGS); - startActivity(intentSettings); - } - }, R.string.menu_nfc_preferences).show(); - - return; - } - - if (!mNfcAdapter.isNdefPushEnabled()) { - Notify.createNotify(this, R.string.error_beam_needed, Notify.LENGTH_LONG, Notify.Style.ERROR, new Notify.ActionListener() { - @Override - public void onAction() { - Intent intentSettings = new Intent(Settings.ACTION_NFCSHARING_SETTINGS); - startActivity(intentSettings); - } - }, R.string.menu_beam_preferences).show(); - - return; - } - - mNfcAdapter.invokeBeam(this); - } private void scanQrCode() { Intent scanQrCode = new Intent(this, ImportKeysProxyActivity.class); @@ -426,7 +380,7 @@ public class ViewKeyActivity extends BaseActivity implements private void certifyImmediate() { Intent intent = new Intent(this, CertifyKeyActivity.class); - intent.putExtra(CertifyKeyActivity.EXTRA_KEY_IDS, new long[]{mMasterKeyId}); + intent.putExtra(CertifyKeyActivity.EXTRA_KEY_IDS, new long[] {mMasterKeyId}); startCertifyIntent(intent); } @@ -487,11 +441,11 @@ public class ViewKeyActivity extends BaseActivity implements HashMap data = providerHelper.getGenericData( baseUri, - new String[]{KeychainContract.Keys.MASTER_KEY_ID, KeychainContract.KeyRings.HAS_SECRET}, - new int[]{ProviderHelper.FIELD_TYPE_INTEGER, ProviderHelper.FIELD_TYPE_INTEGER}); + new String[] {KeychainContract.Keys.MASTER_KEY_ID, KeychainContract.KeyRings.HAS_SECRET}, + new int[] {ProviderHelper.FIELD_TYPE_INTEGER, ProviderHelper.FIELD_TYPE_INTEGER}); exportHelper.showExportKeysDialog( - new long[]{(Long) data.get(KeychainContract.KeyRings.MASTER_KEY_ID)}, + new long[] {(Long) data.get(KeychainContract.KeyRings.MASTER_KEY_ID)}, Constants.Path.APP_DIR_FILE, ((Long) data.get(KeychainContract.KeyRings.HAS_SECRET) != 0) ); } catch (ProviderHelper.NotFoundException e) { @@ -515,7 +469,7 @@ public class ViewKeyActivity extends BaseActivity implements // Create a new Messenger for the communication back Messenger messenger = new Messenger(returnHandler); DeleteKeyDialogFragment deleteKeyDialog = DeleteKeyDialogFragment.newInstance(messenger, - new long[]{ mMasterKeyId }); + new long[] {mMasterKeyId}); deleteKeyDialog.show(getSupportFragmentManager(), "deleteKeyDialog"); } @@ -546,11 +500,11 @@ public class ViewKeyActivity extends BaseActivity implements return; } - if (requestCode == REQUEST_DELETE && resultCode == Activity.RESULT_OK){ + if (requestCode == REQUEST_DELETE && resultCode == Activity.RESULT_OK) { deleteKey(); } - if (requestCode == REQUEST_EXPORT && resultCode == Activity.RESULT_OK){ + if (requestCode == REQUEST_EXPORT && resultCode == Activity.RESULT_OK) { exportToFile(mDataUri, mExportHelper, mProviderHelper); } @@ -572,7 +526,7 @@ public class ViewKeyActivity extends BaseActivity implements long keyId = new ProviderHelper(this) .getCachedPublicKeyRing(dataUri) .extractOrGetMasterKeyId(); - long[] encryptionKeyIds = new long[]{keyId}; + long[] encryptionKeyIds = new long[] {keyId}; Intent intent; if (text) { intent = new Intent(this, EncryptTextActivity.class); @@ -710,98 +664,9 @@ public class ViewKeyActivity extends BaseActivity implements loadTask.execute(); } - /** - * NFC: Initialize NFC sharing if OS and device supports it - */ - @TargetApi(Build.VERSION_CODES.JELLY_BEAN) - private void initNfc(final Uri dataUri) { - // check if NFC Beam is supported (>= Android 4.1) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - - // Implementation for the CreateNdefMessageCallback interface - mNdefCallback = new NfcAdapter.CreateNdefMessageCallback() { - @Override - public NdefMessage createNdefMessage(NfcEvent event) { - /* - * When a device receives a push with an AAR in it, the application specified in the AAR is - * guaranteed to run. The AAR overrides the tag dispatch system. You can add it back in to - * guarantee that this activity starts when receiving a beamed message. For now, this code - * uses the tag dispatch system. - */ - return new NdefMessage(NdefRecord.createMime(Constants.NFC_MIME, - mNfcKeyringBytes), NdefRecord.createApplicationRecord(Constants.PACKAGE_NAME)); - } - }; - - // Implementation for the OnNdefPushCompleteCallback interface - mNdefCompleteCallback = new NfcAdapter.OnNdefPushCompleteCallback() { - @Override - public void onNdefPushComplete(NfcEvent event) { - // A handler is needed to send messages to the activity when this - // callback occurs, because it happens from a binder thread - mNfcHandler.obtainMessage(NFC_SENT).sendToTarget(); - } - }; - - // Check for available NFC Adapter - mNfcAdapter = NfcAdapter.getDefaultAdapter(this); - if (mNfcAdapter != null) { - /* - * Retrieve mNfcKeyringBytes here asynchronously (to not block the UI) - * and init nfc adapter afterwards. - * mNfcKeyringBytes can not be retrieved in createNdefMessage, because this process - * has no permissions to query the Uri. - */ - AsyncTask initTask = - new AsyncTask() { - protected Void doInBackground(Void... unused) { - try { - Uri blobUri = - KeychainContract.KeyRingData.buildPublicKeyRingUri(dataUri); - mNfcKeyringBytes = (byte[]) mProviderHelper.getGenericData( - blobUri, - KeychainContract.KeyRingData.KEY_RING_DATA, - ProviderHelper.FIELD_TYPE_BLOB); - } catch (ProviderHelper.NotFoundException e) { - Log.e(Constants.TAG, "key not found!", e); - } - - // no AsyncTask return (Void) - return null; - } - - protected void onPostExecute(Void unused) { - // Register callback to set NDEF message - mNfcAdapter.setNdefPushMessageCallback(mNdefCallback, - ViewKeyActivity.this); - // Register callback to listen for message-sent success - mNfcAdapter.setOnNdefPushCompleteCallback(mNdefCompleteCallback, - ViewKeyActivity.this); - } - }; - - initTask.execute(); - } - } - } - - /** - * NFC: This handler receives a message from onNdefPushComplete - */ - private final Handler mNfcHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case NFC_SENT: - Notify.showNotify( - ViewKeyActivity.this, R.string.nfc_successful, Notify.Style.INFO); - break; - } - } - }; // These are the rows that we will retrieve. - static final String[] PROJECTION = new String[]{ + static final String[] PROJECTION = new String[] { KeychainContract.KeyRings._ID, KeychainContract.KeyRings.MASTER_KEY_ID, KeychainContract.KeyRings.USER_ID, @@ -1018,4 +883,4 @@ public class ViewKeyActivity extends BaseActivity implements public void onLoaderReset(Loader loader) { } -} +} \ No newline at end of file diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java index 95a6faea9..29586ae9f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java @@ -52,6 +52,7 @@ import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.ui.util.QrCodeUtils; import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.NfcHelper; import java.io.IOException; @@ -68,10 +69,12 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements private View mFingerprintClipboardButton; private View mKeyShareButton; private View mKeyClipboardButton; + private View mKeyNfcButton; private ImageButton mKeySafeSlingerButton; private View mKeyUploadButton; ProviderHelper mProviderHelper; + NfcHelper mNfcHelper; private static final int LOADER_ID_UNIFIED = 0; @@ -83,6 +86,7 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements View view = inflater.inflate(R.layout.view_key_adv_share_fragment, getContainer()); mProviderHelper = new ProviderHelper(ViewKeyAdvShareFragment.this.getActivity()); + mNfcHelper = new NfcHelper(getActivity(), mProviderHelper); mFingerprint = (TextView) view.findViewById(R.id.view_key_fingerprint); mQrCode = (ImageView) view.findViewById(R.id.view_key_qr_code); @@ -90,6 +94,7 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements mFingerprintShareButton = view.findViewById(R.id.view_key_action_fingerprint_share); mFingerprintClipboardButton = view.findViewById(R.id.view_key_action_fingerprint_clipboard); mKeyShareButton = view.findViewById(R.id.view_key_action_key_share); + mKeyNfcButton = view.findViewById(R.id.view_key_action_key_nfc); mKeyClipboardButton = view.findViewById(R.id.view_key_action_key_clipboard); mKeySafeSlingerButton = (ImageButton) view.findViewById(R.id.view_key_action_key_safeslinger); mKeyUploadButton = view.findViewById(R.id.view_key_action_upload); @@ -128,6 +133,14 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements share(mDataUri, mProviderHelper, false, true); } }); + + mKeyNfcButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mNfcHelper.invokeNfcBeam(); + } + }); + mKeySafeSlingerButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -255,9 +268,12 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements // Prepare the loaders. Either re-connect with an existing ones, // or start new ones. getLoaderManager().initLoader(LOADER_ID_UNIFIED, null, this); + + // Prepare the NfcHelper + mNfcHelper.initNfc(mDataUri); } - static final String[] UNIFIED_PROJECTION = new String[]{ + static final String[] UNIFIED_PROJECTION = new String[] { KeyRings._ID, KeyRings.MASTER_KEY_ID, KeyRings.HAS_ANY_SECRET, KeyRings.USER_ID, KeyRings.FINGERPRINT, KeyRings.ALGORITHM, KeyRings.KEY_SIZE, KeyRings.CREATION, KeyRings.IS_EXPIRED, @@ -362,4 +378,5 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements startActivityForResult(uploadIntent, 0); } -} + +} \ No newline at end of file -- cgit v1.2.3