refactor ViewKeyActivity to remove field m* prefix

This commit is contained in:
Vincent Breitmoser
2018-02-12 17:31:14 +01:00
parent b3a5b7e04a
commit 84d652be8b
8 changed files with 327 additions and 387 deletions

View File

@@ -48,7 +48,7 @@ public class CertifyFingerprintActivity extends BaseActivity {
} }
}); });
Timber.i("mDataUri: " + mDataUri.toString()); Timber.i("dataUri: " + mDataUri.toString());
startFragment(savedInstanceState, mDataUri); startFragment(savedInstanceState, mDataUri);
} }

View File

@@ -113,7 +113,7 @@ public class CertifyFingerprintFragment extends LoaderFragment implements
private void loadData(Uri dataUri) { private void loadData(Uri dataUri) {
mDataUri = dataUri; mDataUri = dataUri;
Timber.i("mDataUri: " + mDataUri.toString()); Timber.i("dataUri: " + mDataUri.toString());
// Prepare the loaders. Either re-connect with an existing ones, // Prepare the loaders. Either re-connect with an existing ones,
// or start new ones. // or start new ones.

View File

@@ -165,7 +165,7 @@ public class EditIdentitiesFragment extends Fragment
private void loadData(Uri dataUri) { private void loadData(Uri dataUri) {
mDataUri = dataUri; mDataUri = dataUri;
Timber.i("mDataUri: " + mDataUri); Timber.i("dataUri: " + mDataUri);
// load the secret key ring. we do verify here that the passphrase is correct, so cached won't do // load the secret key ring. we do verify here that the passphrase is correct, so cached won't do
try { try {

View File

@@ -195,7 +195,7 @@ public class EditKeyFragment extends QueueingCryptoOperationFragment<SaveKeyring
private void loadData(Uri dataUri) { private void loadData(Uri dataUri) {
mDataUri = dataUri; mDataUri = dataUri;
Timber.i("mDataUri: " + mDataUri); Timber.i("dataUri: " + mDataUri);
// load the secret key ring. we do verify here that the passphrase is correct, so cached won't do // load the secret key ring. we do verify here that the passphrase is correct, so cached won't do
try { try {

View File

@@ -240,7 +240,7 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements
private void loadData(Uri dataUri) { private void loadData(Uri dataUri) {
mDataUri = dataUri; mDataUri = dataUri;
Timber.i("mDataUri: " + mDataUri); Timber.i("dataUri: " + mDataUri);
mUserIdsAdapter = new UserIdsAdapter(getActivity(), null, 0); mUserIdsAdapter = new UserIdsAdapter(getActivity(), null, 0);
mUserIds.setAdapter(mUserIdsAdapter); mUserIds.setAdapter(mUserIdsAdapter);

View File

@@ -31,6 +31,7 @@ import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Parcelable; import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentManager;
@@ -41,7 +42,6 @@ import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader; import android.support.v4.content.Loader;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextSwitcher; import android.widget.TextSwitcher;
@@ -86,19 +86,18 @@ public class LinkedIdViewFragment extends CryptoOperationFragment implements
private static final String ARG_MASTER_KEY_ID = "master_key_id"; private static final String ARG_MASTER_KEY_ID = "master_key_id";
private static final int LOADER_ID_LINKED_ID = 1; private static final int LOADER_ID_LINKED_ID = 1;
private UriAttribute mLinkedId; private long masterKeyId;
private LinkedTokenResource mLinkedResource; private boolean isSecret;
private boolean mIsSecret;
private Context mContext; private UriAttribute linkedId;
private long mMasterKeyId; private LinkedTokenResource linkedResource;
private AsyncTask mInProgress; private AsyncTask taskInProgress;
private Uri mDataUri; private Uri dataUri;
private ViewHolder mViewHolder; private ViewHolder viewHolder;
private int mLidRank; private int lidRank;
private long mCertifyKeyId; private long certifyKeyId;
public static LinkedIdViewFragment newInstance(Uri dataUri, int rank, public static LinkedIdViewFragment newInstance(Uri dataUri, int rank,
boolean isSecret, long masterKeyId) throws IOException { boolean isSecret, long masterKeyId) throws IOException {
@@ -125,13 +124,11 @@ public class LinkedIdViewFragment extends CryptoOperationFragment implements
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Bundle args = getArguments(); Bundle args = getArguments();
mDataUri = args.getParcelable(ARG_DATA_URI); dataUri = args.getParcelable(ARG_DATA_URI);
mLidRank = args.getInt(ARG_LID_RANK); lidRank = args.getInt(ARG_LID_RANK);
mIsSecret = args.getBoolean(ARG_IS_SECRET); isSecret = args.getBoolean(ARG_IS_SECRET);
mMasterKeyId = args.getLong(ARG_MASTER_KEY_ID); masterKeyId = args.getLong(ARG_MASTER_KEY_ID);
mContext = getActivity();
getLoaderManager().initLoader(LOADER_ID_LINKED_ID, null, this); getLoaderManager().initLoader(LOADER_ID_LINKED_ID, null, this);
@@ -141,10 +138,10 @@ public class LinkedIdViewFragment extends CryptoOperationFragment implements
public Loader<Cursor> onCreateLoader(int id, Bundle args) { public Loader<Cursor> onCreateLoader(int id, Bundle args) {
switch (id) { switch (id) {
case LOADER_ID_LINKED_ID: case LOADER_ID_LINKED_ID:
return new CursorLoader(getActivity(), mDataUri, return new CursorLoader(getContext(), dataUri,
UserIdsAdapter.USER_PACKETS_PROJECTION, UserIdsAdapter.USER_PACKETS_PROJECTION,
Tables.USER_PACKETS + "." + UserPackets.RANK Tables.USER_PACKETS + "." + UserPackets.RANK
+ " = " + Integer.toString(mLidRank), null, null); + " = " + Integer.toString(lidRank), null, null);
default: default:
return null; return null;
} }
@@ -181,68 +178,62 @@ public class LinkedIdViewFragment extends CryptoOperationFragment implements
} }
public void finishFragment() { public void finishFragment() {
new Handler().post(new Runnable() { new Handler().post(() -> {
@Override FragmentManager manager = getFragmentManager();
public void run() { manager.removeOnBackStackChangedListener(LinkedIdViewFragment.this);
FragmentManager manager = getFragmentManager(); manager.popBackStack("linked_id", FragmentManager.POP_BACK_STACK_INCLUSIVE);
manager.removeOnBackStackChangedListener(LinkedIdViewFragment.this);
manager.popBackStack("linked_id", FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
}); });
} }
private void loadIdentity(UriAttribute linkedId, int certStatus) { private void loadIdentity(UriAttribute linkedId, int certStatus) {
mLinkedId = linkedId; this.linkedId = linkedId;
if (mLinkedId instanceof LinkedAttribute) { if (this.linkedId instanceof LinkedAttribute) {
LinkedResource res = ((LinkedAttribute) mLinkedId).mResource; LinkedResource res = ((LinkedAttribute) this.linkedId).mResource;
mLinkedResource = (LinkedTokenResource) res; linkedResource = (LinkedTokenResource) res;
} }
if (!mIsSecret) { if (!isSecret) {
switch (certStatus) { switch (certStatus) {
case Certs.VERIFIED_SECRET: case Certs.VERIFIED_SECRET:
KeyFormattingUtils.setStatusImage(mContext, mViewHolder.mLinkedIdHolder.vVerified, KeyFormattingUtils.setStatusImage(getContext(), viewHolder.mLinkedIdHolder.vVerified,
null, State.VERIFIED, KeyFormattingUtils.DEFAULT_COLOR); null, State.VERIFIED, KeyFormattingUtils.DEFAULT_COLOR);
break; break;
case Certs.VERIFIED_SELF: case Certs.VERIFIED_SELF:
KeyFormattingUtils.setStatusImage(mContext, mViewHolder.mLinkedIdHolder.vVerified, KeyFormattingUtils.setStatusImage(getContext(), viewHolder.mLinkedIdHolder.vVerified,
null, State.UNVERIFIED, KeyFormattingUtils.DEFAULT_COLOR); null, State.UNVERIFIED, KeyFormattingUtils.DEFAULT_COLOR);
break; break;
default: default:
KeyFormattingUtils.setStatusImage(mContext, mViewHolder.mLinkedIdHolder.vVerified, KeyFormattingUtils.setStatusImage(getContext(), viewHolder.mLinkedIdHolder.vVerified,
null, State.INVALID, KeyFormattingUtils.DEFAULT_COLOR); null, State.INVALID, KeyFormattingUtils.DEFAULT_COLOR);
break; break;
} }
} else { } else {
mViewHolder.mLinkedIdHolder.vVerified.setImageResource(R.drawable.octo_link_24dp); viewHolder.mLinkedIdHolder.vVerified.setImageResource(R.drawable.octo_link_24dp);
} }
mViewHolder.mLinkedIdHolder.bind(mContext, mLinkedId); viewHolder.mLinkedIdHolder.bind(getContext(), this.linkedId);
setShowVerifying(false); setShowVerifying(false);
// no resource, nothing further we can do… // no resource, nothing further we can do…
if (mLinkedResource == null) { if (linkedResource == null) {
mViewHolder.vButtonView.setVisibility(View.GONE); viewHolder.vButtonView.setVisibility(View.GONE);
mViewHolder.vButtonVerify.setVisibility(View.GONE); viewHolder.vButtonVerify.setVisibility(View.GONE);
return; return;
} }
if (mLinkedResource.isViewable()) { if (linkedResource.isViewable()) {
mViewHolder.vButtonView.setVisibility(View.VISIBLE); viewHolder.vButtonView.setVisibility(View.VISIBLE);
mViewHolder.vButtonView.setOnClickListener(new OnClickListener() { viewHolder.vButtonView.setOnClickListener(v -> {
@Override Intent intent = linkedResource.getViewIntent();
public void onClick(View v) { if (intent == null) {
Intent intent = mLinkedResource.getViewIntent(); return;
if (intent == null) {
return;
}
getActivity().startActivity(intent);
} }
startActivity(intent);
}); });
} else { } else {
mViewHolder.vButtonView.setVisibility(View.GONE); viewHolder.vButtonView.setVisibility(View.GONE);
} }
} }
@@ -362,27 +353,22 @@ public class LinkedIdViewFragment extends CryptoOperationFragment implements
*/ */
void setShowVerifying(boolean show) { void setShowVerifying(boolean show) {
if (!show) { if (!show) {
if (mInProgress != null) { if (taskInProgress != null) {
mInProgress.cancel(false); taskInProgress.cancel(false);
mInProgress = null; taskInProgress = null;
} }
getFragmentManager().removeOnBackStackChangedListener(this); getFragmentManager().removeOnBackStackChangedListener(this);
new Handler().post(new Runnable() { new Handler().post(() -> getFragmentManager().popBackStack("verification",
@Override FragmentManager.POP_BACK_STACK_INCLUSIVE));
public void run() {
getFragmentManager().popBackStack("verification",
FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
});
if (!mVerificationState) { if (!mVerificationState) {
return; return;
} }
mVerificationState = false; mVerificationState = false;
mViewHolder.showButton(0); viewHolder.showButton(0);
mViewHolder.vKeySpinnerContainer.setVisibility(View.GONE); viewHolder.vKeySpinnerContainer.setVisibility(View.GONE);
mViewHolder.showVerifyingContainer(mContext, false, mIsSecret); viewHolder.showVerifyingContainer(getContext(), false, isSecret);
return; return;
} }
@@ -395,7 +381,7 @@ public class LinkedIdViewFragment extends CryptoOperationFragment implements
manager.beginTransaction().addToBackStack("verification").commit(); manager.beginTransaction().addToBackStack("verification").commit();
manager.executePendingTransactions(); manager.executePendingTransactions();
manager.addOnBackStackChangedListener(this); manager.addOnBackStackChangedListener(this);
mViewHolder.showVerifyingContainer(mContext, true, mIsSecret); viewHolder.showVerifyingContainer(getContext(), true, isSecret);
} }
@@ -405,44 +391,29 @@ public class LinkedIdViewFragment extends CryptoOperationFragment implements
} }
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup superContainer, Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup superContainer, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.linked_id_view_fragment, null); View root = inflater.inflate(R.layout.linked_id_view_fragment, null);
mViewHolder = new ViewHolder(root); viewHolder = new ViewHolder(root);
root.setTag(mViewHolder); root.setTag(viewHolder);
((ImageView) root.findViewById(R.id.status_icon_verified)) ((ImageView) root.findViewById(R.id.status_icon_verified))
.setColorFilter(ContextCompat.getColor(mContext, R.color.android_green_light), .setColorFilter(ContextCompat.getColor(getContext(), R.color.android_green_light),
PorterDuff.Mode.SRC_IN); PorterDuff.Mode.SRC_IN);
((ImageView) root.findViewById(R.id.status_icon_invalid)) ((ImageView) root.findViewById(R.id.status_icon_invalid))
.setColorFilter(ContextCompat.getColor(mContext, R.color.android_red_light), .setColorFilter(ContextCompat.getColor(getContext(), R.color.android_red_light),
PorterDuff.Mode.SRC_IN); PorterDuff.Mode.SRC_IN);
mViewHolder.vButtonVerify.setOnClickListener(new OnClickListener() { viewHolder.vButtonVerify.setOnClickListener(v -> verifyResource());
@Override viewHolder.vButtonRetry.setOnClickListener(v -> verifyResource());
public void onClick(View v) { viewHolder.vButtonConfirm.setOnClickListener(v -> initiateCertifying());
verifyResource();
}
});
mViewHolder.vButtonRetry.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
verifyResource();
}
});
mViewHolder.vButtonConfirm.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
initiateCertifying();
}
});
{ {
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putParcelable(CertListWidget.ARG_URI, Certs.buildLinkedIdCertsUri(mDataUri, mLidRank)); args.putParcelable(CertListWidget.ARG_URI, Certs.buildLinkedIdCertsUri(dataUri, lidRank));
args.putBoolean(CertListWidget.ARG_IS_SECRET, mIsSecret); args.putBoolean(CertListWidget.ARG_IS_SECRET, isSecret);
getLoaderManager().initLoader(CertListWidget.LOADER_ID_LINKED_CERTS, getLoaderManager().initLoader(CertListWidget.LOADER_ID_LINKED_CERTS,
args, mViewHolder.vLinkedCerts); args, viewHolder.vLinkedCerts);
} }
return root; return root;
@@ -450,17 +421,17 @@ public class LinkedIdViewFragment extends CryptoOperationFragment implements
void verifyResource() { void verifyResource() {
// only one at a time (no sync needed, mInProgress is only touched in ui thread) // only one at a time (no sync needed, taskInProgress is only touched in ui thread)
if (mInProgress != null) { if (taskInProgress != null) {
return; return;
} }
setShowVerifying(true); setShowVerifying(true);
mViewHolder.vKeySpinnerContainer.setVisibility(View.GONE); viewHolder.vKeySpinnerContainer.setVisibility(View.GONE);
mViewHolder.setVerifyingState(mContext, VerifyState.VERIFYING, mIsSecret); viewHolder.setVerifyingState(getContext(), VerifyState.VERIFYING, isSecret);
mInProgress = new AsyncTask<Void,Void,LinkedVerifyResult>() { taskInProgress = new AsyncTask<Void,Void,LinkedVerifyResult>() {
@Override @Override
protected LinkedVerifyResult doInBackground(Void... params) { protected LinkedVerifyResult doInBackground(Void... params) {
FragmentActivity activity = getActivity(); FragmentActivity activity = getActivity();
@@ -468,13 +439,13 @@ public class LinkedIdViewFragment extends CryptoOperationFragment implements
byte[] fingerprint; byte[] fingerprint;
try { try {
fingerprint = KeyRepository.create(activity).getCachedPublicKeyRing( fingerprint = KeyRepository.create(activity).getCachedPublicKeyRing(
mMasterKeyId).getFingerprint(); masterKeyId).getFingerprint();
} catch (PgpKeyNotFoundException e) { } catch (PgpKeyNotFoundException e) {
throw new IllegalStateException("Key to verify linked id for must exist in db!"); throw new IllegalStateException("Key to verify linked id for must exist in db!");
} }
long timer = System.currentTimeMillis(); long timer = System.currentTimeMillis();
LinkedVerifyResult result = mLinkedResource.verify(activity, fingerprint); LinkedVerifyResult result = linkedResource.verify(activity, fingerprint);
// ux flow: this operation should take at last a second // ux flow: this operation should take at last a second
timer = System.currentTimeMillis() -timer; timer = System.currentTimeMillis() -timer;
@@ -493,17 +464,17 @@ public class LinkedIdViewFragment extends CryptoOperationFragment implements
return; return;
} }
if (result.success()) { if (result.success()) {
mViewHolder.vText.setText(getString(mLinkedResource.getVerifiedText(mIsSecret))); viewHolder.vText.setText(getString(linkedResource.getVerifiedText(isSecret)));
// hack to preserve bold text // hack to preserve bold text
((TextView) mViewHolder.vText.getCurrentView()).setText( ((TextView) viewHolder.vText.getCurrentView()).setText(
mLinkedResource.getVerifiedText(mIsSecret)); linkedResource.getVerifiedText(isSecret));
mViewHolder.setVerifyingState(mContext, VerifyState.VERIFY_OK, mIsSecret); viewHolder.setVerifyingState(getContext(), VerifyState.VERIFY_OK, isSecret);
mViewHolder.mLinkedIdHolder.seekAttention(); viewHolder.mLinkedIdHolder.seekAttention();
} else { } else {
mViewHolder.setVerifyingState(mContext, VerifyState.VERIFY_ERROR, mIsSecret); viewHolder.setVerifyingState(getContext(), VerifyState.VERIFY_ERROR, isSecret);
result.createNotify(getActivity()).show(); result.createNotify(getActivity()).show();
} }
mInProgress = null; taskInProgress = null;
} }
}.execute(); }.execute();
@@ -511,22 +482,22 @@ public class LinkedIdViewFragment extends CryptoOperationFragment implements
private void initiateCertifying() { private void initiateCertifying() {
if (mIsSecret) { if (isSecret) {
return; return;
} }
// get the user's passphrase for this key (if required) // get the user's passphrase for this key (if required)
mCertifyKeyId = mViewHolder.vKeySpinner.getSelectedKeyId(); certifyKeyId = viewHolder.vKeySpinner.getSelectedKeyId();
if (mCertifyKeyId == key.none || mCertifyKeyId == key.symmetric) { if (certifyKeyId == key.none || certifyKeyId == key.symmetric) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
SubtleAttentionSeeker.tintBackground(mViewHolder.vKeySpinnerContainer, 600).start(); SubtleAttentionSeeker.tintBackground(viewHolder.vKeySpinnerContainer, 600).start();
} else { } else {
Notify.create(getActivity(), R.string.select_key_to_certify, Style.ERROR).show(); Notify.create(getActivity(), R.string.select_key_to_certify, Style.ERROR).show();
} }
return; return;
} }
mViewHolder.setVerifyingState(mContext, VerifyState.CERTIFYING, false); viewHolder.setVerifyingState(getContext(), VerifyState.CERTIFYING, false);
cryptoOperation(); cryptoOperation();
} }
@@ -543,11 +514,11 @@ public class LinkedIdViewFragment extends CryptoOperationFragment implements
@Nullable @Nullable
@Override @Override
public Parcelable createOperationInput() { public Parcelable createOperationInput() {
CertifyAction action = CertifyAction.createForUserAttributes(mMasterKeyId, CertifyAction action = CertifyAction.createForUserAttributes(masterKeyId,
Collections.singletonList(mLinkedId.toUserAttribute())); Collections.singletonList(linkedId.toUserAttribute()));
// fill values for this action // fill values for this action
CertifyActionsParcel.Builder builder = CertifyActionsParcel.builder(mCertifyKeyId); CertifyActionsParcel.Builder builder = CertifyActionsParcel.builder(certifyKeyId);
builder.addActions(Collections.singletonList(action)); builder.addActions(Collections.singletonList(action));
return builder.build(); return builder.build();

View File

@@ -20,8 +20,8 @@ package org.sufficientlysecure.keychain.ui.keyview;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import android.animation.ArgbEvaluator; import android.animation.ArgbEvaluator;
import android.animation.ObjectAnimator; import android.animation.ObjectAnimator;
@@ -106,7 +106,6 @@ import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.ui.util.Notify.Style; import org.sufficientlysecure.keychain.ui.util.Notify.Style;
import org.sufficientlysecure.keychain.ui.util.QrCodeUtils; import org.sufficientlysecure.keychain.ui.util.QrCodeUtils;
import org.sufficientlysecure.keychain.util.ContactHelper; import org.sufficientlysecure.keychain.util.ContactHelper;
import org.sufficientlysecure.keychain.util.Passphrase;
import org.sufficientlysecure.keychain.util.Preferences; import org.sufficientlysecure.keychain.util.Preferences;
import timber.log.Timber; import timber.log.Timber;
@@ -127,82 +126,80 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
public static final String EXTRA_DISPLAY_RESULT = "display_result"; public static final String EXTRA_DISPLAY_RESULT = "display_result";
public static final String EXTRA_LINKED_TRANSITION = "linked_transition"; public static final String EXTRA_LINKED_TRANSITION = "linked_transition";
KeyRepository mKeyRepository; KeyRepository keyRepository;
protected Uri mDataUri; protected Uri dataUri;
// For CryptoOperationHelper.Callback // For CryptoOperationHelper.Callback
private HkpKeyserverAddress mKeyserver; private CryptoOperationHelper<ImportKeyringParcel, ImportKeyResult> importOpHelper;
private ArrayList<ParcelableKeyRing> mKeyList; private CryptoOperationHelper<ChangeUnlockParcel, EditKeyResult> editOpHelper;
private CryptoOperationHelper<ImportKeyringParcel, ImportKeyResult> mImportOpHelper; private ChangeUnlockParcel changeUnlockParcel;
private CryptoOperationHelper<ChangeUnlockParcel, EditKeyResult> mEditOpHelper;
private ChangeUnlockParcel mChangeUnlockParcel;
private TextView mStatusText; private TextView statusText;
private ImageView mStatusImage; private ImageView statusImage;
private AppBarLayout mAppBarLayout; private AppBarLayout appBarLayout;
private CollapsingToolbarLayout mCollapsingToolbarLayout; private CollapsingToolbarLayout collapsingToolbarLayout;
private ImageButton mActionEncryptFile; private ImageButton actionEncryptFile;
private ImageButton mActionEncryptText; private ImageButton actionEncryptText;
private FloatingActionButton mFab; private FloatingActionButton floatingActionButton;
private ImageView mPhoto; private ImageView photoView;
private FrameLayout mPhotoLayout; private FrameLayout photoLayout;
private ImageView mQrCode; private ImageView qrCodeView;
private CardView mQrCodeLayout; private CardView qrCodeLayout;
private byte[] mQrCodeLoaded; private byte[] qrCodeLoaded;
private static final int LOADER_ID_UNIFIED = 0; private static final int LOADER_ID_UNIFIED = 0;
private boolean mIsSecret = false; private boolean isSecret = false;
private boolean mHasEncrypt = false; private boolean hasEncrypt = false;
private boolean mIsVerified = false; private boolean isVerified = false;
private boolean mIsRevoked = false; private boolean isRevoked = false;
private boolean mIsSecure = true; private boolean isSecure = true;
private boolean mIsExpired = false; private boolean isExpired = false;
private MenuItem mRefreshItem; private MenuItem refreshItem;
private boolean mIsRefreshing; private boolean isRefreshing;
private Animation mRotate, mRotateSpin; private Animation rotate, rotateSpin;
private View mRefresh; private View refreshView;
private long mMasterKeyId; private long masterKeyId;
private byte[] mFingerprint; private byte[] fingerprint;
@SuppressLint("InflateParams") @SuppressLint("InflateParams")
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
mKeyRepository = KeyRepository.create(this); keyRepository = KeyRepository.create(this);
mImportOpHelper = new CryptoOperationHelper<>(1, this, this, null); importOpHelper = new CryptoOperationHelper<>(1, this, this, null);
setTitle(null); setTitle(null);
mStatusText = findViewById(R.id.view_key_status); statusText = findViewById(R.id.view_key_status);
mStatusImage = findViewById(R.id.view_key_status_image); statusImage = findViewById(R.id.view_key_status_image);
mAppBarLayout = findViewById(R.id.app_bar_layout); appBarLayout = findViewById(R.id.app_bar_layout);
mCollapsingToolbarLayout = findViewById(R.id.collapsing_toolbar); collapsingToolbarLayout = findViewById(R.id.collapsing_toolbar);
mActionEncryptFile = findViewById(R.id.view_key_action_encrypt_files); actionEncryptFile = findViewById(R.id.view_key_action_encrypt_files);
mActionEncryptText = findViewById(R.id.view_key_action_encrypt_text); actionEncryptText = findViewById(R.id.view_key_action_encrypt_text);
mFab = findViewById(R.id.fab); floatingActionButton = findViewById(R.id.fab);
mPhoto = findViewById(R.id.view_key_photo); photoView = findViewById(R.id.view_key_photo);
mPhotoLayout = findViewById(R.id.view_key_photo_layout); photoLayout = findViewById(R.id.view_key_photo_layout);
mQrCode = findViewById(R.id.view_key_qr_code); qrCodeView = findViewById(R.id.view_key_qr_code);
mQrCodeLayout = findViewById(R.id.view_key_qr_code_layout); qrCodeLayout = findViewById(R.id.view_key_qr_code_layout);
mRotateSpin = AnimationUtils.loadAnimation(this, R.anim.rotate_spin); rotateSpin = AnimationUtils.loadAnimation(this, R.anim.rotate_spin);
//ContentDescriptionHint Listeners implemented //ContentDescriptionHint Listeners implemented
ContentDescriptionHint.setup(mActionEncryptFile); ContentDescriptionHint.setup(actionEncryptFile);
ContentDescriptionHint.setup(mActionEncryptText); ContentDescriptionHint.setup(actionEncryptText);
ContentDescriptionHint.setup(mFab); ContentDescriptionHint.setup(floatingActionButton);
mRotateSpin.setAnimationListener(new AnimationListener() { rotateSpin.setAnimationListener(new AnimationListener() {
@Override @Override
public void onAnimationStart(Animation animation) { public void onAnimationStart(Animation animation) {
@@ -210,9 +207,9 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
@Override @Override
public void onAnimationEnd(Animation animation) { public void onAnimationEnd(Animation animation) {
mRefreshItem.getActionView().clearAnimation(); refreshItem.getActionView().clearAnimation();
mRefreshItem.setActionView(null); refreshItem.setActionView(null);
mRefreshItem.setEnabled(true); refreshItem.setEnabled(true);
// this is a deferred call // this is a deferred call
supportInvalidateOptionsMenu(); supportInvalidateOptionsMenu();
@@ -223,9 +220,9 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
} }
}); });
mRotate = AnimationUtils.loadAnimation(this, R.anim.rotate); rotate = AnimationUtils.loadAnimation(this, R.anim.rotate);
mRotate.setRepeatCount(Animation.INFINITE); rotate.setRepeatCount(Animation.INFINITE);
mRotate.setAnimationListener(new Animation.AnimationListener() { rotate.setAnimationListener(new Animation.AnimationListener() {
@Override @Override
public void onAnimationStart(Animation animation) { public void onAnimationStart(Animation animation) {
@@ -238,23 +235,23 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
@Override @Override
public void onAnimationRepeat(Animation animation) { public void onAnimationRepeat(Animation animation) {
if (!mIsRefreshing) { if (!isRefreshing) {
mRefreshItem.getActionView().clearAnimation(); refreshItem.getActionView().clearAnimation();
mRefreshItem.getActionView().startAnimation(mRotateSpin); refreshItem.getActionView().startAnimation(rotateSpin);
} }
} }
}); });
mRefresh = getLayoutInflater().inflate(R.layout.indeterminate_progress, null); refreshView = getLayoutInflater().inflate(R.layout.indeterminate_progress, null);
mDataUri = getIntent().getData(); dataUri = getIntent().getData();
if (mDataUri == null) { if (dataUri == null) {
Timber.e("Data missing. Should be uri of key!"); Timber.e("Data missing. Should be uri of key!");
finish(); finish();
return; return;
} }
if (mDataUri.getHost().equals(ContactsContract.AUTHORITY)) { if (dataUri.getHost().equals(ContactsContract.AUTHORITY)) {
mDataUri = new ContactHelper(this).dataUriFromContactUri(mDataUri); dataUri = new ContactHelper(this).dataUriFromContactUri(dataUri);
if (mDataUri == null) { if (dataUri == null) {
Timber.e("Contact Data missing. Should be uri of key!"); Timber.e("Contact Data missing. Should be uri of key!");
Toast.makeText(this, R.string.error_contacts_key_id_missing, Toast.LENGTH_LONG).show(); Toast.makeText(this, R.string.error_contacts_key_id_missing, Toast.LENGTH_LONG).show();
finish(); finish();
@@ -262,38 +259,20 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
} }
} }
Timber.i("mDataUri: " + mDataUri); Timber.i("dataUri: " + dataUri);
mActionEncryptFile.setOnClickListener(new View.OnClickListener() { actionEncryptFile.setOnClickListener(v -> encrypt(dataUri, false));
@Override actionEncryptText.setOnClickListener(v -> encrypt(dataUri, true));
public void onClick(View v) {
encrypt(mDataUri, false); floatingActionButton.setOnClickListener(v -> {
} if (isSecret) {
}); startSafeSlinger(dataUri);
mActionEncryptText.setOnClickListener(new View.OnClickListener() { } else {
@Override scanQrCode();
public void onClick(View v) {
encrypt(mDataUri, true);
} }
}); });
mFab.setOnClickListener(new View.OnClickListener() { qrCodeLayout.setOnClickListener(v -> showQrCodeDialog());
@Override
public void onClick(View v) {
if (mIsSecret) {
startSafeSlinger(mDataUri);
} else {
scanQrCode();
}
}
});
mQrCodeLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showQrCodeDialog();
}
});
// Prepare the loaders. Either re-connect with an existing ones, // Prepare the loaders. Either re-connect with an existing ones,
// or start new ones. // or start new ones.
@@ -311,7 +290,7 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
if (Preferences.getPreferences(this).getExperimentalEnableKeybase()) { if (Preferences.getPreferences(this).getExperimentalEnableKeybase()) {
FragmentManager manager = getSupportFragmentManager(); FragmentManager manager = getSupportFragmentManager();
final ViewKeyKeybaseFragment keybaseFrag = ViewKeyKeybaseFragment.newInstance(mDataUri); final ViewKeyKeybaseFragment keybaseFrag = ViewKeyKeybaseFragment.newInstance(dataUri);
manager.beginTransaction() manager.beginTransaction()
.replace(R.id.view_key_keybase_fragment, keybaseFrag) .replace(R.id.view_key_keybase_fragment, keybaseFrag)
.commit(); .commit();
@@ -327,7 +306,7 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu); super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.key_view, menu); getMenuInflater().inflate(R.menu.key_view, menu);
mRefreshItem = menu.findItem(R.id.menu_key_view_refresh); refreshItem = menu.findItem(R.id.menu_key_view_refresh);
return true; return true;
} }
@@ -361,20 +340,16 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
} }
case R.id.menu_key_view_advanced: { case R.id.menu_key_view_advanced: {
Intent advancedIntent = new Intent(this, ViewKeyAdvActivity.class); Intent advancedIntent = new Intent(this, ViewKeyAdvActivity.class);
advancedIntent.setData(mDataUri); advancedIntent.setData(dataUri);
startActivity(advancedIntent); startActivity(advancedIntent);
return true; return true;
} }
case R.id.menu_key_view_refresh: { case R.id.menu_key_view_refresh: {
try { updateFromKeyserver();
updateFromKeyserver(mDataUri, mKeyRepository);
} catch (PgpKeyNotFoundException e) {
Notify.create(this, R.string.error_key_not_found, Notify.Style.ERROR).show();
}
return true; return true;
} }
case R.id.menu_key_view_certify_fingerprint: { case R.id.menu_key_view_certify_fingerprint: {
certifyFingerprint(mDataUri); certifyFingerprint(dataUri);
return true; return true;
} }
} }
@@ -384,13 +359,13 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
@Override @Override
public boolean onPrepareOptionsMenu(Menu menu) { public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem backupKey = menu.findItem(R.id.menu_key_view_backup); MenuItem backupKey = menu.findItem(R.id.menu_key_view_backup);
backupKey.setVisible(mIsSecret); backupKey.setVisible(isSecret);
menu.findItem(R.id.menu_key_view_skt).setVisible(mIsSecret); menu.findItem(R.id.menu_key_view_skt).setVisible(isSecret);
MenuItem changePassword = menu.findItem(R.id.menu_key_change_password); MenuItem changePassword = menu.findItem(R.id.menu_key_change_password);
changePassword.setVisible(mIsSecret); changePassword.setVisible(isSecret);
MenuItem certifyFingerprint = menu.findItem(R.id.menu_key_view_certify_fingerprint); MenuItem certifyFingerprint = menu.findItem(R.id.menu_key_view_certify_fingerprint);
certifyFingerprint.setVisible(!mIsSecret && !mIsVerified && !mIsExpired && !mIsRevoked); certifyFingerprint.setVisible(!isSecret && !isVerified && !isExpired && !isRevoked);
return true; return true;
} }
@@ -400,7 +375,7 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
= new CryptoOperationHelper.Callback<ChangeUnlockParcel, EditKeyResult>() { = new CryptoOperationHelper.Callback<ChangeUnlockParcel, EditKeyResult>() {
@Override @Override
public ChangeUnlockParcel createOperationInput() { public ChangeUnlockParcel createOperationInput() {
return mChangeUnlockParcel; return changeUnlockParcel;
} }
@Override @Override
@@ -424,7 +399,7 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
} }
}; };
mEditOpHelper = new CryptoOperationHelper<>(2, this, editKeyCallback, R.string.progress_building_key); editOpHelper = new CryptoOperationHelper<>(2, this, editKeyCallback, R.string.progress_building_key);
// Message is received after passphrase is cached // Message is received after passphrase is cached
Handler returnHandler = new Handler() { Handler returnHandler = new Handler() {
@@ -434,12 +409,12 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
Bundle data = message.getData(); Bundle data = message.getData();
// use new passphrase! // use new passphrase!
mChangeUnlockParcel = ChangeUnlockParcel.createChangeUnlockParcel( changeUnlockParcel = ChangeUnlockParcel.createChangeUnlockParcel(
mMasterKeyId, mFingerprint, masterKeyId, fingerprint,
data.getParcelable(SetPassphraseDialogFragment.MESSAGE_NEW_PASSPHRASE) data.getParcelable(SetPassphraseDialogFragment.MESSAGE_NEW_PASSPHRASE)
); );
mEditOpHelper.cryptoOperation(); editOpHelper.cryptoOperation();
} }
} }
}; };
@@ -472,7 +447,7 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
private void certifyImmediate() { private void certifyImmediate() {
Intent intent = new Intent(this, CertifyKeyActivity.class); Intent intent = new Intent(this, CertifyKeyActivity.class);
intent.putExtra(CertifyKeyActivity.EXTRA_KEY_IDS, new long[] { mMasterKeyId }); intent.putExtra(CertifyKeyActivity.EXTRA_KEY_IDS, new long[] { masterKeyId });
startActivityForResult(intent, REQUEST_CERTIFY); startActivityForResult(intent, REQUEST_CERTIFY);
} }
@@ -485,11 +460,11 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
Bundle opts = null; Bundle opts = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
ActivityOptions options = ActivityOptions ActivityOptions options = ActivityOptions
.makeSceneTransitionAnimation(this, mQrCodeLayout, "qr_code"); .makeSceneTransitionAnimation(this, qrCodeLayout, "qr_code");
opts = options.toBundle(); opts = options.toBundle();
} }
qrCodeIntent.setData(mDataUri); qrCodeIntent.setData(dataUri);
ActivityCompat.startActivity(this, qrCodeIntent, opts); ActivityCompat.startActivity(this, qrCodeIntent, opts);
} }
@@ -498,7 +473,7 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
if (keyHasPassphrase()) { if (keyHasPassphrase()) {
Intent intent = new Intent(this, PassphraseDialogActivity.class); Intent intent = new Intent(this, PassphraseDialogActivity.class);
RequiredInputParcel requiredInput = RequiredInputParcel requiredInput =
RequiredInputParcel.createRequiredDecryptPassphrase(mMasterKeyId, mMasterKeyId); RequiredInputParcel.createRequiredDecryptPassphrase(masterKeyId, masterKeyId);
requiredInput.mSkipCaching = true; requiredInput.mSkipCaching = true;
intent.putExtra(PassphraseDialogActivity.EXTRA_REQUIRED_INPUT, requiredInput); intent.putExtra(PassphraseDialogActivity.EXTRA_REQUIRED_INPUT, requiredInput);
startActivityForResult(intent, requestCode); startActivityForResult(intent, requestCode);
@@ -510,7 +485,7 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
private boolean keyHasPassphrase() { private boolean keyHasPassphrase() {
try { try {
SecretKeyType secretKeyType = SecretKeyType secretKeyType =
mKeyRepository.getCachedPublicKeyRing(mMasterKeyId).getSecretKeyType(mMasterKeyId); keyRepository.getCachedPublicKeyRing(masterKeyId).getSecretKeyType(masterKeyId);
switch (secretKeyType) { switch (secretKeyType) {
// all of these make no sense to ask // all of these make no sense to ask
case PASSPHRASE_EMPTY: case PASSPHRASE_EMPTY:
@@ -528,7 +503,7 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
private void startBackupActivity() { private void startBackupActivity() {
Intent intent = new Intent(this, BackupActivity.class); Intent intent = new Intent(this, BackupActivity.class);
intent.putExtra(BackupActivity.EXTRA_MASTER_KEY_IDS, new long[]{mMasterKeyId}); intent.putExtra(BackupActivity.EXTRA_MASTER_KEY_IDS, new long[]{ masterKeyId });
intent.putExtra(BackupActivity.EXTRA_SECRET, true); intent.putExtra(BackupActivity.EXTRA_SECRET, true);
startActivity(intent); startActivity(intent);
} }
@@ -537,9 +512,9 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
Intent deleteIntent = new Intent(this, DeleteKeyDialogActivity.class); Intent deleteIntent = new Intent(this, DeleteKeyDialogActivity.class);
deleteIntent.putExtra(DeleteKeyDialogActivity.EXTRA_DELETE_MASTER_KEY_IDS, deleteIntent.putExtra(DeleteKeyDialogActivity.EXTRA_DELETE_MASTER_KEY_IDS,
new long[]{mMasterKeyId}); new long[]{ masterKeyId });
deleteIntent.putExtra(DeleteKeyDialogActivity.EXTRA_HAS_SECRET, mIsSecret); deleteIntent.putExtra(DeleteKeyDialogActivity.EXTRA_HAS_SECRET, isSecret);
if (mIsSecret) { if (isSecret) {
// for upload in case key is secret // for upload in case key is secret
deleteIntent.putExtra(DeleteKeyDialogActivity.EXTRA_KEYSERVER, deleteIntent.putExtra(DeleteKeyDialogActivity.EXTRA_KEYSERVER,
Preferences.getPreferences(this).getPreferredKeyserver()); Preferences.getPreferences(this).getPreferredKeyserver());
@@ -550,11 +525,11 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
@Override @Override
protected void onActivityResult(@RequestType int requestCode, int resultCode, Intent data) { protected void onActivityResult(@RequestType int requestCode, int resultCode, Intent data) {
if (mImportOpHelper.handleActivityResult(requestCode, resultCode, data)) { if (importOpHelper.handleActivityResult(requestCode, resultCode, data)) {
return; return;
} }
if (mEditOpHelper != null) { if (editOpHelper != null) {
mEditOpHelper.handleActivityResult(requestCode, resultCode, data); editOpHelper.handleActivityResult(requestCode, resultCode, data);
} }
if (resultCode != Activity.RESULT_OK) { if (resultCode != Activity.RESULT_OK) {
@@ -577,7 +552,7 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
Notify.create(this, R.string.error_scan_fp, Notify.LENGTH_LONG, Style.ERROR).show(); Notify.create(this, R.string.error_scan_fp, Notify.LENGTH_LONG, Style.ERROR).show();
return; return;
} }
if (Arrays.equals(mFingerprint, fingerprint)) { if (Arrays.equals(this.fingerprint, fingerprint)) {
certifyImmediate(); certifyImmediate();
} else { } else {
Notify.create(this, R.string.error_scan_match, Notify.LENGTH_LONG, Style.ERROR).show(); Notify.create(this, R.string.error_scan_match, Notify.LENGTH_LONG, Style.ERROR).show();
@@ -617,33 +592,30 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
} }
public void showMainFragment() { public void showMainFragment() {
new Handler().post(new Runnable() { new Handler().post(() -> {
@Override FragmentManager manager = getSupportFragmentManager();
public void run() {
FragmentManager manager = getSupportFragmentManager();
// unless we must refresh // unless we must refresh
ViewKeyFragment frag = (ViewKeyFragment) manager.findFragmentByTag("view_key_fragment"); ViewKeyFragment frag = (ViewKeyFragment) manager.findFragmentByTag("view_key_fragment");
// if everything is valid, just drop it // if everything is valid, just drop it
if (frag != null && frag.isValidForData(mIsSecret)) { if (frag != null && frag.isValidForData(isSecret)) {
return; return;
}
// if the main fragment doesn't exist, or is not of the correct type, (re)create it
frag = ViewKeyFragment.newInstance(mMasterKeyId, mIsSecret);
// get rid of possible backstack, this fragment is always at the bottom
manager.popBackStack("security_token", FragmentManager.POP_BACK_STACK_INCLUSIVE);
manager.beginTransaction()
.replace(R.id.view_key_fragment, frag, "view_key_fragment")
// if this gets lost, it doesn't really matter since the loader will reinstate it onResume
.commitAllowingStateLoss();
} }
// if the main fragment doesn't exist, or is not of the correct type, (re)create it
frag = ViewKeyFragment.newInstance(masterKeyId, isSecret);
// get rid of possible backstack, this fragment is always at the bottom
manager.popBackStack("security_token", FragmentManager.POP_BACK_STACK_INCLUSIVE);
manager.beginTransaction()
.replace(R.id.view_key_fragment, frag, "view_key_fragment")
// if this gets lost, it doesn't really matter since the loader will reinstate it onResume
.commitAllowingStateLoss();
}); });
} }
private void encrypt(Uri dataUri, boolean text) { private void encrypt(Uri dataUri, boolean text) {
// If there is no encryption key, don't bother. // If there is no encryption key, don't bother.
if (!mHasEncrypt) { if (!hasEncrypt) {
Notify.create(this, R.string.error_no_encrypt_subkey, Notify.Style.ERROR).show(); Notify.create(this, R.string.error_no_encrypt_subkey, Notify.Style.ERROR).show();
return; return;
} }
@@ -700,18 +672,18 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
} }
protected void onPostExecute(Bitmap qrCode) { protected void onPostExecute(Bitmap qrCode) {
mQrCodeLoaded = fingerprint; qrCodeLoaded = fingerprint;
// scale the image up to our actual size. we do this in code rather // scale the image up to our actual size. we do this in code rather
// than let the ImageView do this because we don't require filtering. // than let the ImageView do this because we don't require filtering.
Bitmap scaled = Bitmap.createScaledBitmap(qrCode, Bitmap scaled = Bitmap.createScaledBitmap(qrCode,
mQrCode.getHeight(), mQrCode.getHeight(), ViewKeyActivity.this.qrCodeView.getHeight(), ViewKeyActivity.this.qrCodeView.getHeight(),
false); false);
mQrCode.setImageBitmap(scaled); ViewKeyActivity.this.qrCodeView.setImageBitmap(scaled);
// simple fade-in animation // simple fade-in animation
AlphaAnimation anim = new AlphaAnimation(0.0f, 1.0f); AlphaAnimation anim = new AlphaAnimation(0.0f, 1.0f);
anim.setDuration(200); anim.setDuration(200);
mQrCode.startAnimation(anim); ViewKeyActivity.this.qrCodeView.startAnimation(anim);
} }
}; };
@@ -753,7 +725,7 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
public Loader<Cursor> onCreateLoader(int id, Bundle args) { public Loader<Cursor> onCreateLoader(int id, Bundle args) {
switch (id) { switch (id) {
case LOADER_ID_UNIFIED: { case LOADER_ID_UNIFIED: {
Uri baseUri = KeychainContract.KeyRings.buildUnifiedKeyRingUri(mDataUri); Uri baseUri = KeychainContract.KeyRings.buildUnifiedKeyRingUri(dataUri);
return new CursorLoader(this, baseUri, PROJECTION, null, null, null); return new CursorLoader(this, baseUri, PROJECTION, null, null, null);
} }
@@ -803,23 +775,23 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
String name = data.getString(INDEX_NAME); String name = data.getString(INDEX_NAME);
mCollapsingToolbarLayout.setTitle(name != null ? name : getString(R.string.user_id_no_name)); collapsingToolbarLayout.setTitle(name != null ? name : getString(R.string.user_id_no_name));
mMasterKeyId = data.getLong(INDEX_MASTER_KEY_ID); masterKeyId = data.getLong(INDEX_MASTER_KEY_ID);
mFingerprint = data.getBlob(INDEX_FINGERPRINT); fingerprint = data.getBlob(INDEX_FINGERPRINT);
mIsSecret = data.getInt(INDEX_HAS_ANY_SECRET) != 0; isSecret = data.getInt(INDEX_HAS_ANY_SECRET) != 0;
mHasEncrypt = data.getInt(INDEX_HAS_ENCRYPT) != 0; hasEncrypt = data.getInt(INDEX_HAS_ENCRYPT) != 0;
mIsRevoked = data.getInt(INDEX_IS_REVOKED) > 0; isRevoked = data.getInt(INDEX_IS_REVOKED) > 0;
mIsExpired = data.getInt(INDEX_IS_EXPIRED) != 0; isExpired = data.getInt(INDEX_IS_EXPIRED) != 0;
mIsSecure = data.getInt(INDEX_IS_SECURE) == 1; isSecure = data.getInt(INDEX_IS_SECURE) == 1;
mIsVerified = data.getInt(INDEX_VERIFIED) > 0; isVerified = data.getInt(INDEX_VERIFIED) > 0;
// queue showing of the main fragment // queue showing of the main fragment
showMainFragment(); showMainFragment();
// if the refresh animation isn't playing // if the refresh animation isn't playing
if (!mRotate.hasStarted() && !mRotateSpin.hasStarted()) { if (!rotate.hasStarted() && !rotateSpin.hasStarted()) {
// re-create options menu based on mIsSecret, mIsVerified // re-create options menu based on isSecret, isVerified
supportInvalidateOptionsMenu(); supportInvalidateOptionsMenu();
// this is done at the end of the animation otherwise // this is done at the end of the animation otherwise
} }
@@ -836,72 +808,72 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
return; return;
} }
mPhoto.setImageBitmap(photo); photoView.setImageBitmap(photo);
mPhoto.setColorFilter(getResources().getColor(R.color.toolbar_photo_tint), PorterDuff.Mode.SRC_ATOP); photoView.setColorFilter(getResources().getColor(R.color.toolbar_photo_tint), PorterDuff.Mode.SRC_ATOP);
mPhotoLayout.setVisibility(View.VISIBLE); photoLayout.setVisibility(View.VISIBLE);
} }
}; };
boolean showStatusText = mIsSecure && !mIsExpired && !mIsRevoked; boolean showStatusText = isSecure && !isExpired && !isRevoked;
if (showStatusText) { if (showStatusText) {
mStatusText.setVisibility(View.VISIBLE); statusText.setVisibility(View.VISIBLE);
if (mIsSecret) { if (isSecret) {
mStatusText.setText(R.string.view_key_my_key); statusText.setText(R.string.view_key_my_key);
} else if (mIsVerified) { } else if (isVerified) {
mStatusText.setText(R.string.view_key_verified); statusText.setText(R.string.view_key_verified);
} else { } else {
mStatusText.setText(R.string.view_key_unverified); statusText.setText(R.string.view_key_unverified);
} }
} else { } else {
mStatusText.setVisibility(View.GONE); statusText.setVisibility(View.GONE);
} }
// Note: order is important // Note: order is important
int color; int color;
if (mIsRevoked) { if (isRevoked) {
mStatusImage.setVisibility(View.VISIBLE); statusImage.setVisibility(View.VISIBLE);
KeyFormattingUtils.setStatusImage(this, mStatusImage, mStatusText, KeyFormattingUtils.setStatusImage(this, statusImage, statusText,
State.REVOKED, R.color.icons, true); State.REVOKED, R.color.icons, true);
// noinspection deprecation, fix requires api level 23 // noinspection deprecation, fix requires api level 23
color = getResources().getColor(R.color.key_flag_red); color = getResources().getColor(R.color.key_flag_red);
mActionEncryptFile.setVisibility(View.INVISIBLE); actionEncryptFile.setVisibility(View.INVISIBLE);
mActionEncryptText.setVisibility(View.INVISIBLE); actionEncryptText.setVisibility(View.INVISIBLE);
hideFab(); hideFab();
mQrCodeLayout.setVisibility(View.GONE); qrCodeLayout.setVisibility(View.GONE);
} else if (!mIsSecure) { } else if (!isSecure) {
mStatusImage.setVisibility(View.VISIBLE); statusImage.setVisibility(View.VISIBLE);
KeyFormattingUtils.setStatusImage(this, mStatusImage, mStatusText, KeyFormattingUtils.setStatusImage(this, statusImage, statusText,
State.INSECURE, R.color.icons, true); State.INSECURE, R.color.icons, true);
// noinspection deprecation, fix requires api level 23 // noinspection deprecation, fix requires api level 23
color = getResources().getColor(R.color.key_flag_red); color = getResources().getColor(R.color.key_flag_red);
mActionEncryptFile.setVisibility(View.INVISIBLE); actionEncryptFile.setVisibility(View.INVISIBLE);
mActionEncryptText.setVisibility(View.INVISIBLE); actionEncryptText.setVisibility(View.INVISIBLE);
hideFab(); hideFab();
mQrCodeLayout.setVisibility(View.GONE); qrCodeLayout.setVisibility(View.GONE);
} else if (mIsExpired) { } else if (isExpired) {
mStatusImage.setVisibility(View.VISIBLE); statusImage.setVisibility(View.VISIBLE);
KeyFormattingUtils.setStatusImage(this, mStatusImage, mStatusText, KeyFormattingUtils.setStatusImage(this, statusImage, statusText,
State.EXPIRED, R.color.icons, true); State.EXPIRED, R.color.icons, true);
// noinspection deprecation, fix requires api level 23 // noinspection deprecation, fix requires api level 23
color = getResources().getColor(R.color.key_flag_red); color = getResources().getColor(R.color.key_flag_red);
mActionEncryptFile.setVisibility(View.INVISIBLE); actionEncryptFile.setVisibility(View.INVISIBLE);
mActionEncryptText.setVisibility(View.INVISIBLE); actionEncryptText.setVisibility(View.INVISIBLE);
hideFab(); hideFab();
mQrCodeLayout.setVisibility(View.GONE); qrCodeLayout.setVisibility(View.GONE);
} else if (mIsSecret) { } else if (isSecret) {
mStatusImage.setVisibility(View.GONE); statusImage.setVisibility(View.GONE);
// noinspection deprecation, fix requires api level 23 // noinspection deprecation, fix requires api level 23
color = getResources().getColor(R.color.key_flag_green); color = getResources().getColor(R.color.key_flag_green);
// reload qr code only if the fingerprint changed // reload qr code only if the fingerprint changed
if (!Arrays.equals(mFingerprint, mQrCodeLoaded)) { if (!Arrays.equals(fingerprint, qrCodeLoaded)) {
loadQrCode(mFingerprint); loadQrCode(fingerprint);
} }
photoTask.execute(mMasterKeyId); photoTask.execute(masterKeyId);
mQrCodeLayout.setVisibility(View.VISIBLE); qrCodeLayout.setVisibility(View.VISIBLE);
// and place leftOf qr code // and place leftOf qr code
// RelativeLayout.LayoutParams nameParams = (RelativeLayout.LayoutParams) // RelativeLayout.LayoutParams nameParams = (RelativeLayout.LayoutParams)
@@ -915,39 +887,39 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
// mName.setLayoutParams(nameParams); // mName.setLayoutParams(nameParams);
RelativeLayout.LayoutParams statusParams = (RelativeLayout.LayoutParams) RelativeLayout.LayoutParams statusParams = (RelativeLayout.LayoutParams)
mStatusText.getLayoutParams(); statusText.getLayoutParams();
statusParams.setMargins(FormattingUtils.dpToPx(this, 48), 0, 0, 0); statusParams.setMargins(FormattingUtils.dpToPx(this, 48), 0, 0, 0);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
statusParams.setMarginEnd(0); statusParams.setMarginEnd(0);
} }
statusParams.addRule(RelativeLayout.LEFT_OF, R.id.view_key_qr_code_layout); statusParams.addRule(RelativeLayout.LEFT_OF, R.id.view_key_qr_code_layout);
mStatusText.setLayoutParams(statusParams); statusText.setLayoutParams(statusParams);
mActionEncryptFile.setVisibility(View.VISIBLE); actionEncryptFile.setVisibility(View.VISIBLE);
mActionEncryptText.setVisibility(View.VISIBLE); actionEncryptText.setVisibility(View.VISIBLE);
showFab(); showFab();
// noinspection deprecation (no getDrawable with theme at current minApi level 15!) // noinspection deprecation (no getDrawable with theme at current minApi level 15!)
mFab.setImageDrawable(getResources().getDrawable(R.drawable.ic_repeat_white_24dp)); floatingActionButton.setImageDrawable(getResources().getDrawable(R.drawable.ic_repeat_white_24dp));
} else { } else {
mActionEncryptFile.setVisibility(View.VISIBLE); actionEncryptFile.setVisibility(View.VISIBLE);
mActionEncryptText.setVisibility(View.VISIBLE); actionEncryptText.setVisibility(View.VISIBLE);
mQrCodeLayout.setVisibility(View.GONE); qrCodeLayout.setVisibility(View.GONE);
if (mIsVerified) { if (isVerified) {
mStatusText.setText(R.string.view_key_verified); statusText.setText(R.string.view_key_verified);
mStatusImage.setVisibility(View.VISIBLE); statusImage.setVisibility(View.VISIBLE);
KeyFormattingUtils.setStatusImage(this, mStatusImage, mStatusText, KeyFormattingUtils.setStatusImage(this, statusImage, statusText,
State.VERIFIED, R.color.icons, true); State.VERIFIED, R.color.icons, true);
// noinspection deprecation, fix requires api level 23 // noinspection deprecation, fix requires api level 23
color = getResources().getColor(R.color.key_flag_green); color = getResources().getColor(R.color.key_flag_green);
photoTask.execute(mMasterKeyId); photoTask.execute(masterKeyId);
hideFab(); hideFab();
} else { } else {
mStatusText.setText(R.string.view_key_unverified); statusText.setText(R.string.view_key_unverified);
mStatusImage.setVisibility(View.VISIBLE); statusImage.setVisibility(View.VISIBLE);
KeyFormattingUtils.setStatusImage(this, mStatusImage, mStatusText, KeyFormattingUtils.setStatusImage(this, statusImage, statusText,
State.UNVERIFIED, R.color.icons, true); State.UNVERIFIED, R.color.icons, true);
// noinspection deprecation, fix requires api level 23 // noinspection deprecation, fix requires api level 23
color = getResources().getColor(R.color.key_flag_orange); color = getResources().getColor(R.color.key_flag_orange);
@@ -957,16 +929,16 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
} }
if (mPreviousColor == 0 || mPreviousColor == color) { if (mPreviousColor == 0 || mPreviousColor == color) {
mAppBarLayout.setBackgroundColor(color); appBarLayout.setBackgroundColor(color);
mCollapsingToolbarLayout.setContentScrimColor(color); collapsingToolbarLayout.setContentScrimColor(color);
mCollapsingToolbarLayout.setStatusBarScrimColor(getStatusBarBackgroundColor(color)); collapsingToolbarLayout.setStatusBarScrimColor(getStatusBarBackgroundColor(color));
mPreviousColor = color; mPreviousColor = color;
} else { } else {
ObjectAnimator colorFade = ObjectAnimator colorFade =
ObjectAnimator.ofObject(mAppBarLayout, "backgroundColor", ObjectAnimator.ofObject(appBarLayout, "backgroundColor",
new ArgbEvaluator(), mPreviousColor, color); new ArgbEvaluator(), mPreviousColor, color);
mCollapsingToolbarLayout.setContentScrimColor(color); collapsingToolbarLayout.setContentScrimColor(color);
mCollapsingToolbarLayout.setStatusBarScrimColor(getStatusBarBackgroundColor(color)); collapsingToolbarLayout.setStatusBarScrimColor(getStatusBarBackgroundColor(color));
colorFade.setDuration(1200); colorFade.setDuration(1200);
colorFade.start(); colorFade.start();
@@ -974,7 +946,7 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
} }
//noinspection deprecation //noinspection deprecation
mStatusImage.setAlpha(80); statusImage.setAlpha(80);
break; break;
} }
@@ -986,22 +958,22 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
* Helper to show Fab, from http://stackoverflow.com/a/31047038 * Helper to show Fab, from http://stackoverflow.com/a/31047038
*/ */
private void showFab() { private void showFab() {
CoordinatorLayout.LayoutParams p = (CoordinatorLayout.LayoutParams) mFab.getLayoutParams(); CoordinatorLayout.LayoutParams p = (CoordinatorLayout.LayoutParams) floatingActionButton.getLayoutParams();
p.setBehavior(new FloatingActionButton.Behavior()); p.setBehavior(new FloatingActionButton.Behavior());
p.setAnchorId(R.id.app_bar_layout); p.setAnchorId(R.id.app_bar_layout);
mFab.setLayoutParams(p); floatingActionButton.setLayoutParams(p);
mFab.setVisibility(View.VISIBLE); floatingActionButton.setVisibility(View.VISIBLE);
} }
/** /**
* Helper to hide Fab, from http://stackoverflow.com/a/31047038 * Helper to hide Fab, from http://stackoverflow.com/a/31047038
*/ */
private void hideFab() { private void hideFab() {
CoordinatorLayout.LayoutParams p = (CoordinatorLayout.LayoutParams) mFab.getLayoutParams(); CoordinatorLayout.LayoutParams p = (CoordinatorLayout.LayoutParams) floatingActionButton.getLayoutParams();
p.setBehavior(null); //should disable default animations p.setBehavior(null); //should disable default animations
p.setAnchorId(View.NO_ID); //should let you set visibility p.setAnchorId(View.NO_ID); //should let you set visibility
mFab.setLayoutParams(p); floatingActionButton.setLayoutParams(p);
mFab.setVisibility(View.GONE); floatingActionButton.setVisibility(View.GONE);
} }
@Override @Override
@@ -1012,45 +984,42 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements
// CryptoOperationHelper.Callback functions // CryptoOperationHelper.Callback functions
private void updateFromKeyserver(Uri dataUri, KeyRepository keyRepository) private void updateFromKeyserver() {
throws PgpKeyNotFoundException { if (fingerprint == null) {
return;
}
mIsRefreshing = true; isRefreshing = true;
mRefreshItem.setEnabled(false); refreshItem.setEnabled(false);
mRefreshItem.setActionView(mRefresh); refreshItem.setActionView(refreshView);
mRefresh.startAnimation(mRotate); refreshView.startAnimation(rotate);
byte[] blob = keyRepository.getCachedPublicKeyRing(dataUri).getFingerprint(); importOpHelper.cryptoOperation();
ParcelableKeyRing keyEntry = ParcelableKeyRing.createFromReference(blob, null, null, null);
ArrayList<ParcelableKeyRing> entries = new ArrayList<>();
entries.add(keyEntry);
mKeyList = entries;
mKeyserver = Preferences.getPreferences(this).getPreferredKeyserver();
mImportOpHelper.cryptoOperation();
} }
@Override @Override
public ImportKeyringParcel createOperationInput() { public ImportKeyringParcel createOperationInput() {
return ImportKeyringParcel.createImportKeyringParcel(mKeyList, mKeyserver); HkpKeyserverAddress preferredKeyserver = Preferences.getPreferences(this).getPreferredKeyserver();
ParcelableKeyRing keyEntry = ParcelableKeyRing.createFromReference(fingerprint, null, null, null);
return ImportKeyringParcel.createImportKeyringParcel(Collections.singletonList(keyEntry), preferredKeyserver);
} }
@Override @Override
public void onCryptoOperationSuccess(ImportKeyResult result) { public void onCryptoOperationSuccess(ImportKeyResult result) {
mIsRefreshing = false; isRefreshing = false;
result.createNotify(this).show(); result.createNotify(this).show();
} }
@Override @Override
public void onCryptoOperationCancelled() { public void onCryptoOperationCancelled() {
mIsRefreshing = false; isRefreshing = false;
} }
@Override @Override
public void onCryptoOperationError(ImportKeyResult result) { public void onCryptoOperationError(ImportKeyResult result) {
mIsRefreshing = false; isRefreshing = false;
result.createNotify(this).show(); result.createNotify(this).show();
} }

View File

@@ -58,17 +58,17 @@ public class ViewKeyFragment extends LoaderFragment implements ViewKeyMvpView, O
private static final int LOADER_ID_SUBKEY_STATUS = 3; private static final int LOADER_ID_SUBKEY_STATUS = 3;
private static final int LOADER_ID_KEYSERVER_STATUS = 4; private static final int LOADER_ID_KEYSERVER_STATUS = 4;
private IdentitiesCardView mIdentitiesCardView; private IdentitiesCardView identitiesCardView;
private IdentitiesPresenter mIdentitiesPresenter; private IdentitiesPresenter identitiesPresenter;
SystemContactCardView mSystemContactCard; SystemContactCardView systemContactCard;
SystemContactPresenter mSystemContactPresenter; SystemContactPresenter systemContactPresenter;
KeyHealthView mKeyStatusHealth; KeyHealthView keyStatusHealth;
KeyserverStatusView mKeyStatusKeyserver; KeyserverStatusView keyStatusKeyserver;
KeyHealthPresenter mKeyHealthPresenter; KeyHealthPresenter keyHealthPresenter;
KeyserverStatusPresenter mKeyserverStatusPresenter; KeyserverStatusPresenter keyserverStatusPresenter;
private Integer displayedContextMenuPosition; private Integer displayedContextMenuPosition;
@@ -91,11 +91,11 @@ public class ViewKeyFragment extends LoaderFragment implements ViewKeyMvpView, O
View root = super.onCreateView(inflater, superContainer, savedInstanceState); View root = super.onCreateView(inflater, superContainer, savedInstanceState);
View view = inflater.inflate(R.layout.view_key_fragment, getContainer()); View view = inflater.inflate(R.layout.view_key_fragment, getContainer());
mIdentitiesCardView = view.findViewById(R.id.card_identities); identitiesCardView = view.findViewById(R.id.card_identities);
mSystemContactCard = view.findViewById(R.id.linked_system_contact_card); systemContactCard = view.findViewById(R.id.linked_system_contact_card);
mKeyStatusHealth = view.findViewById(R.id.key_status_health); keyStatusHealth = view.findViewById(R.id.key_status_health);
mKeyStatusKeyserver = view.findViewById(R.id.key_status_keyserver); keyStatusKeyserver = view.findViewById(R.id.key_status_keyserver);
return root; return root;
} }
@@ -107,21 +107,21 @@ public class ViewKeyFragment extends LoaderFragment implements ViewKeyMvpView, O
long masterKeyId = getArguments().getLong(ARG_MASTER_KEY_ID); long masterKeyId = getArguments().getLong(ARG_MASTER_KEY_ID);
mIsSecret = getArguments().getBoolean(ARG_IS_SECRET); mIsSecret = getArguments().getBoolean(ARG_IS_SECRET);
mIdentitiesPresenter = new IdentitiesPresenter( identitiesPresenter = new IdentitiesPresenter(
getContext(), mIdentitiesCardView, this, LOADER_IDENTITIES, masterKeyId, mIsSecret); getContext(), identitiesCardView, this, LOADER_IDENTITIES, masterKeyId, mIsSecret);
mIdentitiesPresenter.startLoader(getLoaderManager()); identitiesPresenter.startLoader(getLoaderManager());
mSystemContactPresenter = new SystemContactPresenter( systemContactPresenter = new SystemContactPresenter(
getContext(), mSystemContactCard, LOADER_ID_LINKED_CONTACT, masterKeyId, mIsSecret); getContext(), systemContactCard, LOADER_ID_LINKED_CONTACT, masterKeyId, mIsSecret);
mSystemContactPresenter.startLoader(getLoaderManager()); systemContactPresenter.startLoader(getLoaderManager());
mKeyHealthPresenter = new KeyHealthPresenter( keyHealthPresenter = new KeyHealthPresenter(
getContext(), mKeyStatusHealth, LOADER_ID_SUBKEY_STATUS, masterKeyId, mIsSecret); getContext(), keyStatusHealth, LOADER_ID_SUBKEY_STATUS, masterKeyId, mIsSecret);
mKeyHealthPresenter.startLoader(getLoaderManager()); keyHealthPresenter.startLoader(getLoaderManager());
mKeyserverStatusPresenter = new KeyserverStatusPresenter( keyserverStatusPresenter = new KeyserverStatusPresenter(
getContext(), mKeyStatusKeyserver, LOADER_ID_KEYSERVER_STATUS, masterKeyId, mIsSecret); getContext(), keyStatusKeyserver, LOADER_ID_KEYSERVER_STATUS, masterKeyId, mIsSecret);
mKeyserverStatusPresenter.startLoader(getLoaderManager()); keyserverStatusPresenter.startLoader(getLoaderManager());
} }
@Override @Override
@@ -193,7 +193,7 @@ public class ViewKeyFragment extends LoaderFragment implements ViewKeyMvpView, O
case R.id.autocrypt_forget: case R.id.autocrypt_forget:
int position = displayedContextMenuPosition; int position = displayedContextMenuPosition;
displayedContextMenuPosition = null; displayedContextMenuPosition = null;
mIdentitiesPresenter.onClickForgetIdentity(position); identitiesPresenter.onClickForgetIdentity(position);
return true; return true;
} }