diff options
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui')
50 files changed, 827 insertions, 786 deletions
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 a2d4a3d7c..b3738851c 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; @@ -168,8 +169,8 @@ public class CertifyKeyFragment extends LoaderFragment @Override public void onClick(View v) { if (mSignMasterKeyId == Constants.key.none) { - Notify.showNotify(getActivity(), getString(R.string.select_key_to_certify), - Notify.Style.ERROR); + Notify.create(getActivity(), getString(R.string.select_key_to_certify), + Notify.Style.ERROR).show(); } else { initiateCertifying(); } @@ -246,14 +247,14 @@ public class CertifyKeyFragment extends LoaderFragment while (!data.isAfterLast()) { long masterKeyId = data.getLong(INDEX_MASTER_KEY_ID); String userId = data.getString(INDEX_USER_ID); - String[] pieces = KeyRing.splitUserId(userId); + KeyRing.UserId pieces = KeyRing.splitUserId(userId); // Two cases: boolean grouped = masterKeyId == lastMasterKeyId; - boolean subGrouped = data.isFirst() || grouped && lastName.equals(pieces[0]); + boolean subGrouped = data.isFirst() || grouped && lastName.equals(pieces.name); // Remember for next loop - lastName = pieces[0]; + lastName = pieces.name; Log.d(Constants.TAG, Long.toString(masterKeyId, 16) + (grouped ? "grouped" : "not grouped")); @@ -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; @@ -360,8 +360,8 @@ public class CertifyKeyFragment extends LoaderFragment // Bail out if there is not at least one user id selected ArrayList<CertifyAction> certifyActions = mUserIdsAdapter.getSelectedCertifyActions(); if (certifyActions.isEmpty()) { - Notify.showNotify(getActivity(), "No identities selected!", - Notify.Style.ERROR); + Notify.create(getActivity(), "No identities selected!", + Notify.Style.ERROR).show(); 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..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,31 +20,74 @@ 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; + +import java.util.ArrayList; 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 static enum FragAction { - START, - TO_RIGHT, - TO_LEFT - } + public static final String FRAGMENT_TAG = "currentFragment"; + + String mName; + String mEmail; + ArrayList<String> 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(null, 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); + mToolbar.setNavigationOnClickListener(null); + } 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 @@ -52,23 +95,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(); @@ -77,8 +120,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 66424e012..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<EmailAdapter.ViewModel> 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; @@ -85,7 +78,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; @@ -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<String> 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<String> getAdditionalEmails() { + ArrayList<String> 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<String> 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<RecyclerView.ViewHolder> { private List<ViewModel> 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 ae42c891d..cbe3eecd4 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; @@ -64,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<String> mAdditionalEmails; - String mPassphrase; - SaveKeyringParcel mSaveKeyringParcel; /** * Creates new instance of this fragment */ - public static CreateKeyFinalFragment newInstance(String name, String email, - ArrayList<String> additionalEmails, - String 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.putString(ARG_PASSPHRASE, passphrase); - frag.setArguments(args); return frag; @@ -107,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().getString(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; @@ -127,7 +105,7 @@ public class CreateKeyFinalFragment extends Fragment { } mEmailEdit.setText(emailText); } else { - mEmailEdit.setText(mEmail); + mEmailEdit.setText(mCreateKeyActivity.mEmail); } mCreateButton.setOnClickListener(new View.OnClickListener() { @@ -140,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 +135,12 @@ public class CreateKeyFinalFragment extends Fragment { } @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + mCreateKeyActivity = (CreateKeyActivity) getActivity(); + } + + @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case REQUEST_EDIT_KEY: { @@ -186,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(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(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; } } @@ -288,8 +277,8 @@ public class CreateKeyFinalFragment extends Fragment { // TODO: upload operation needs a result! // TODO: then combine these results //if (result.getResult() == OperationResultParcel.RESULT_OK) { - //Notify.showNotify(getActivity(), R.string.key_send_success, - //Notify.Style.INFO); + //Notify.create(getActivity(), R.string.key_send_success, + //Notify.Style.OK).show(); Intent data = new Intent(); data.putExtra(OperationResult.EXTRA_RESULT, saveKeyResult); 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..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); @@ -68,7 +60,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,39 +71,31 @@ 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); 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(); } }); @@ -124,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 055ea608b..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; @@ -34,20 +35,13 @@ 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; +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<String> mAdditionalEmails; - // view CreateKeyActivity mCreateKeyActivity; PassphraseEditText mPassphraseEdit; @@ -59,15 +53,10 @@ public class CreateKeyPassphraseFragment extends Fragment { /** * Creates new instance of this fragment */ - public static CreateKeyPassphraseFragment newInstance(String name, String email, - ArrayList<String> 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; @@ -83,7 +72,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 +84,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); } @@ -118,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 @@ -131,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() { @@ -159,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, - mPassphraseEdit.getText().toString() - ); + // 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 <dominik@dominikschuermann.de> + * + * 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 <http://www.gnu.org/licenses/>. + */ + +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/DecryptFilesFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java index c808557a6..a92fb596c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java @@ -139,7 +139,7 @@ public class DecryptFilesFragment extends DecryptFragment { private void decryptAction() { if (mInputUri == null) { - Notify.showNotify(getActivity(), R.string.no_file_selected, Notify.Style.ERROR); + Notify.create(getActivity(), R.string.no_file_selected, Notify.Style.ERROR).show(); return; } @@ -147,7 +147,9 @@ public class DecryptFilesFragment extends DecryptFragment { } private String removeEncryptedAppend(String name) { - if (name.endsWith(".asc") || name.endsWith(".gpg") || name.endsWith(".pgp")) { + if (name.endsWith(Constants.FILE_EXTENSION_ASC) + || name.endsWith(Constants.FILE_EXTENSION_PGP_MAIN) + || name.endsWith(Constants.FILE_EXTENSION_PGP_ALTERNATE)) { return name.substring(0, name.length() - 4); } return name; @@ -189,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); @@ -263,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); @@ -339,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 60103f344..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); @@ -128,14 +129,14 @@ public abstract class DecryptFragment extends Fragment { mSignatureKeyId = signatureResult.getKeyId(); String userId = signatureResult.getPrimaryUserId(); - String[] userIdSplit = KeyRing.splitUserId(userId); - if (userIdSplit[0] != null) { - mSignatureName.setText(userIdSplit[0]); + KeyRing.UserId userIdSplit = KeyRing.splitUserId(userId); + if (userIdSplit.name != null) { + mSignatureName.setText(userIdSplit.name); } else { mSignatureName.setText(R.string.user_id_no_name); } - if (userIdSplit[1] != null) { - mSignatureEmail.setText(userIdSplit[1]); + if (userIdSplit.email != null) { + mSignatureEmail.setText(userIdSplit.email); } else { mSignatureEmail.setText(KeyFormattingUtils.beautifyKeyIdWithPrefix(getActivity(), mSignatureKeyId)); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextActivity.java index 1e9e7bcb1..bc2ec014a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextActivity.java @@ -161,7 +161,7 @@ public class DecryptTextActivity extends BaseActivity { if (sharedText != null) { loadFragment(savedInstanceState, sharedText); } else { - Notify.showNotify(this, R.string.error_invalid_data, Notify.Style.ERROR); + Notify.create(this, R.string.error_invalid_data, Notify.Style.ERROR).show(); } } else { Log.e(Constants.TAG, "ACTION_SEND received non-plaintext, this should not happen in this activity!"); @@ -175,7 +175,7 @@ public class DecryptTextActivity extends BaseActivity { if (extraText != null) { loadFragment(savedInstanceState, extraText); } else { - Notify.showNotify(this, R.string.error_invalid_data, Notify.Style.ERROR); + Notify.create(this, R.string.error_invalid_data, Notify.Style.ERROR).show(); } } else if (ACTION_DECRYPT_FROM_CLIPBOARD.equals(action)) { Log.d(Constants.TAG, "ACTION_DECRYPT_FROM_CLIPBOARD"); 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..80a07214b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java @@ -132,7 +132,7 @@ public class DecryptTextFragment extends DecryptFragment { private void copyToClipboard(String text) { ClipboardReflection.copyToClipboard(getActivity(), text); - Notify.showNotify(getActivity(), R.string.text_copied_to_clipboard, Notify.Style.INFO); + Notify.create(getActivity(), R.string.text_copied_to_clipboard, Notify.Style.OK).show(); } @Override @@ -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 de1eb64c2..86fb8dc80 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<Cursor> { @@ -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 ); } @@ -545,7 +546,7 @@ public class EditKeyFragment extends LoaderFragment implements Messenger messenger = new Messenger(returnHandler); // pre-fill out primary name - String predefinedName = KeyRing.splitUserId(mPrimaryUserId)[0]; + String predefinedName = KeyRing.splitUserId(mPrimaryUserId).name; AddUserIdDialogFragment addUserIdDialog = AddUserIdDialogFragment.newInstance(messenger, predefinedName); @@ -576,11 +577,11 @@ public class EditKeyFragment extends LoaderFragment implements private void returnKeyringParcel() { if (mSaveKeyringParcel.mAddUserIds.size() == 0) { - Notify.showNotify(getActivity(), R.string.edit_key_error_add_identity, Notify.Style.ERROR); + Notify.create(getActivity(), R.string.edit_key_error_add_identity, Notify.Style.ERROR).show(); return; } if (mSaveKeyringParcel.mAddSubKeys.size() == 0) { - Notify.showNotify(getActivity(), R.string.edit_key_error_add_subkey, Notify.Style.ERROR); + Notify.create(getActivity(), R.string.edit_key_error_add_subkey, Notify.Style.ERROR).show(); return; } @@ -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 baf445293..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 { @@ -29,6 +31,8 @@ public interface EncryptActivityInterface { public boolean isUseArmor(); public boolean isUseCompression(); + public boolean isEncryptFilenames(); + public boolean isHiddenRecipients(); public long getSignatureKey(); public long[] getEncryptionKeys(); @@ -37,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<Uri> 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 b862d5b11..fe9b05226 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; @@ -62,14 +63,18 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi private static final int MODE_SYMMETRIC = 1; // model used by fragments - private long mEncryptionKeyIds[] = null; - private String mEncryptionUserIds[] = null; - private long mSigningKeyId = Constants.key.none; - private String mPassphrase = ""; private boolean mUseArmor = false; private boolean mUseCompression = true; private boolean mDeleteAfterEncrypt = false; private boolean mShareAfterEncrypt = false; + 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<Uri> mInputUris; private ArrayList<Uri> mOutputUris; private String mMessage = ""; @@ -89,6 +94,16 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi } @Override + public boolean isEncryptFilenames() { + return mEncryptFilenames; + } + + @Override + public boolean isHiddenRecipients() { + return mHiddenRecipients; + } + + @Override public long getSignatureKey() { return mSigningKeyId; } @@ -122,7 +137,7 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi } @Override - public void setPassphrase(String passphrase) { + public void setPassphrase(Passphrase passphrase) { mPassphrase = passphrase; } @@ -222,14 +237,15 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi } else { data.setCompressionId(CompressionAlgorithmTags.UNCOMPRESSED); } + data.setHiddenRecipients(mHiddenRecipients); data.setEnableAsciiArmorOutput(mUseArmor); data.setSymmetricEncryptionAlgorithm(PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED); data.setSignatureHashAlgorithm(PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED); 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); @@ -268,14 +284,14 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi sendIntent = new Intent(Intent.ACTION_SEND_MULTIPLE); sendIntent.putExtra(Intent.EXTRA_STREAM, mOutputUris); } - sendIntent.setType("application/octet-stream"); + sendIntent.setType(Constants.ENCRYPTED_FILES_MIME); if (!isModeSymmetric() && mEncryptionUserIds != null) { Set<String> users = new HashSet<>(); for (String user : mEncryptionUserIds) { - String[] userId = KeyRing.splitUserId(user); - if (userId[1] != null) { - users.add(userId[1]); + 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()])); @@ -287,7 +303,8 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi // file checks if (mInputUris.isEmpty()) { - Notify.showNotify(this, R.string.no_file_selected, Notify.Style.ERROR); + Notify.create(this, R.string.no_file_selected, Notify.Style.ERROR) + .show(getSupportFragmentManager().findFragmentById(R.id.encrypt_file_fragment)); return false; } else if (mInputUris.size() > 1 && !mShareAfterEncrypt) { // This should be impossible... @@ -301,11 +318,13 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi // symmetric encryption checks if (mPassphrase == null) { - Notify.showNotify(this, R.string.passphrases_do_not_match, Notify.Style.ERROR); + Notify.create(this, R.string.passphrases_do_not_match, Notify.Style.ERROR) + .show(getSupportFragmentManager().findFragmentById(R.id.encrypt_file_fragment)); return false; } if (mPassphrase.isEmpty()) { - Notify.showNotify(this, R.string.passphrase_must_not_be_empty, Notify.Style.ERROR); + Notify.create(this, R.string.passphrase_must_not_be_empty, Notify.Style.ERROR) + .show(getSupportFragmentManager().findFragmentById(R.id.encrypt_file_fragment)); return false; } @@ -317,7 +336,8 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi // Files must be encrypted, only text can be signed-only right now if (!gotEncryptionKeys) { - Notify.showNotify(this, R.string.select_encryption_key, Notify.Style.ERROR); + Notify.create(this, R.string.select_encryption_key, Notify.Style.ERROR) + .show(getSupportFragmentManager().findFragmentById(R.id.encrypt_file_fragment)); return false; } } @@ -371,6 +391,16 @@ public class EncryptFilesActivity extends EncryptActivity implements EncryptActi notifyUpdate(); break; } + case R.id.check_encrypt_filenames: { + mEncryptFilenames = item.isChecked(); + notifyUpdate(); + break; + } +// case R.id.check_hidden_recipients: { +// mHiddenRecipients = item.isChecked(); +// notifyUpdate(); +// break; +// } default: { return super.onOptionsItemSelected(item); } 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 48737d223..4ba76d8ea 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptFilesFragment.java @@ -115,9 +115,9 @@ public class EncryptFilesFragment extends Fragment implements EncryptActivityInt } if (mEncryptInterface.getInputUris().contains(inputUri)) { - Notify.showNotify(getActivity(), + Notify.create(getActivity(), getActivity().getString(R.string.error_file_added_already, FileHelper.getFilename(getActivity(), inputUri)), - Notify.Style.ERROR); + Notify.Style.ERROR).show(this); return; } @@ -137,36 +137,39 @@ public class EncryptFilesFragment extends Fragment implements EncryptActivityInt throw new IllegalStateException(); } Uri inputUri = mEncryptInterface.getInputUris().get(0); + String targetName = + (mEncryptInterface.isEncryptFilenames() ? "1" : FileHelper.getFilename(getActivity(), inputUri)) + + (mEncryptInterface.isUseArmor() ? Constants.FILE_EXTENSION_ASC : Constants.FILE_EXTENSION_PGP_MAIN); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { File file = new File(inputUri.getPath()); File parentDir = file.exists() ? file.getParentFile() : Constants.Path.APP_DIR; - String targetName = FileHelper.getFilename(getActivity(), inputUri) + - (mEncryptInterface.isUseArmor() ? ".asc" : ".gpg"); File targetFile = new File(parentDir, targetName); FileHelper.saveFile(this, getString(R.string.title_encrypt_to_file), getString(R.string.specify_file_to_encrypt_to), targetFile, REQUEST_CODE_OUTPUT); } else { - FileHelper.saveDocument(this, "*/*", FileHelper.getFilename(getActivity(), inputUri) + - (mEncryptInterface.isUseArmor() ? ".asc" : ".gpg"), REQUEST_CODE_OUTPUT); + FileHelper.saveDocument(this, "*/*", targetName, REQUEST_CODE_OUTPUT); } } private void encryptClicked(boolean share) { if (mEncryptInterface.getInputUris().isEmpty()) { - Notify.showNotify(getActivity(), R.string.error_no_file_selected, Notify.Style.ERROR); + Notify.create(getActivity(), R.string.error_no_file_selected, Notify.Style.ERROR).show(this); return; } if (share) { mEncryptInterface.getOutputUris().clear(); + int filenameCounter = 1; for (Uri uri : mEncryptInterface.getInputUris()) { - String targetName = FileHelper.getFilename(getActivity(), uri) + - (mEncryptInterface.isUseArmor() ? ".asc" : ".gpg"); + String targetName = + (mEncryptInterface.isEncryptFilenames() ? String.valueOf(filenameCounter) : FileHelper.getFilename(getActivity(), uri)) + + (mEncryptInterface.isUseArmor() ? Constants.FILE_EXTENSION_ASC : Constants.FILE_EXTENSION_PGP_MAIN); mEncryptInterface.getOutputUris().add(TemporaryStorageProvider.createFile(getActivity(), targetName)); + filenameCounter++; } mEncryptInterface.startEncrypt(true); } else { if (mEncryptInterface.getInputUris().size() > 1) { - Notify.showNotify(getActivity(), R.string.error_multi_not_supported, Notify.Style.ERROR); + Notify.create(getActivity(), R.string.error_multi_not_supported, Notify.Style.ERROR).show(this); return; } showOutputFileDialog(); 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 ee15cf7b5..c800153ae 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java @@ -36,7 +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.Preferences; +import org.sufficientlysecure.keychain.util.Passphrase; import org.sufficientlysecure.keychain.util.ShareHelper; import java.util.ArrayList; @@ -63,16 +63,19 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv private static final int MODE_SYMMETRIC = 1; // model used by fragments + 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 String mPassphrase = ""; - private boolean mShareAfterEncrypt = false; + private Passphrase mPassphrase = new Passphrase(); + private ArrayList<Uri> mInputUris; private ArrayList<Uri> mOutputUris; private String mMessage = ""; - private boolean mUseCompression = true; public boolean isModeSymmetric() { return MODE_SYMMETRIC == mCurrentMode; @@ -84,11 +87,21 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv } @Override + public boolean isEncryptFilenames() { + return false; + } + + @Override public boolean isUseCompression() { return mUseCompression; } @Override + public boolean isHiddenRecipients() { + return mHiddenRecipients; + } + + @Override public long getSignatureKey() { return mSigningKeyId; } @@ -122,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; } @@ -184,8 +198,9 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv // Copy to clipboard copyToClipboard(result.getResultBytes()); result.createNotify(EncryptTextActivity.this).show(); - // Notify.showNotify(EncryptTextActivity.this, - // R.string.encrypt_sign_clipboard_successful, Notify.Style.INFO); + // Notify.create(EncryptTextActivity.this, + // R.string.encrypt_sign_clipboard_successful, Notify.Style.OK) + // .show(getSupportFragmentManager().findFragmentById(R.id.encrypt_text_fragment)); } } @@ -202,6 +217,7 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv } else { data.setCompressionId(CompressionAlgorithmTags.UNCOMPRESSED); } + data.setHiddenRecipients(mHiddenRecipients); data.setSymmetricEncryptionAlgorithm(PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED); data.setSignatureHashAlgorithm(PgpConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_PREFERRED); @@ -210,8 +226,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); @@ -247,15 +263,15 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv private Intent createSendIntent(byte[] resultBytes) { Intent sendIntent; sendIntent = new Intent(Intent.ACTION_SEND); - sendIntent.setType("text/plain"); + sendIntent.setType(Constants.ENCRYPTED_TEXT_MIME); sendIntent.putExtra(Intent.EXTRA_TEXT, new String(resultBytes)); if (!isModeSymmetric() && mEncryptionUserIds != null) { Set<String> users = new HashSet<>(); for (String user : mEncryptionUserIds) { - String[] userId = KeyRing.splitUserId(user); - if (userId[1] != null) { - users.add(userId[1]); + KeyRing.UserId userId = KeyRing.splitUserId(user); + if (userId.email != null) { + users.add(userId.email); } } // pass trough email addresses as extra for email applications @@ -266,7 +282,8 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv protected boolean inputIsValid() { if (mMessage == null) { - Notify.showNotify(this, R.string.error_message, Notify.Style.ERROR); + Notify.create(this, R.string.error_message, Notify.Style.ERROR) + .show(getSupportFragmentManager().findFragmentById(R.id.encrypt_text_fragment)); return false; } @@ -274,11 +291,13 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv // symmetric encryption checks if (mPassphrase == null) { - Notify.showNotify(this, R.string.passphrases_do_not_match, Notify.Style.ERROR); + Notify.create(this, R.string.passphrases_do_not_match, Notify.Style.ERROR) + .show(getSupportFragmentManager().findFragmentById(R.id.encrypt_text_fragment)); return false; } if (mPassphrase.isEmpty()) { - Notify.showNotify(this, R.string.passphrase_must_not_be_empty, Notify.Style.ERROR); + Notify.create(this, R.string.passphrase_must_not_be_empty, Notify.Style.ERROR) + .show(getSupportFragmentManager().findFragmentById(R.id.encrypt_text_fragment)); return false; } @@ -289,7 +308,8 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv && mEncryptionKeyIds.length > 0); if (!gotEncryptionKeys && mSigningKeyId == 0) { - Notify.showNotify(this, R.string.select_encryption_or_signature_key, Notify.Style.ERROR); + Notify.create(this, R.string.select_encryption_or_signature_key, Notify.Style.ERROR) + .show(getSupportFragmentManager().findFragmentById(R.id.encrypt_text_fragment)); return false; } } @@ -353,6 +373,11 @@ public class EncryptTextActivity extends EncryptActivity implements EncryptActiv notifyUpdate(); break; } +// case R.id.check_hidden_recipients: { +// mHiddenRecipients = item.isChecked(); +// notifyUpdate(); +// break; +// } default: { return super.onOptionsItemSelected(item); } 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 <dominik@dominikschuermann.de> - * - * 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 <http://www.gnu.org/licenses/>. - */ - -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/ImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index d51e2c7fc..9143609ad 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -26,6 +26,7 @@ import android.os.Messenger; import android.support.v4.app.Fragment; import android.view.View; import android.view.View.OnClickListener; +import android.view.ViewGroup; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; @@ -277,7 +278,8 @@ public class ImportKeysActivity extends BaseActivity { private boolean isFingerprintValid(String fingerprint) { if (fingerprint == null || fingerprint.length() < 40) { - Notify.showNotify(this, R.string.import_qr_code_too_short_fingerprint, Notify.Style.ERROR); + Notify.create(this, R.string.import_qr_code_too_short_fingerprint, Notify.Style.ERROR) + .show((ViewGroup) findViewById(R.id.import_snackbar)); return false; } else { return true; @@ -329,7 +331,8 @@ public class ImportKeysActivity extends BaseActivity { return; } - result.createNotify(ImportKeysActivity.this).show(); + result.createNotify(ImportKeysActivity.this) + .show((ViewGroup) findViewById(R.id.import_snackbar)); } } }; @@ -372,7 +375,8 @@ public class ImportKeysActivity extends BaseActivity { startService(intent); } catch (IOException e) { Log.e(Constants.TAG, "Problem writing cache file", e); - Notify.showNotify(this, "Problem writing cache file!", Notify.Style.ERROR); + Notify.create(this, "Problem writing cache file!", Notify.Style.ERROR) + .show((ViewGroup) findViewById(R.id.import_snackbar)); } } else if (ls instanceof ImportKeysListFragment.CloudLoaderState) { ImportKeysListFragment.CloudLoaderState sls = (ImportKeysListFragment.CloudLoaderState) ls; @@ -412,7 +416,8 @@ public class ImportKeysActivity extends BaseActivity { // start service with intent startService(intent); } else { - Notify.showNotify(this, R.string.error_nothing_import, Notify.Style.ERROR); + Notify.create(this, R.string.error_nothing_import, Notify.Style.ERROR) + .show((ViewGroup) findViewById(R.id.import_snackbar)); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java index cc8b47971..1c1e5fe99 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysProxyActivity.java @@ -154,7 +154,7 @@ public class ImportKeysProxyActivity extends FragmentActivity { String fingerprint = null; // example: openpgp4fpr:73EE2314F65FA92EC2390D3A718C070100012282 - if (uri.getScheme().toLowerCase(Locale.ENGLISH).equals(Constants.FINGERPRINT_SCHEME)) { + if (uri != null && uri.getScheme() != null && uri.getScheme().toLowerCase(Locale.ENGLISH).equals(Constants.FINGERPRINT_SCHEME)) { fingerprint = uri.getEncodedSchemeSpecificPart().toLowerCase(Locale.ENGLISH); } 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 8c34efba2..5f1189deb 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -169,6 +169,22 @@ public class KeyListFragment extends LoaderFragment mStickyList.setDrawingListUnderStickyHeader(false); mStickyList.setFastScrollEnabled(true); + // Adds an empty footer view so that the Floating Action Button won't block content + // in last few rows. + View footer = new View(getActivity()); + + int spacing = (int) android.util.TypedValue.applyDimension( + android.util.TypedValue.COMPLEX_UNIT_DIP, 72, getResources().getDisplayMetrics() + ); + + android.widget.AbsListView.LayoutParams params = new android.widget.AbsListView.LayoutParams( + android.widget.AbsListView.LayoutParams.MATCH_PARENT, + spacing + ); + + footer.setLayoutParams(params); + mStickyList.addFooterView(footer, null, false); + /* * Multi-selection */ @@ -369,13 +385,13 @@ public class KeyListFragment extends LoaderFragment /** * Show dialog to delete key * - * @param hasSecret must contain whether the list of masterKeyIds contains a secret key or not + * @param hasSecret must contain whether the list of masterKeyIds contains a secret key or not */ public void showDeleteKeyDialog(final ActionMode mode, long[] masterKeyIds, boolean hasSecret) { // Can only work on singular secret keys if (hasSecret && masterKeyIds.length > 1) { - Notify.showNotify(getActivity(), R.string.secret_cannot_multiple, - Notify.Style.ERROR); + Notify.create(getActivity(), R.string.secret_cannot_multiple, + Notify.Style.ERROR).show(); return; } @@ -468,28 +484,29 @@ public class KeyListFragment extends LoaderFragment case R.id.menu_key_list_debug_read: try { KeychainDatabase.debugBackup(getActivity(), true); - Notify.showNotify(getActivity(), "Restored debug_backup.db", Notify.Style.INFO); + Notify.create(getActivity(), "Restored debug_backup.db", Notify.Style.OK).show(); getActivity().getContentResolver().notifyChange(KeychainContract.KeyRings.CONTENT_URI, null); } catch (IOException e) { Log.e(Constants.TAG, "IO Error", e); - Notify.showNotify(getActivity(), "IO Error " + e.getMessage(), Notify.Style.ERROR); + Notify.create(getActivity(), "IO Error " + e.getMessage(), Notify.Style.ERROR).show(); } return true; case R.id.menu_key_list_debug_write: try { KeychainDatabase.debugBackup(getActivity(), false); - Notify.showNotify(getActivity(), "Backup to debug_backup.db completed", Notify.Style.INFO); + Notify.create(getActivity(), "Backup to debug_backup.db completed", Notify.Style.OK).show(); } catch (IOException e) { Log.e(Constants.TAG, "IO Error", e); - Notify.showNotify(getActivity(), "IO Error: " + e.getMessage(), Notify.Style.ERROR); + Notify.create(getActivity(), "IO Error: " + e.getMessage(), Notify.Style.ERROR).show(); } return true; 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; @@ -688,14 +705,14 @@ public class KeyListFragment extends LoaderFragment { // set name and stuff, common to both key types String userId = cursor.getString(INDEX_USER_ID); - String[] userIdSplit = KeyRing.splitUserId(userId); - if (userIdSplit[0] != null) { - h.mMainUserId.setText(highlighter.highlight(userIdSplit[0])); + KeyRing.UserId userIdSplit = KeyRing.splitUserId(userId); + if (userIdSplit.name != null) { + h.mMainUserId.setText(highlighter.highlight(userIdSplit.name)); } else { h.mMainUserId.setText(R.string.user_id_no_name); } - if (userIdSplit[1] != null) { - h.mMainUserIdRest.setText(highlighter.highlight(userIdSplit[1])); + if (userIdSplit.email != null) { + h.mMainUserIdRest.setText(highlighter.highlight(userIdSplit.email)); h.mMainUserIdRest.setVisibility(View.VISIBLE); } else { h.mMainUserIdRest.setVisibility(View.GONE); @@ -908,5 +925,4 @@ public class KeyListFragment extends LoaderFragment } - } 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/PassphraseDialogActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/PassphraseDialogActivity.java index b06cf0abd..b77637696 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; /** @@ -212,9 +213,9 @@ public class PassphraseDialogActivity extends FragmentActivity { // the catch clause doesn't return. try { String mainUserId = mSecretRing.getPrimaryUserIdWithFallback(); - String[] mainUserIdSplit = KeyRing.splitUserId(mainUserId); - if (mainUserIdSplit[0] != null) { - userId = mainUserIdSplit[0]; + KeyRing.UserId mainUserIdSplit = KeyRing.splitUserId(mainUserId); + if (mainUserIdSplit.name != null) { + userId = mainUserIdSplit.name; } else { userId = getString(R.string.user_id_no_name); } @@ -240,7 +241,7 @@ public class PassphraseDialogActivity extends FragmentActivity { break; // special case: empty passphrase just returns the empty passphrase case PASSPHRASE_EMPTY: - finishCaching(""); + finishCaching(new Passphrase("")); default: message = "This should not happen!"; break; @@ -322,7 +323,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) { @@ -399,7 +400,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/QrCodeViewActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/QrCodeViewActivity.java index d3c1d971a..43af07bbe 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/QrCodeViewActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/QrCodeViewActivity.java @@ -80,7 +80,7 @@ public class QrCodeViewActivity extends BaseActivity { KeychainContract.KeyRings.FINGERPRINT, ProviderHelper.FIELD_TYPE_BLOB); if (blob == null) { Log.e(Constants.TAG, "key not found!"); - Notify.showNotify(this, R.string.error_key_not_found, Style.ERROR); + Notify.create(this, R.string.error_key_not_found, Style.ERROR).show(); ActivityCompat.finishAfterTransition(QrCodeViewActivity.this); } @@ -102,7 +102,7 @@ public class QrCodeViewActivity extends BaseActivity { }); } catch (ProviderHelper.NotFoundException e) { Log.e(Constants.TAG, "key not found!", e); - Notify.showNotify(this, R.string.error_key_not_found, Style.ERROR); + Notify.create(this, R.string.error_key_not_found, Style.ERROR).show(); ActivityCompat.finishAfterTransition(QrCodeViewActivity.this); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java index d0cea5f05..863aef65f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SafeSlingerActivity.java @@ -205,7 +205,7 @@ public class SafeSlingerActivity extends BaseActivity { activity.startService(intent); } catch (IOException e) { Log.e(Constants.TAG, "Problem writing cache file", e); - Notify.showNotify(activity, "Problem writing cache file!", Notify.Style.ERROR); + Notify.create(activity, "Problem writing cache file!", Notify.Style.ERROR).show(); } } else { // give everything else down to KeyListActivity! 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 70c590728..435a455dc 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.FragmentManager; import android.support.v4.app.LoaderManager; @@ -59,9 +52,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; @@ -76,6 +67,8 @@ import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; import org.sufficientlysecure.keychain.ui.linked.LinkedIdWizard; 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; @@ -84,6 +77,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 +87,8 @@ public class ViewKeyActivity extends BaseActivity implements LoaderManager.LoaderCallbacks<Cursor> { 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 +109,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 +246,7 @@ public class ViewKeyActivity extends BaseActivity implements mActionNfc.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - invokeNfcBeam(); + mNfcHelper.invokeNfcBeam(); } }); @@ -264,7 +254,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); } @@ -291,31 +282,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: { @@ -328,7 +319,7 @@ public class ViewKeyActivity extends BaseActivity implements try { updateFromKeyserver(mDataUri, mProviderHelper); } catch (ProviderHelper.NotFoundException e) { - Notify.showNotify(this, R.string.error_key_not_found, Notify.Style.ERROR); + Notify.create(this, R.string.error_key_not_found, Notify.Style.ERROR).show(); } return true; } @@ -364,41 +355,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); @@ -415,7 +371,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); } @@ -464,22 +420,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<String, Object> 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<String, Object> 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.create(this, R.string.error_key_not_found, Notify.Style.ERROR).show(); + 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 @@ -491,7 +457,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 @@ -507,32 +477,27 @@ public class ViewKeyActivity extends BaseActivity implements String fp = data.getStringExtra(ImportKeysProxyActivity.EXTRA_FINGERPRINT); if (fp == null) { - Notify.createNotify(this, "Error scanning fingerprint!", + Notify.create(this, "Error scanning fingerprint!", Notify.LENGTH_LONG, Notify.Style.ERROR).show(); return; } if (mFingerprint.equalsIgnoreCase(fp)) { certifyImmediate(); } else { - Notify.createNotify(this, "Fingerprints did not match!", + Notify.create(this, "Fingerprints did not match!", Notify.LENGTH_LONG, Notify.Style.ERROR).show(); } return; } - if (requestCode == REQUEST_DELETE && resultCode == Activity.RESULT_OK){ - deleteKey(mDataUri, mExportHelper); - } - 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); - } + if (requestCode == REQUEST_DELETE && resultCode == Activity.RESULT_OK) { + deleteKey(); } + if (requestCode == REQUEST_EXPORT && resultCode == Activity.RESULT_OK) { + exportToFile(mDataUri, mExportHelper, mProviderHelper); + } if (data != null && data.hasExtra(OperationResult.EXTRA_RESULT)) { OperationResult result = data.getParcelableExtra(OperationResult.EXTRA_RESULT); @@ -545,14 +510,14 @@ public class ViewKeyActivity extends BaseActivity implements private void encrypt(Uri dataUri, boolean text) { // If there is no encryption key, don't bother. if (!mHasEncrypt) { - Notify.showNotify(this, R.string.error_no_encrypt_subkey, Notify.Style.ERROR); + Notify.create(this, R.string.error_no_encrypt_subkey, Notify.Style.ERROR).show(); return; } try { 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); @@ -690,98 +655,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<Void, Void, Void> initTask = - new AsyncTask<Void, Void, Void>() { - 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, @@ -849,9 +725,9 @@ public class ViewKeyActivity extends BaseActivity implements startFragment(mIsSecret, fpData); // get name, email, and comment from USER_ID - String[] mainUserId = KeyRing.splitUserId(data.getString(INDEX_USER_ID)); - if (mainUserId[0] != null) { - mName.setText(mainUserId[0]); + KeyRing.UserId mainUserId = KeyRing.splitUserId(data.getString(INDEX_USER_ID)); + if (mainUserId.name != null) { + mName.setText(mainUserId.name); } else { mName.setText(R.string.user_id_no_name); } @@ -892,6 +768,7 @@ public class ViewKeyActivity extends BaseActivity implements } else if (mIsExpired) { if (mIsSecret) { mStatusText.setText(R.string.view_key_expired_secret); + mName.setText(mainUserId.name); } else { mStatusText.setText(R.string.view_key_expired); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java index 0654f0c9a..f17d6e0fd 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java @@ -197,9 +197,9 @@ public class ViewKeyAdvActivity extends BaseActivity implements case LOADER_ID_UNIFIED: { if (data.moveToFirst()) { // get name, email, and comment from USER_ID - String[] mainUserId = KeyRing.splitUserId(data.getString(INDEX_USER_ID)); - if (mainUserId[0] != null) { - setTitle(mainUserId[0]); + KeyRing.UserId mainUserId = KeyRing.splitUserId(data.getString(INDEX_USER_ID)); + if (mainUserId.name != null) { + setTitle(mainUserId.name); } else { setTitle(R.string.user_id_no_name); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvCertsFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvCertsFragment.java index 90d7a400f..f5c8a87b1 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvCertsFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvCertsFragment.java @@ -237,9 +237,9 @@ public class ViewKeyAdvCertsFragment extends LoaderFragment implements TextView wSignStatus = (TextView) view.findViewById(R.id.signStatus); String signerKeyId = KeyFormattingUtils.beautifyKeyIdWithPrefix(getActivity(), cursor.getLong(mIndexSignerKeyId)); - String[] userId = KeyRing.splitUserId(cursor.getString(mIndexSignerUserId)); - if (userId[0] != null) { - wSignerName.setText(userId[0]); + KeyRing.UserId userId = KeyRing.splitUserId(cursor.getString(mIndexSignerUserId)); + if (userId.name != null) { + wSignerName.setText(userId.name); } else { wSignerName.setText(R.string.user_id_no_name); } 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..6bd3a9303 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) { @@ -186,13 +199,13 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements } else { message = getResources().getString(R.string.key_copied_to_clipboard); } - Notify.showNotify(getActivity(), message, Notify.Style.OK); + Notify.create(getActivity(), message, Notify.Style.OK).show(); } else { // Android will fail with android.os.TransactionTooLargeException if key is too big // see http://www.lonestarprod.com/?p=34 if (content.length() >= 86389) { - Notify.showNotify(getActivity(), R.string.key_too_big_for_sharing, - Notify.Style.ERROR); + Notify.create(getActivity(), R.string.key_too_big_for_sharing, + Notify.Style.ERROR).show(); return; } @@ -210,10 +223,10 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements } } catch (PgpGeneralException | IOException e) { Log.e(Constants.TAG, "error processing key!", e); - Notify.showNotify(getActivity(), R.string.error_key_processing, Notify.Style.ERROR); + Notify.create(getActivity(), R.string.error_key_processing, Notify.Style.ERROR).show(); } catch (ProviderHelper.NotFoundException e) { Log.e(Constants.TAG, "key not found!", e); - Notify.showNotify(getActivity(), R.string.error_key_not_found, Notify.Style.ERROR); + Notify.create(getActivity(), R.string.error_key_not_found, Notify.Style.ERROR).show(); } } @@ -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 diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java index 429feb075..db88de676 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java @@ -140,25 +140,25 @@ public class ImportKeysAdapter extends ArrayAdapter<ImportKeysListEntry> { // main user id String userId = entry.getUserIds().get(0); - String[] userIdSplit = KeyRing.splitUserId(userId); + KeyRing.UserId userIdSplit = KeyRing.splitUserId(userId); // name - if (userIdSplit[0] != null) { + if (userIdSplit.name != null) { // show red user id if it is a secret key if (entry.isSecretKey()) { holder.mainUserId.setText(mActivity.getString(R.string.secret_key) - + " " + userIdSplit[0]); + + " " + userIdSplit.name); } else { - holder.mainUserId.setText(highlighter.highlight(userIdSplit[0])); + holder.mainUserId.setText(highlighter.highlight(userIdSplit.name)); } } else { holder.mainUserId.setText(R.string.user_id_no_name); } // email - if (userIdSplit[1] != null) { + if (userIdSplit.email != null) { holder.mainUserIdRest.setVisibility(View.VISIBLE); - holder.mainUserIdRest.setText(highlighter.highlight(userIdSplit[1])); + holder.mainUserIdRest.setText(highlighter.highlight(userIdSplit.email)); } else { holder.mainUserIdRest.setVisibility(View.GONE); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/MultiUserIdsAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/MultiUserIdsAdapter.java index 70b57aa93..5218273a0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/MultiUserIdsAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/MultiUserIdsAdapter.java @@ -33,7 +33,6 @@ import android.widget.TextView; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.KeyRing; import org.sufficientlysecure.keychain.service.CertifyActionsParcel.CertifyAction; -import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import java.util.ArrayList; @@ -83,9 +82,9 @@ public class MultiUserIdsAdapter extends CursorAdapter { { // first one String userId = uids.get(0); - String[] splitUserId = KeyRing.splitUserId(userId); - if (splitUserId[0] != null) { - vName.setText(splitUserId[0]); + KeyRing.UserId splitUserId = KeyRing.splitUserId(userId); + if (splitUserId.name != null) { + vName.setText(splitUserId.name); } else { vName.setText(R.string.user_id_no_name); } @@ -93,9 +92,9 @@ public class MultiUserIdsAdapter extends CursorAdapter { if (isHeader == 1) { vHeaderId.setVisibility(View.VISIBLE); String message; - if (splitUserId[0] != null) { + if (splitUserId.name != null) { message = mContext.getString(R.string.section_uids_to_certify) + - splitUserId[0]; + splitUserId.name; } else { message = mContext.getString(R.string.section_uids_to_certify) + context.getString(R.string.user_id_no_name); @@ -108,13 +107,13 @@ public class MultiUserIdsAdapter extends CursorAdapter { StringBuilder lines = new StringBuilder(); for (String uid : uids) { - String[] splitUserId = KeyRing.splitUserId(uid); - if (splitUserId[1] == null) { + KeyRing.UserId splitUserId = KeyRing.splitUserId(uid); + if (splitUserId.email == null) { continue; } - lines.append(splitUserId[1]); - if (splitUserId[2] != null) { - lines.append(" (").append(splitUserId[2]).append(")"); + lines.append(splitUserId.email); + if (splitUserId.comment != null) { + lines.append(" (").append(splitUserId.comment).append(")"); } lines.append('\n'); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java index 892e30a54..3308a4500 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java @@ -122,16 +122,16 @@ abstract public class SelectKeyCursorAdapter extends CursorAdapter { ViewHolderItem h = (ViewHolderItem) view.getTag(); String userId = cursor.getString(mIndexUserId); - String[] userIdSplit = KeyRing.splitUserId(userId); + KeyRing.UserId userIdSplit = KeyRing.splitUserId(userId); - if (userIdSplit[0] != null) { - h.mainUserId.setText(highlighter.highlight(userIdSplit[0])); + if (userIdSplit.name != null) { + h.mainUserId.setText(highlighter.highlight(userIdSplit.name)); } else { h.mainUserId.setText(R.string.user_id_no_name); } - if (userIdSplit[1] != null) { + if (userIdSplit.email != null) { h.mainUserIdRest.setVisibility(View.VISIBLE); - h.mainUserIdRest.setText(highlighter.highlight(userIdSplit[1])); + h.mainUserIdRest.setText(highlighter.highlight(userIdSplit.email)); } else { h.mainUserIdRest.setVisibility(View.GONE); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java index 1cf3f4d38..c68c078ad 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java @@ -72,20 +72,20 @@ public class UserIdsAdapter extends UserAttributesAdapter { vDeleteButton.setVisibility(View.GONE); // not used String userId = cursor.getString(INDEX_USER_ID); - String[] splitUserId = KeyRing.splitUserId(userId); - if (splitUserId[0] != null) { - vName.setText(splitUserId[0]); + KeyRing.UserId splitUserId = KeyRing.splitUserId(userId); + if (splitUserId.name != null) { + vName.setText(splitUserId.name); } else { vName.setText(R.string.user_id_no_name); } - if (splitUserId[1] != null) { - vAddress.setText(splitUserId[1]); + if (splitUserId.email != null) { + vAddress.setText(splitUserId.email); vAddress.setVisibility(View.VISIBLE); } else { vAddress.setVisibility(View.GONE); } - if (splitUserId[2] != null) { - vComment.setText(splitUserId[2]); + if (splitUserId.comment != null) { + vComment.setText(splitUserId.comment); vComment.setVisibility(View.VISIBLE); } else { vComment.setVisibility(View.GONE); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAddedAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAddedAdapter.java index 970855c77..c7197b46d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAddedAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAddedAdapter.java @@ -92,20 +92,20 @@ public class UserIdsAddedAdapter extends ArrayAdapter<String> { // save reference to model item holder.mModel = getItem(position); - String[] splitUserId = KeyRing.splitUserId(holder.mModel); - if (splitUserId[0] != null) { - holder.vName.setText(splitUserId[0]); + KeyRing.UserId splitUserId = KeyRing.splitUserId(holder.mModel); + if (splitUserId.name != null) { + holder.vName.setText(splitUserId.name); } else { holder.vName.setText(R.string.user_id_no_name); } - if (splitUserId[1] != null) { - holder.vAddress.setText(splitUserId[1]); + if (splitUserId.email != null) { + holder.vAddress.setText(splitUserId.email); holder.vAddress.setVisibility(View.VISIBLE); } else { holder.vAddress.setVisibility(View.GONE); } - if (splitUserId[2] != null) { - holder.vComment.setText(splitUserId[2]); + if (splitUserId.comment != null) { + holder.vComment.setText(splitUserId.comment); holder.vComment.setVisibility(View.VISIBLE); } else { holder.vComment.setVisibility(View.GONE); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddUserIdDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddUserIdDialogFragment.java index 5dd675fd3..fe4ba0262 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddUserIdDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddUserIdDialogFragment.java @@ -100,8 +100,8 @@ public class AddUserIdDialogFragment extends DialogFragment implements OnEditorA // return new user id back to activity Bundle data = new Bundle(); - String userId = KeyRing.createUserId(mName.getText().toString(), - mEmail.getText().toString(), mComment.getText().toString()); + String userId = KeyRing.createUserId(new KeyRing.UserId(mName.getText().toString(), + mEmail.getText().toString(), mComment.getText().toString())); data.putString(MESSAGE_DATA_USER_ID, userId); sendMessageToHandler(MESSAGE_OKAY, data); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java index 20f20c32e..f512ecca2 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java @@ -100,9 +100,9 @@ public class DeleteKeyDialogFragment extends DialogFragment { } ); String name; - String[] mainUserId = KeyRing.splitUserId((String) data.get(KeyRings.USER_ID)); - if (mainUserId[0] != null) { - name = mainUserId[0]; + KeyRing.UserId mainUserId = KeyRing.splitUserId((String) data.get(KeyRings.USER_ID)); + if (mainUserId.name != null) { + name = mainUserId.name; } else { name = getString(R.string.user_id_no_name); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java index 7ac85781f..63b6d26ac 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java @@ -190,7 +190,7 @@ public class FileDialogFragment extends DialogFragment { mFile = file; mFilename.setText(mFile.getName()); } else { - Notify.showNotify(getActivity(), R.string.no_file_selected, Notify.Style.ERROR); + Notify.create(getActivity(), R.string.no_file_selected, Notify.Style.ERROR).show(); } } 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); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateDnsStep2Fragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateDnsStep2Fragment.java index 2e6181f07..c0e2fd29c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateDnsStep2Fragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateDnsStep2Fragment.java @@ -118,7 +118,7 @@ public class LinkedIdCreateDnsStep2Fragment extends LinkedIdCreateFinalFragment private void proofToClipboard() { ClipboardReflection.copyToClipboard(getActivity(), mResourceString); - Notify.showNotify(getActivity(), R.string.linked_text_clipboard, Notify.Style.OK); + Notify.create(getActivity(), R.string.linked_text_clipboard, Notify.Style.OK).show(); } private void saveFile(Uri uri) { @@ -127,10 +127,10 @@ public class LinkedIdCreateDnsStep2Fragment extends LinkedIdCreateFinalFragment new PrintWriter(getActivity().getContentResolver().openOutputStream(uri)); out.print(mResourceString); if (out.checkError()) { - Notify.showNotify(getActivity(), "Error writing file!", Style.ERROR); + Notify.create(getActivity(), "Error writing file!", Style.ERROR).show(); } } catch (FileNotFoundException e) { - Notify.showNotify(getActivity(), "File could not be opened for writing!", Style.ERROR); + Notify.create(getActivity(), "File could not be opened for writing!", Style.ERROR).show(); e.printStackTrace(); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateFinalFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateFinalFragment.java index 28fbe6f19..99e770857 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateFinalFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateFinalFragment.java @@ -168,7 +168,7 @@ public abstract class LinkedIdCreateFinalFragment extends Fragment { private void startCertify() { if (mVerifiedResource == null) { - Notify.showNotify(getActivity(), R.string.linked_need_verify, Notify.Style.ERROR); + Notify.create(getActivity(), R.string.linked_need_verify, Notify.Style.ERROR).show(); return; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateGithubStep1Fragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateGithubStep1Fragment.java index 86a514fa9..77eccf3be 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateGithubStep1Fragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateGithubStep1Fragment.java @@ -80,14 +80,14 @@ public class LinkedIdCreateGithubStep1Fragment extends Fragment { super.onPostExecute(result); if (result == null) { - Notify.showNotify(getActivity(), - "Connection error while checking username!", Notify.Style.ERROR); + Notify.create(getActivity(), + "Connection error while checking username!", Notify.Style.ERROR).show(); return; } if (!result) { - Notify.showNotify(getActivity(), - "This handle does not exist on Github!", Notify.Style.ERROR); + Notify.create(getActivity(), + "This handle does not exist on Github!", Notify.Style.ERROR).show(); return; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateHttpsStep2Fragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateHttpsStep2Fragment.java index 55ac6e075..5559c0daf 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateHttpsStep2Fragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateHttpsStep2Fragment.java @@ -125,7 +125,7 @@ public class LinkedIdCreateHttpsStep2Fragment extends LinkedIdCreateFinalFragmen private void proofSave () { String state = Environment.getExternalStorageState(); if (!Environment.MEDIA_MOUNTED.equals(state)) { - Notify.showNotify(getActivity(), "External storage not available!", Style.ERROR); + Notify.create(getActivity(), "External storage not available!", Style.ERROR); return; } @@ -146,11 +146,10 @@ public class LinkedIdCreateHttpsStep2Fragment extends LinkedIdCreateFinalFragmen new PrintWriter(getActivity().getContentResolver().openOutputStream(uri)); out.print(mResourceString); if (out.checkError()) { - Notify.showNotify(getActivity(), "Error writing file!", Style.ERROR); + Notify.create(getActivity(), "Error writing file!", Style.ERROR).show(); } } catch (FileNotFoundException e) { - Notify.showNotify(getActivity(), "File could not be opened for writing!", Style.ERROR); - e.printStackTrace(); + Notify.create(getActivity(), "File could not be opened for writing!", Style.ERROR).show(); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateTwitterStep1Fragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateTwitterStep1Fragment.java index c22351f87..c36f98058 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateTwitterStep1Fragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateTwitterStep1Fragment.java @@ -78,13 +78,13 @@ public class LinkedIdCreateTwitterStep1Fragment extends Fragment { super.onPostExecute(result); if (result == null) { - Notify.showNotify(getActivity(), + Notify.create(getActivity(), "Connection error while checking username!", Notify.Style.ERROR); return; } if (!result) { - Notify.showNotify(getActivity(), + Notify.create(getActivity(), "This handle does not exist on Twitter!", Notify.Style.ERROR); return; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdViewFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdViewFragment.java index 502abe8e6..41d0178a3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdViewFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdViewFragment.java @@ -55,6 +55,7 @@ import org.sufficientlysecure.keychain.ui.util.Notify.Style; import org.sufficientlysecure.keychain.ui.widget.CertListWidget; import org.sufficientlysecure.keychain.ui.widget.CertifyKeySpinner; import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.util.Passphrase; public class LinkedIdViewFragment extends Fragment implements @@ -153,7 +154,7 @@ public class LinkedIdViewFragment extends Fragment implements } catch (IOException e) { Log.e(Constants.TAG, "error parsing identity", e); - Notify.createNotify(getActivity(), "Error parsing identity!", + Notify.create(getActivity(), "Error parsing identity!", Notify.LENGTH_LONG, Style.ERROR).show(); finishFragment(); } @@ -492,7 +493,7 @@ public class LinkedIdViewFragment extends Fragment implements } // get the user's passphrase for this key (if required) - String passphrase; + Passphrase passphrase; long certifyKeyId = mViewHolder.vKeySpinner.getSelectedItemId(); try { passphrase = PassphraseCacheService.getCachedPassphrase( 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..7e07ed818 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 @@ -18,7 +18,9 @@ package org.sufficientlysecure.keychain.ui.util; import android.app.Activity; -import android.content.res.Resources; +import android.support.v4.app.Fragment; +import android.view.View; +import android.view.ViewGroup; import com.nispok.snackbar.Snackbar; import com.nispok.snackbar.Snackbar.SnackbarDuration; @@ -35,157 +37,147 @@ import org.sufficientlysecure.keychain.util.FabContainer; */ public class Notify { - public static enum Style {OK, WARN, INFO, ERROR} + public static enum Style { + OK, WARN, ERROR; + + public void applyToBar(Snackbar bar) { + + switch (this) { + case OK: + // bar.actionColorResource(R.color.android_green_light); + bar.lineColorResource(R.color.android_green_light); + break; + case WARN: + // bar.textColorResource(R.color.android_orange_light); + bar.lineColorResource(R.color.android_orange_light); + break; + case ERROR: + // bar.textColorResource(R.color.android_red_light); + bar.lineColorResource(R.color.android_red_light); + break; + } + + } + } public static final int LENGTH_INDEFINITE = 0; public static final int LENGTH_LONG = 3500; - /** - * Shows a simple in-layout notification with the CharSequence given as parameter - * @param text Text to show - * @param style Notification styling - */ - public static void showNotify(final Activity activity, CharSequence text, Style style) { - - Snackbar bar = getSnackbar(activity) + public static Showable create(final Activity activity, String text, int duration, Style style, + final ActionListener actionListener, int actionResId) { + final Snackbar snackbar = Snackbar.with(activity) + .type(SnackbarType.MULTI_LINE) .text(text); - switch (style) { - case OK: - break; - case WARN: - bar.textColor(activity.getResources().getColor(R.color.android_orange_light)); - break; - case ERROR: - bar.textColor(activity.getResources().getColor(R.color.android_red_light)); - break; - } - - SnackbarManager.show(bar); - - } - - public static Showable createNotify (Activity activity, int resId, int duration, Style style) { - final Snackbar bar = getSnackbar(activity) - .text(resId); - if (duration == LENGTH_INDEFINITE) { - bar.duration(SnackbarDuration.LENGTH_INDEFINITE); + snackbar.duration(SnackbarDuration.LENGTH_INDEFINITE); } else { - bar.duration(duration); + snackbar.duration(duration); } - switch (style) { - case OK: - bar.actionColor(activity.getResources().getColor(R.color.android_green_light)); - break; - case WARN: - bar.textColor(activity.getResources().getColor(R.color.android_orange_light)); - break; - case ERROR: - bar.textColor(activity.getResources().getColor(R.color.android_red_light)); - break; - } - - return new Showable () { - @Override - public void show() { - SnackbarManager.show(bar); - } - }; - } - - public static Showable createNotify(Activity activity, int resId, int duration, Style style, - final ActionListener listener, int resIdAction) { - return createNotify(activity, activity.getString(resId), duration, style, listener, resIdAction); - } - - public static Showable createNotify(Activity activity, String msg, int duration, Style style) { - return createNotify(activity, msg, duration, style, null, 0); - } + style.applyToBar(snackbar); - public static Showable createNotify(Activity activity, String msg, int duration, Style style, - final ActionListener listener, int resIdAction) { + if (actionListener != null) { + snackbar.actionLabel(actionResId) + .actionListener(new ActionClickListener() { + @Override + public void onActionClicked(Snackbar snackbar) { + actionListener.onAction(); + } + }); + } - final Snackbar bar = getSnackbar(activity) - .text(msg); + if (activity instanceof FabContainer) { + snackbar.eventListener(new EventListenerAdapter() { + @Override + public void onShow(Snackbar snackbar) { + ((FabContainer) activity).fabMoveUp(snackbar.getHeight()); + } - if (listener != null) { - bar.actionLabel(resIdAction); - bar.actionListener(new ActionClickListener() { @Override - public void onActionClicked(Snackbar snackbar) { - listener.onAction(); + public void onDismiss(Snackbar snackbar) { + ((FabContainer) activity).fabRestorePosition(); } }); } - if (duration == LENGTH_INDEFINITE) { - bar.duration(SnackbarDuration.LENGTH_INDEFINITE); - } else { - bar.duration(duration); - } + return new Showable() { + @Override + public void show() { + SnackbarManager.show(snackbar, activity); + } - switch (style) { - case OK: - bar.actionColor(activity.getResources().getColor(R.color.android_green_light)); - break; - case WARN: - bar.textColor(activity.getResources().getColor(R.color.android_orange_light)); - break; - case ERROR: - bar.textColor(activity.getResources().getColor(R.color.android_red_light)); - break; - } + @Override + public void show(Fragment fragment) { + if (fragment != null) { + View view = fragment.getView(); + + if (view != null && view instanceof ViewGroup) { + SnackbarManager.show(snackbar, (ViewGroup) view); + return; + } + } + + show(); + } - return new Showable () { @Override - public void show() { - SnackbarManager.show(bar); + public void show(ViewGroup viewGroup) { + if (viewGroup != null) { + SnackbarManager.show(snackbar, viewGroup); + return; + } + + show(); } }; + } + public static Showable create(Activity activity, String text, int duration, Style style) { + return create(activity, text, duration, style, null, -1); } - /** - * Shows a simple in-layout notification with the resource text from given id - * @param resId ResourceId of notification text - * @param style Notification styling - * @throws Resources.NotFoundException - */ - public static void showNotify(Activity activity, int resId, Style style) throws Resources.NotFoundException { - showNotify(activity, activity.getResources().getText(resId), style); + public static Showable create(Activity activity, String text, Style style) { + return create(activity, text, LENGTH_LONG, style); } - private static Snackbar getSnackbar(final Activity activity) { - Snackbar bar = Snackbar.with(activity) - .type(SnackbarType.MULTI_LINE) - .duration(SnackbarDuration.LENGTH_LONG); + public static Showable create(Activity activity, int textResId, int duration, Style style, + ActionListener actionListener, int actionResId) { + return create(activity, activity.getString(textResId), duration, style, actionListener, actionResId); + } - if (activity instanceof FabContainer) { - bar.eventListener(new EventListenerAdapter() { - @Override - public void onShow(Snackbar snackbar) { - ((FabContainer) activity).fabMoveUp(snackbar.getHeight()); - } + public static Showable create(Activity activity, int textResId, int duration, Style style) { + return create(activity, activity.getString(textResId), duration, style); + } - @Override - public void onDismiss(Snackbar snackbar) { - ((FabContainer) activity).fabRestorePosition(); - } - }); - } - return bar; + public static Showable create(Activity activity, int textResId, Style style) { + return create(activity, activity.getString(textResId), style); } public interface Showable { + + /** + * Shows the notification on the bottom of the Activity. + */ public void show(); + /** + * Shows the notification on the bottom of the Fragment. + */ + public void show(Fragment fragment); + + /** + * Shows the notification on the given ViewGroup. + * The viewGroup should be either a RelativeLayout or FrameLayout. + */ + public void show(ViewGroup viewGroup); + } public interface ActionListener { + public void onAction(); } -}
\ No newline at end of file +} 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/EncryptKeyCompletionView.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java index 94a321f29..ceace1d26 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java @@ -184,7 +184,7 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView { public class EncryptionKey { private String mUserIdFull; - private String[] mUserId; + private KeyRing.UserId mUserId; private long mKeyId; private boolean mHasDuplicate; private Date mCreation; @@ -222,23 +222,23 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView { } public String getPrimary() { - if (mUserId[0] != null) { - return mUserId[0]; + if (mUserId.name != null) { + return mUserId.name; } else { - return mUserId[1]; + return mUserId.email; } } public String getSecondary() { - if (mUserId[1] != null) { - return mUserId[1]; + if (mUserId.email != null) { + return mUserId.email; } else { return getCreationDate(); } } public String getTertiary() { - if (mUserId[0] != null) { + if (mUserId.name != null) { return getCreationDate(); } else { return null; 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 aeb013c71..70f4e7792 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 @@ -39,7 +39,6 @@ import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.KeyRing; import org.sufficientlysecure.keychain.provider.KeychainContract; -import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.util.Log; import java.util.Calendar; @@ -158,9 +157,9 @@ public abstract class KeySpinner extends TintSpinner implements LoaderManager.Lo TextView vKeyEmail = (TextView) view.findViewById(R.id.keyspinner_key_email); TextView vDuplicate = (TextView) view.findViewById(R.id.keyspinner_duplicate); - String[] userId = KeyRing.splitUserId(cursor.getString(mIndexUserId)); - vKeyName.setText(userId[2] == null ? userId[0] : (userId[0] + " (" + userId[2] + ")")); - vKeyEmail.setText(userId[1]); + KeyRing.UserId userId = KeyRing.splitUserId(cursor.getString(mIndexUserId)); + vKeyName.setText(userId.name); + vKeyEmail.setText(userId.email); boolean duplicate = cursor.getLong(mIndexDuplicate) > 0; if (duplicate) { 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); |