use LiveData to load key data in DecryptFragment
This commit is contained in:
parent
4416ddf11c
commit
8d835b3b7f
|
@ -21,16 +21,12 @@ package org.sufficientlysecure.keychain.ui;
|
|||
import java.util.ArrayList;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.arch.lifecycle.LiveData;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.CursorLoader;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
|
@ -43,12 +39,13 @@ import org.openintents.openpgp.util.OpenPgpUtils;
|
|||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.keyimport.HkpKeyserverAddress;
|
||||
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
|
||||
import org.sufficientlysecure.keychain.livedata.GenericLiveData;
|
||||
import org.sufficientlysecure.keychain.model.SubKey.UnifiedKeyInfo;
|
||||
import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
|
||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing.VerificationStatus;
|
||||
import org.sufficientlysecure.keychain.pgp.KeyRing;
|
||||
import org.sufficientlysecure.keychain.provider.KeyRepository;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||
import org.sufficientlysecure.keychain.service.ImportKeyringParcel;
|
||||
import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper;
|
||||
import org.sufficientlysecure.keychain.ui.keyview.ViewKeyActivity;
|
||||
|
@ -60,9 +57,7 @@ import org.sufficientlysecure.keychain.util.Preferences;
|
|||
import timber.log.Timber;
|
||||
|
||||
|
||||
public abstract class DecryptFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {
|
||||
|
||||
public static final int LOADER_ID_UNIFIED = 0;
|
||||
public abstract class DecryptFragment extends Fragment {
|
||||
public static final String ARG_DECRYPT_VERIFY_RESULT = "decrypt_verify_result";
|
||||
|
||||
protected LinearLayout mResultLayout;
|
||||
|
@ -80,32 +75,29 @@ public abstract class DecryptFragment extends Fragment implements LoaderManager.
|
|||
private ViewAnimator mOverlayAnimator;
|
||||
|
||||
private CryptoOperationHelper<ImportKeyringParcel, ImportKeyResult> mImportOpHelper;
|
||||
private LiveData<UnifiedKeyInfo> unifiedKeyInfoLiveData;
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
Activity activity = requireActivity();
|
||||
// NOTE: These views are inside the activity!
|
||||
mResultLayout = getActivity().findViewById(R.id.result_main_layout);
|
||||
mResultLayout = activity.findViewById(R.id.result_main_layout);
|
||||
mEncryptionIcon = activity.findViewById(R.id.result_encryption_icon);
|
||||
mEncryptionText = activity.findViewById(R.id.result_encryption_text);
|
||||
mSignatureIcon = activity.findViewById(R.id.result_signature_icon);
|
||||
mSignatureText = activity.findViewById(R.id.result_signature_text);
|
||||
mSignatureLayout = activity.findViewById(R.id.result_signature_layout);
|
||||
mSignatureName = activity.findViewById(R.id.result_signature_name);
|
||||
mSignatureEmail = activity.findViewById(R.id.result_signature_email);
|
||||
mSignatureAction = activity.findViewById(R.id.result_signature_action);
|
||||
mResultLayout.setVisibility(View.GONE);
|
||||
mEncryptionIcon = getActivity().findViewById(R.id.result_encryption_icon);
|
||||
mEncryptionText = getActivity().findViewById(R.id.result_encryption_text);
|
||||
mSignatureIcon = getActivity().findViewById(R.id.result_signature_icon);
|
||||
mSignatureText = getActivity().findViewById(R.id.result_signature_text);
|
||||
mSignatureLayout = getActivity().findViewById(R.id.result_signature_layout);
|
||||
mSignatureName = getActivity().findViewById(R.id.result_signature_name);
|
||||
mSignatureEmail = getActivity().findViewById(R.id.result_signature_email);
|
||||
mSignatureAction = getActivity().findViewById(R.id.result_signature_action);
|
||||
|
||||
// Overlay
|
||||
mOverlayAnimator = (ViewAnimator) view;
|
||||
Button vErrorOverlayButton = view.findViewById(R.id.decrypt_error_overlay_button);
|
||||
vErrorOverlayButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mOverlayAnimator.setDisplayedChild(0);
|
||||
}
|
||||
});
|
||||
vErrorOverlayButton.setOnClickListener(v -> mOverlayAnimator.setDisplayedChild(0));
|
||||
}
|
||||
|
||||
private void showErrorOverlay(boolean overlay) {
|
||||
|
@ -116,7 +108,7 @@ public abstract class DecryptFragment extends Fragment implements LoaderManager.
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
public void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
|
||||
outState.putParcelable(ARG_DECRYPT_VERIFY_RESULT, mDecryptVerifyResult);
|
||||
|
@ -165,7 +157,7 @@ public abstract class DecryptFragment extends Fragment implements LoaderManager.
|
|||
public void onCryptoOperationSuccess(ImportKeyResult result) {
|
||||
result.createNotify(getActivity()).show();
|
||||
|
||||
getLoaderManager().restartLoader(LOADER_ID_UNIFIED, null, DecryptFragment.this);
|
||||
loadSignerKeyData();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -237,16 +229,13 @@ public abstract class DecryptFragment extends Fragment implements LoaderManager.
|
|||
mSignatureText.setText(R.string.decrypt_result_no_signature);
|
||||
KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.NOT_SIGNED);
|
||||
|
||||
getLoaderManager().destroyLoader(LOADER_ID_UNIFIED);
|
||||
|
||||
loadSignerKeyData();
|
||||
showErrorOverlay(false);
|
||||
|
||||
onVerifyLoaded(true);
|
||||
} else {
|
||||
// signature present
|
||||
|
||||
// after loader is restarted signature results are checked
|
||||
getLoaderManager().restartLoader(LOADER_ID_UNIFIED, null, this);
|
||||
loadSignerKeyData();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -257,70 +246,43 @@ public abstract class DecryptFragment extends Fragment implements LoaderManager.
|
|||
private void setShowAction(final long signatureKeyId) {
|
||||
mSignatureAction.setText(R.string.decrypt_result_action_show);
|
||||
mSignatureAction.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_vpn_key_grey_24dp, 0);
|
||||
mSignatureLayout.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
showKey(signatureKeyId);
|
||||
}
|
||||
});
|
||||
mSignatureLayout.setOnClickListener(v -> showKey(signatureKeyId));
|
||||
}
|
||||
|
||||
// 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.VERIFIED,
|
||||
KeychainContract.KeyRings.HAS_ANY_SECRET,
|
||||
KeyRings.NAME,
|
||||
KeyRings.EMAIL,
|
||||
KeyRings.COMMENT,
|
||||
};
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
static final int INDEX_MASTER_KEY_ID = 1;
|
||||
static final int INDEX_USER_ID = 2;
|
||||
static final int INDEX_VERIFIED = 3;
|
||||
static final int INDEX_HAS_ANY_SECRET = 4;
|
||||
static final int INDEX_NAME = 5;
|
||||
static final int INDEX_EMAIL = 6;
|
||||
static final int INDEX_COMMENT = 7;
|
||||
|
||||
@Override
|
||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||
if (id != LOADER_ID_UNIFIED) {
|
||||
return null;
|
||||
public void loadSignerKeyData() {
|
||||
if (unifiedKeyInfoLiveData != null) {
|
||||
unifiedKeyInfoLiveData.removeObservers(this);
|
||||
unifiedKeyInfoLiveData = 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) {
|
||||
if (mSignatureResult == null || mSignatureResult.getResult() == OpenPgpSignatureResult.RESULT_NO_SIGNATURE) {
|
||||
setSignatureLayoutVisibility(View.GONE);
|
||||
return;
|
||||
}
|
||||
|
||||
// If the key is unknown, show it as such
|
||||
if (data.getCount() == 0 || !data.moveToFirst()) {
|
||||
unifiedKeyInfoLiveData = new GenericLiveData<>(requireContext(), null, () -> {
|
||||
KeyRepository keyRepository = KeyRepository.create(requireContext());
|
||||
Long masterKeyId = keyRepository.getMasterKeyIdBySubkeyId(mSignatureResult.getKeyId());
|
||||
return keyRepository.getUnifiedKeyInfo(masterKeyId);
|
||||
});
|
||||
unifiedKeyInfoLiveData.observe(this, this::onLoadSignerKeyData);
|
||||
}
|
||||
|
||||
public void onLoadSignerKeyData(UnifiedKeyInfo unifiedKeyInfo) {
|
||||
if (unifiedKeyInfo == null) {
|
||||
showUnknownKeyStatus();
|
||||
return;
|
||||
}
|
||||
|
||||
long signatureKeyId = mSignatureResult.getKeyId();
|
||||
|
||||
String name = data.getString(INDEX_NAME);
|
||||
String email = data.getString(INDEX_EMAIL);
|
||||
if (name != null) {
|
||||
mSignatureName.setText(name);
|
||||
if (unifiedKeyInfo.name() != null) {
|
||||
mSignatureName.setText(unifiedKeyInfo.name());
|
||||
} else {
|
||||
mSignatureName.setText(R.string.user_id_no_name);
|
||||
}
|
||||
if (email != null) {
|
||||
mSignatureEmail.setText(email);
|
||||
if (unifiedKeyInfo.email() != null) {
|
||||
mSignatureEmail.setText(unifiedKeyInfo.email());
|
||||
} else {
|
||||
mSignatureEmail.setText(KeyFormattingUtils.beautifyKeyIdWithPrefix(
|
||||
mSignatureResult.getKeyId()));
|
||||
|
@ -331,8 +293,8 @@ public abstract class DecryptFragment extends Fragment implements LoaderManager.
|
|||
boolean isRevoked = mSignatureResult.getResult() == OpenPgpSignatureResult.RESULT_INVALID_KEY_REVOKED;
|
||||
boolean isExpired = mSignatureResult.getResult() == OpenPgpSignatureResult.RESULT_INVALID_KEY_EXPIRED;
|
||||
boolean isInsecure = mSignatureResult.getResult() == OpenPgpSignatureResult.RESULT_INVALID_KEY_INSECURE;
|
||||
boolean isVerified = data.getInt(INDEX_VERIFIED) > 0;
|
||||
boolean isYours = data.getInt(INDEX_HAS_ANY_SECRET) != 0;
|
||||
boolean isVerified = unifiedKeyInfo.verified() == VerificationStatus.VERIFIED_SECRET;
|
||||
boolean isYours = unifiedKeyInfo.has_any_secret();
|
||||
|
||||
if (isRevoked) {
|
||||
mSignatureText.setText(R.string.decrypt_result_signature_revoked_key);
|
||||
|
@ -402,16 +364,6 @@ public abstract class DecryptFragment extends Fragment implements LoaderManager.
|
|||
|
||||
}
|
||||
|
||||
@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();
|
||||
|
@ -446,12 +398,7 @@ public abstract class DecryptFragment extends Fragment implements LoaderManager.
|
|||
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);
|
||||
}
|
||||
});
|
||||
mSignatureLayout.setOnClickListener(v -> lookupUnknownKey(signatureKeyId));
|
||||
|
||||
showErrorOverlay(false);
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import android.content.ClipboardManager;
|
|||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.util.Linkify;
|
||||
import android.view.LayoutInflater;
|
||||
|
@ -100,7 +101,7 @@ public class DisplayTextFragment extends DecryptFragment {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
Bundle args = getArguments();
|
||||
|
|
Loading…
Reference in a new issue