diff options
Diffstat (limited to 'OpenKeychain')
7 files changed, 391 insertions, 230 deletions
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 766e65e8b..6c1902af1 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java @@ -240,7 +240,7 @@ public class DecryptFilesFragment extends DecryptFragment { } case KeychainIntentService.ACTION_DECRYPT_VERIFY: { // display signature result in activity - onResult(pgpResult); + loadVerifyResult(pgpResult); if (mDeleteAfter.isChecked()) { // Create and show dialog to delete original file @@ -308,4 +308,8 @@ public class DecryptFilesFragment extends DecryptFragment { } } + @Override + protected void onVerifyLoaded(boolean verified) { + + } } 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 33209be86..d641f02f9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java @@ -17,26 +17,49 @@ package org.sufficientlysecure.keychain.ui; +import java.util.ArrayList; + import android.content.Intent; +import android.database.Cursor; +import android.net.Uri; import android.os.Bundle; +import android.os.Message; +import android.os.Messenger; +import android.support.v4.app.LoaderManager; +import android.support.v4.content.CursorLoader; +import android.support.v4.content.Loader; +import android.util.Log; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import org.openintents.openpgp.OpenPgpSignatureResult; +import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult; +import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; +import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.pgp.KeyRing; +import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; import org.sufficientlysecure.keychain.provider.KeychainContract; +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; +import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.service.KeychainIntentService; +import org.sufficientlysecure.keychain.service.ServiceProgressHandler; import org.sufficientlysecure.keychain.ui.base.CryptoOperationFragment; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State; +import org.sufficientlysecure.keychain.ui.util.Notify; +import org.sufficientlysecure.keychain.ui.util.Notify.Style; +import org.sufficientlysecure.keychain.util.Preferences; + -public abstract class DecryptFragment extends CryptoOperationFragment { - private static final int RESULT_CODE_LOOKUP_KEY = 0x00007006; +public abstract class DecryptFragment extends CryptoOperationFragment implements + LoaderManager.LoaderCallbacks<Cursor> { - protected long mSignatureKeyId = 0; + public static final int LOADER_ID_UNIFIED = 0; protected LinearLayout mResultLayout; @@ -46,155 +69,118 @@ public abstract class DecryptFragment extends CryptoOperationFragment { protected TextView mSignatureText; protected View mSignatureLayout; - protected View mSignatureDivider1; - protected View mSignatureDivider2; protected TextView mSignatureName; protected TextView mSignatureEmail; protected TextView mSignatureAction; + private OpenPgpSignatureResult mSignatureResult; + @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); - mResultLayout = (LinearLayout) getView().findViewById(R.id.result_main_layout); + mResultLayout = (LinearLayout) view.findViewById(R.id.result_main_layout); mResultLayout.setVisibility(View.GONE); - mEncryptionIcon = (ImageView) getView().findViewById(R.id.result_encryption_icon); - mEncryptionText = (TextView) getView().findViewById(R.id.result_encryption_text); - mSignatureIcon = (ImageView) getView().findViewById(R.id.result_signature_icon); - mSignatureText = (TextView) getView().findViewById(R.id.result_signature_text); - mSignatureLayout = getView().findViewById(R.id.result_signature_layout); - mSignatureDivider1 = getView().findViewById(R.id.result_signature_divider1); - mSignatureDivider2 = getView().findViewById(R.id.result_signature_divider2); - mSignatureName = (TextView) getView().findViewById(R.id.result_signature_name); - mSignatureEmail = (TextView) getView().findViewById(R.id.result_signature_email); - mSignatureAction = (TextView) getView().findViewById(R.id.result_signature_action); + mEncryptionIcon = (ImageView) view.findViewById(R.id.result_encryption_icon); + mEncryptionText = (TextView) view.findViewById(R.id.result_encryption_text); + mSignatureIcon = (ImageView) view.findViewById(R.id.result_signature_icon); + mSignatureText = (TextView) view.findViewById(R.id.result_signature_text); + mSignatureLayout = view.findViewById(R.id.result_signature_layout); + mSignatureName = (TextView) view.findViewById(R.id.result_signature_name); + mSignatureEmail = (TextView) view.findViewById(R.id.result_signature_email); + mSignatureAction = (TextView) view.findViewById(R.id.result_signature_action); } private void lookupUnknownKey(long unknownKeyId) { - Intent intent = new Intent(getActivity(), ImportKeysActivity.class); - intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER); - intent.putExtra(ImportKeysActivity.EXTRA_KEY_ID, unknownKeyId); - startActivityForResult(intent, RESULT_CODE_LOOKUP_KEY); - } - - private void showKey(long keyId) { - Intent viewKeyIntent = new Intent(getActivity(), ViewKeyActivity.class); - viewKeyIntent.setData(KeychainContract.KeyRings - .buildGenericKeyRingUri(keyId)); - startActivity(viewKeyIntent); - } - /** - * - * @return returns false if signature is invalid, key is revoked or expired. - */ - protected boolean onResult(DecryptVerifyResult decryptVerifyResult) { - final OpenPgpSignatureResult signatureResult = decryptVerifyResult.getSignatureResult(); + // Message is received after importing is done in KeychainIntentService + ServiceProgressHandler serviceHandler = new ServiceProgressHandler(getActivity()) { + public void handleMessage(Message message) { + // handle messages by standard KeychainIntentServiceHandler first + super.handleMessage(message); - boolean valid = false; + if (message.arg1 == MessageStatus.OKAY.ordinal()) { + // get returned data bundle + Bundle returnData = message.getData(); - mSignatureKeyId = 0; - mResultLayout.setVisibility(View.VISIBLE); - if (signatureResult != null) { - mSignatureKeyId = signatureResult.getKeyId(); - - String userId = signatureResult.getPrimaryUserId(); - 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.email != null) { - mSignatureEmail.setText(userIdSplit.email); - } else { - mSignatureEmail.setText(KeyFormattingUtils.beautifyKeyIdWithPrefix(getActivity(), mSignatureKeyId)); - } + if (returnData == null) { + return; + } - if (signatureResult.isSignatureOnly()) { - mEncryptionText.setText(R.string.decrypt_result_not_encrypted); - KeyFormattingUtils.setStatusImage(getActivity(), mEncryptionIcon, mEncryptionText, State.NOT_ENCRYPTED); - } else { - mEncryptionText.setText(R.string.decrypt_result_encrypted); - KeyFormattingUtils.setStatusImage(getActivity(), mEncryptionIcon, mEncryptionText, State.ENCRYPTED); - } + final ImportKeyResult result = + returnData.getParcelable(OperationResult.EXTRA_RESULT); - switch (signatureResult.getStatus()) { - case OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED: { - mSignatureText.setText(R.string.decrypt_result_signature_certified); - KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.VERIFIED); + // if (!result.success()) { + result.createNotify(getActivity()).show(); + // } - setSignatureLayoutVisibility(View.VISIBLE); - setShowAction(mSignatureKeyId); + getLoaderManager().restartLoader(LOADER_ID_UNIFIED, null, DecryptFragment.this); - valid = true; - break; } + } + }; - case OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED: { - mSignatureText.setText(R.string.decrypt_result_signature_uncertified); - KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.UNVERIFIED); + // fill values for this action + Bundle data = new Bundle(); - setSignatureLayoutVisibility(View.VISIBLE); - setShowAction(mSignatureKeyId); + // search config + { + Preferences prefs = Preferences.getPreferences(getActivity()); + Preferences.CloudSearchPrefs cloudPrefs = + new Preferences.CloudSearchPrefs(true, true, prefs.getPreferredKeyserver()); + data.putString(KeychainIntentService.IMPORT_KEY_SERVER, cloudPrefs.keyserver); + } - valid = true; - break; - } + { + ParcelableKeyRing keyEntry = new ParcelableKeyRing(null, + KeyFormattingUtils.convertKeyIdToHex(unknownKeyId), null); + ArrayList<ParcelableKeyRing> selectedEntries = new ArrayList<>(); + selectedEntries.add(keyEntry); - case OpenPgpSignatureResult.SIGNATURE_KEY_MISSING: { - mSignatureText.setText(R.string.decrypt_result_signature_missing_key); - KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.UNKNOWN_KEY); - - setSignatureLayoutVisibility(View.VISIBLE); - mSignatureAction.setText(R.string.decrypt_result_action_Lookup); - mSignatureAction.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_file_download_grey_24dp, 0); - mSignatureLayout.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - lookupUnknownKey(mSignatureKeyId); - } - }); - - valid = true; - break; - } + data.putParcelableArrayList(KeychainIntentService.IMPORT_KEY_LIST, selectedEntries); + } - case OpenPgpSignatureResult.SIGNATURE_KEY_EXPIRED: { - mSignatureText.setText(R.string.decrypt_result_signature_expired_key); - KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.EXPIRED); + // Send all information needed to service to query keys in other thread + Intent intent = new Intent(getActivity(), KeychainIntentService.class); + intent.setAction(KeychainIntentService.ACTION_IMPORT_KEYRING); + intent.putExtra(KeychainIntentService.EXTRA_DATA, data); - setSignatureLayoutVisibility(View.VISIBLE); - setShowAction(mSignatureKeyId); + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(serviceHandler); + intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); - valid = false; - break; - } + getActivity().startService(intent); - case OpenPgpSignatureResult.SIGNATURE_KEY_REVOKED: { - mSignatureText.setText(R.string.decrypt_result_signature_revoked_key); - KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.REVOKED); + } - setSignatureLayoutVisibility(View.VISIBLE); - setShowAction(mSignatureKeyId); + private void showKey(long keyId) { + try { - valid = false; - break; - } + Intent viewKeyIntent = new Intent(getActivity(), ViewKeyActivity.class); + long masterKeyId = new ProviderHelper(getActivity()).getCachedPublicKeyRing( + KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(keyId) + ).getMasterKeyId(); + viewKeyIntent.setData(KeyRings.buildGenericKeyRingUri(masterKeyId)); + startActivity(viewKeyIntent); + + } catch (PgpKeyNotFoundException e) { + Notify.create(getActivity(), R.string.error_key_not_found, Style.ERROR); + } + } + + /** + * @return returns false if signature is invalid, key is revoked or expired. + */ + protected void loadVerifyResult(DecryptVerifyResult decryptVerifyResult) { - case OpenPgpSignatureResult.SIGNATURE_ERROR: { - mSignatureText.setText(R.string.decrypt_result_invalid_signature); - KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.INVALID); + mSignatureResult = decryptVerifyResult.getSignatureResult(); + mResultLayout.setVisibility(View.VISIBLE); - setSignatureLayoutVisibility(View.GONE); + // unsigned data + if (mSignatureResult == null) { - valid = false; - break; - } - } - } else { setSignatureLayoutVisibility(View.GONE); mSignatureText.setText(R.string.decrypt_result_no_signature); @@ -202,16 +188,27 @@ public abstract class DecryptFragment extends CryptoOperationFragment { mEncryptionText.setText(R.string.decrypt_result_encrypted); KeyFormattingUtils.setStatusImage(getActivity(), mEncryptionIcon, mEncryptionText, State.ENCRYPTED); - valid = true; + getLoaderManager().destroyLoader(LOADER_ID_UNIFIED); + + onVerifyLoaded(true); + + return; + } + + if (mSignatureResult.isSignatureOnly()) { + mEncryptionText.setText(R.string.decrypt_result_not_encrypted); + KeyFormattingUtils.setStatusImage(getActivity(), mEncryptionIcon, mEncryptionText, State.NOT_ENCRYPTED); + } else { + mEncryptionText.setText(R.string.decrypt_result_encrypted); + KeyFormattingUtils.setStatusImage(getActivity(), mEncryptionIcon, mEncryptionText, State.ENCRYPTED); } - return valid; + getLoaderManager().restartLoader(LOADER_ID_UNIFIED, null, this); + } private void setSignatureLayoutVisibility(int visibility) { mSignatureLayout.setVisibility(visibility); - mSignatureDivider1.setVisibility(visibility); - mSignatureDivider2.setVisibility(visibility); } private void setShowAction(final long signatureKeyId) { @@ -225,4 +222,177 @@ public abstract class DecryptFragment extends CryptoOperationFragment { }); } + // These are the rows that we will retrieve. + static final String[] UNIFIED_PROJECTION = new String[]{ + KeychainContract.KeyRings._ID, + KeychainContract.KeyRings.MASTER_KEY_ID, + KeychainContract.KeyRings.USER_ID, + KeychainContract.KeyRings.IS_REVOKED, + KeychainContract.KeyRings.IS_EXPIRED, + KeychainContract.KeyRings.VERIFIED, + }; + + @SuppressWarnings("unused") + static final int INDEX_MASTER_KEY_ID = 1; + static final int INDEX_USER_ID = 2; + static final int INDEX_IS_REVOKED = 3; + static final int INDEX_IS_EXPIRED = 4; + static final int INDEX_VERIFIED = 5; + + @Override + public Loader<Cursor> onCreateLoader(int id, Bundle args) { + if (id != LOADER_ID_UNIFIED) { + return null; + } + + Uri baseUri = KeychainContract.KeyRings.buildUnifiedKeyRingsFindBySubkeyUri( + mSignatureResult.getKeyId()); + return new CursorLoader(getActivity(), baseUri, UNIFIED_PROJECTION, null, null, null); + } + + @Override + public void onLoadFinished(Loader<Cursor> loader, Cursor data) { + + if (loader.getId() != LOADER_ID_UNIFIED) { + return; + } + + // If the key is unknown, show it as such + if (data.getCount() == 0 || !data.moveToFirst()) { + showUnknownKeyStatus(); + return; + } + + long signatureKeyId = mSignatureResult.getKeyId(); + + String userId = data.getString(INDEX_USER_ID); + 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.email != null) { + mSignatureEmail.setText(userIdSplit.email); + } else { + mSignatureEmail.setText(KeyFormattingUtils.beautifyKeyIdWithPrefix( + getActivity(), mSignatureResult.getKeyId())); + } + + boolean isRevoked = data.getInt(INDEX_IS_REVOKED) != 0; + boolean isExpired = data.getInt(INDEX_IS_EXPIRED) != 0; + boolean isVerified = data.getInt(INDEX_VERIFIED) > 0; + + if (isRevoked) { + mSignatureText.setText(R.string.decrypt_result_signature_revoked_key); + KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.REVOKED); + + setSignatureLayoutVisibility(View.VISIBLE); + setShowAction(signatureKeyId); + + onVerifyLoaded(false); + + } else if (isExpired) { + mSignatureText.setText(R.string.decrypt_result_signature_expired_key); + KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.EXPIRED); + + setSignatureLayoutVisibility(View.VISIBLE); + setShowAction(signatureKeyId); + + onVerifyLoaded(true); + + } else if (isVerified) { + mSignatureText.setText(R.string.decrypt_result_signature_certified); + KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.VERIFIED); + + setSignatureLayoutVisibility(View.VISIBLE); + setShowAction(signatureKeyId); + + onVerifyLoaded(true); + + } else { + mSignatureText.setText(R.string.decrypt_result_signature_uncertified); + KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.UNVERIFIED); + + setSignatureLayoutVisibility(View.VISIBLE); + setShowAction(signatureKeyId); + + onVerifyLoaded(true); + } + + } + + @Override + public void onLoaderReset(Loader<Cursor> loader) { + + if (loader.getId() != LOADER_ID_UNIFIED) { + return; + } + + setSignatureLayoutVisibility(View.GONE); + + } + + private void showUnknownKeyStatus() { + + final long signatureKeyId = mSignatureResult.getKeyId(); + + int result = mSignatureResult.getStatus(); + if (result != OpenPgpSignatureResult.SIGNATURE_KEY_MISSING + && result != OpenPgpSignatureResult.SIGNATURE_ERROR) { + Log.e(Constants.TAG, "got missing status for non-missing key, shouldn't happen!"); + } + + String userId = mSignatureResult.getPrimaryUserId(); + 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.email != null) { + mSignatureEmail.setText(userIdSplit.email); + } else { + mSignatureEmail.setText(KeyFormattingUtils.beautifyKeyIdWithPrefix( + getActivity(), mSignatureResult.getKeyId())); + } + + switch (mSignatureResult.getStatus()) { + + case OpenPgpSignatureResult.SIGNATURE_KEY_MISSING: { + mSignatureText.setText(R.string.decrypt_result_signature_missing_key); + KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.UNKNOWN_KEY); + + setSignatureLayoutVisibility(View.VISIBLE); + mSignatureAction.setText(R.string.decrypt_result_action_Lookup); + mSignatureAction + .setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_file_download_grey_24dp, 0); + mSignatureLayout.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + lookupUnknownKey(signatureKeyId); + } + }); + + onVerifyLoaded(true); + + break; + } + + case OpenPgpSignatureResult.SIGNATURE_ERROR: { + mSignatureText.setText(R.string.decrypt_result_invalid_signature); + KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.INVALID); + + setSignatureLayoutVisibility(View.GONE); + + onVerifyLoaded(false); + break; + } + + } + + } + + protected abstract void onVerifyLoaded(boolean verified); + } 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 9c6c89c43..1b9ae917f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java @@ -23,6 +23,9 @@ import android.os.Bundle; import android.os.Message; import android.os.Messenger; import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.Button; @@ -39,7 +42,6 @@ import org.sufficientlysecure.keychain.service.ServiceProgressHandler; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment; import org.sufficientlysecure.keychain.ui.util.Notify; -import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.ShareHelper; import java.io.UnsupportedEncodingException; @@ -54,6 +56,7 @@ public class DecryptTextFragment extends DecryptFragment { // model private String mCiphertext; + private boolean mShowMenuOptions = false; /** * Creates new instance of this fragment @@ -79,22 +82,6 @@ public class DecryptTextFragment extends DecryptFragment { mInvalidLayout = (LinearLayout) view.findViewById(R.id.decrypt_text_invalid); mText = (TextView) view.findViewById(R.id.decrypt_text_plaintext); - View vShareButton = view.findViewById(R.id.action_decrypt_share_plaintext); - vShareButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - startActivity(sendWithChooserExcludingEncrypt(mText.getText().toString())); - } - }); - - View vCopyButton = view.findViewById(R.id.action_decrypt_copy_plaintext); - vCopyButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - copyToClipboard(mText.getText().toString()); - } - }); - Button vInvalidButton = (Button) view.findViewById(R.id.decrypt_text_invalid_button); vInvalidButton.setOnClickListener(new View.OnClickListener() { @Override @@ -139,6 +126,8 @@ public class DecryptTextFragment extends DecryptFragment { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + setHasOptionsMenu(true); + String ciphertext = getArguments().getString(ARG_CIPHERTEXT); if (ciphertext != null) { mCiphertext = ciphertext; @@ -147,6 +136,33 @@ public class DecryptTextFragment extends DecryptFragment { } @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); + if (mShowMenuOptions) { + inflater.inflate(R.menu.decrypt_menu, menu); + } + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.decrypt_share: { + startActivity(sendWithChooserExcludingEncrypt(mText.getText().toString())); + break; + } + case R.id.decrypt_copy: { + copyToClipboard(mText.getText().toString()); + break; + } + default: { + return super.onOptionsItemSelected(item); + } + } + + return true; + } + + @Override protected void cryptoOperation(CryptoInputParcel cryptoInput) { // Send all information needed to service to decrypt in other thread Intent intent = new Intent(getActivity(), KeychainIntentService.class); @@ -206,15 +222,8 @@ public class DecryptTextFragment extends DecryptFragment { pgpResult.createNotify(getActivity()).show(); // display signature result in activity - boolean valid = onResult(pgpResult); + loadVerifyResult(pgpResult); - if (valid) { - mInvalidLayout.setVisibility(View.GONE); - mValidLayout.setVisibility(View.VISIBLE); - } else { - mInvalidLayout.setVisibility(View.VISIBLE); - mValidLayout.setVisibility(View.GONE); - } } else { pgpResult.createNotify(getActivity()).show(); // TODO: show also invalid layout with different text? @@ -234,4 +243,19 @@ public class DecryptTextFragment extends DecryptFragment { getActivity().startService(intent); } + @Override + protected void onVerifyLoaded(boolean verified) { + + mShowMenuOptions = verified; + getActivity().supportInvalidateOptionsMenu(); + + if (verified) { + mInvalidLayout.setVisibility(View.GONE); + mValidLayout.setVisibility(View.VISIBLE); + } else { + mInvalidLayout.setVisibility(View.VISIBLE); + mValidLayout.setVisibility(View.GONE); + } + + } } diff --git a/OpenKeychain/src/main/res/layout/decrypt_result_include.xml b/OpenKeychain/src/main/res/layout/decrypt_result_include.xml index debc1106f..f64d72987 100644 --- a/OpenKeychain/src/main/res/layout/decrypt_result_include.xml +++ b/OpenKeychain/src/main/res/layout/decrypt_result_include.xml @@ -1,10 +1,12 @@ <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" android:id="@+id/result_main_layout" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="@color/holo_gray_bright"> + android:background="@color/holo_gray_bright" + tools:showIn="@layout/decrypt_text_fragment"> <LinearLayout android:orientation="vertical" @@ -13,7 +15,8 @@ android:paddingLeft="16dp" android:paddingRight="16dp" android:paddingTop="4dp" - android:paddingBottom="4dp"> + android:paddingBottom="4dp" + android:animateLayoutChanges="true"> <LinearLayout android:orientation="horizontal" @@ -32,10 +35,11 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" - android:text="Not Encrypted (set in-code)" android:layout_marginLeft="8dp" android:layout_marginTop="8dp" - android:layout_marginBottom="8dp" /> + android:layout_marginBottom="8dp" + tools:text="Encryption status text" + /> </LinearLayout> <LinearLayout @@ -55,25 +59,19 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" - android:text="Signed by (set in-code)" android:layout_marginLeft="8dp" android:layout_marginTop="8dp" - android:layout_marginBottom="8dp" /> + android:layout_marginBottom="8dp" + tools:text="Signature status text" + /> </LinearLayout> - <View - android:id="@+id/result_signature_divider1" - android:layout_width="match_parent" - android:layout_height="1dip" - android:layout_marginLeft="32dp" - android:background="?android:attr/listDivider" /> - <LinearLayout android:id="@+id/result_signature_layout" android:layout_width="match_parent" android:layout_height="?android:attr/listPreferredItemHeight" android:clickable="true" - android:layout_marginLeft="32dp" + android:paddingLeft="4dp" android:paddingRight="4dp" android:background="?android:selectableItemBackground" android:orientation="horizontal"> @@ -83,6 +81,7 @@ android:layout_height="match_parent" android:layout_weight="1" android:paddingRight="4dp" + android:paddingLeft="4dp" android:gravity="center_vertical" android:orientation="vertical"> @@ -91,15 +90,16 @@ android:textAppearance="?android:attr/textAppearanceMedium" android:layout_width="match_parent" android:layout_height="wrap_content" - android:text="Alice (set in-code)" /> + tools:text="Alice" /> <TextView android:id="@+id/result_signature_email" android:textAppearance="?android:attr/textAppearanceSmall" android:layout_width="match_parent" android:layout_height="wrap_content" - android:text="alice@example.com (set in-code)" - android:gravity="center_vertical" /> + android:gravity="center_vertical" + tools:text="alice@example.com" + /> </LinearLayout> @@ -114,6 +114,7 @@ <TextView android:id="@+id/result_signature_action" android:paddingLeft="8dp" + android:paddingRight="8dp" android:textAppearance="?android:attr/textAppearanceMedium" android:layout_width="wrap_content" android:layout_height="match_parent" @@ -121,17 +122,10 @@ android:drawableRight="@drawable/ic_vpn_key_grey_24dp" android:drawablePadding="8dp" android:gravity="center_vertical" - android:background="?android:selectableItemBackground" /> + /> </LinearLayout> - <View - android:id="@+id/result_signature_divider2" - android:layout_width="match_parent" - android:layout_height="1dip" - android:layout_marginLeft="32dp" - android:background="?android:attr/listDivider" /> - </LinearLayout> <View diff --git a/OpenKeychain/src/main/res/layout/decrypt_text_fragment.xml b/OpenKeychain/src/main/res/layout/decrypt_text_fragment.xml index 1d0873c96..efdbf03c0 100644 --- a/OpenKeychain/src/main/res/layout/decrypt_text_fragment.xml +++ b/OpenKeychain/src/main/res/layout/decrypt_text_fragment.xml @@ -36,55 +36,6 @@ </ScrollView> - <View - android:layout_width="match_parent" - android:layout_height="1dip" - android:layout_marginLeft="16dp" - android:layout_marginRight="16dp" - android:background="?android:attr/listDivider" /> - - <LinearLayout - android:id="@+id/action_decrypt_share_plaintext" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginLeft="16dp" - android:layout_marginRight="16dp" - android:clickable="true" - android:background="?android:selectableItemBackground" - android:orientation="horizontal"> - - <TextView - android:paddingLeft="8dp" - android:paddingRight="8dp" - android:textAppearance="?android:attr/textAppearanceMedium" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:minHeight="?android:attr/listPreferredItemHeight" - android:text="@string/btn_add_share_decrypted_text" - android:drawableRight="@drawable/ic_share_grey_24dp" - android:drawablePadding="8dp" - android:gravity="center_vertical" - android:layout_weight="1" /> - - <View - android:layout_width="1dip" - android:layout_height="match_parent" - android:gravity="right" - android:layout_marginBottom="8dp" - android:layout_marginTop="8dp" - android:background="?android:attr/listDivider" /> - - <ImageButton - android:id="@+id/action_decrypt_copy_plaintext" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:padding="8dp" - android:src="@drawable/ic_content_copy_grey_24dp" - android:layout_gravity="center_vertical" - android:background="?android:selectableItemBackground" /> - - </LinearLayout> - </LinearLayout> <LinearLayout diff --git a/OpenKeychain/src/main/res/menu/decrypt_menu.xml b/OpenKeychain/src/main/res/menu/decrypt_menu.xml new file mode 100644 index 000000000..c0d7a519f --- /dev/null +++ b/OpenKeychain/src/main/res/menu/decrypt_menu.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto"> + + <item + android:id="@+id/decrypt_copy" + android:title="@string/btn_copy_decrypted_text" + android:icon="@drawable/ic_action_encrypt_copy_24dp" + app:showAsAction="ifRoom" /> + + <item + android:id="@+id/decrypt_share" + android:title="@string/btn_share_decrypted_text" + android:icon="@drawable/ic_action_encrypt_share_24dp" + app:showAsAction="ifRoom" /> + +</menu>
\ No newline at end of file diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 155ff6dee..0c80066c0 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -79,7 +79,8 @@ <string name="btn_view_cert_key">"View certification key"</string> <string name="btn_create_key">"Create key"</string> <string name="btn_add_files">"Add file(s)"</string> - <string name="btn_add_share_decrypted_text">"Share decrypted text"</string> + <string name="btn_share_decrypted_text">"Share decrypted text"</string> + <string name="btn_copy_decrypted_text">"Copy decrypted text"</string> <string name="btn_decrypt_clipboard">"Decrypt text from clipboard"</string> <string name="btn_decrypt_and_verify">"and verify signatures"</string> <string name="btn_decrypt_files">"Decrypt files"</string> @@ -284,16 +285,16 @@ <!-- results shown after decryption/verification --> <string name="decrypt_result_no_signature">"Not Signed"</string> <string name="decrypt_result_invalid_signature">"Invalid signature!"</string> - <string name="decrypt_result_signature_uncertified">"Signed by (not certified!)"</string> - <string name="decrypt_result_signature_certified">"Signed by"</string> - <string name="decrypt_result_signature_expired_key">"Key is expired!"</string> - <string name="decrypt_result_signature_revoked_key">"Key has been revoked!"</string> - <string name="decrypt_result_signature_missing_key">"Unknown public key"</string> + <string name="decrypt_result_signature_uncertified">"Signed by <b>unconfirmed</b> key"</string> + <string name="decrypt_result_signature_certified">"Signed by confirmed key"</string> + <string name="decrypt_result_signature_expired_key">"Signed by <b>expired</b> key!"</string> + <string name="decrypt_result_signature_revoked_key">"Signed by <b>revoked</b> key!"</string> + <string name="decrypt_result_signature_missing_key">"Signed by <b>unknown public key</b>"</string> <string name="decrypt_result_encrypted">"Encrypted"</string> <string name="decrypt_result_not_encrypted">"Not Encrypted"</string> <string name="decrypt_result_action_show">"Show"</string> <string name="decrypt_result_action_Lookup">"Lookup"</string> - <string name="decrypt_invalid_text">"Either the signature is invalid or the key has been revoked/is expired. You cannot be sure who wrote the text. Do you still want to display it?"</string> + <string name="decrypt_invalid_text">"Either the signature is invalid or the key has been revoked. You cannot be sure who wrote the text. Do you still want to display it?"</string> <string name="decrypt_invalid_button">"I understand the risks, display it!"</string> <!-- Add keys --> |