diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java index 661d8efab..3eced678e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java @@ -140,11 +140,6 @@ public class KeychainContract { .appendPath(PATH_UNIFIED).build(); } - public static Uri buildUnifiedKeyRingUri(Uri uri) { - return CONTENT_URI.buildUpon().appendPath(uri.getPathSegments().get(1)) - .appendPath(PATH_UNIFIED).build(); - } - public static Uri buildUnifiedKeyRingsFindByEmailUri(String email) { return CONTENT_URI.buildUpon().appendPath(PATH_FIND) .appendPath(PATH_BY_EMAIL).appendPath(email).build(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintActivity.java index 58a4c3793..6c958bf5b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintActivity.java @@ -17,40 +17,41 @@ package org.sufficientlysecure.keychain.ui; +import android.arch.lifecycle.ViewModelProviders; +import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.View; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.ui.base.BaseActivity; +import org.sufficientlysecure.keychain.ui.keyview.UnifiedKeyInfoViewModel; import timber.log.Timber; public class CertifyFingerprintActivity extends BaseActivity { - - protected Uri mDataUri; + public static final String EXTRA_MASTER_KEY_ID = "master_key_id"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - mDataUri = getIntent().getData(); - if (mDataUri == null) { - Timber.e("Data missing. Should be uri of key!"); + Bundle extras = getIntent().getExtras(); + if (extras == null || !extras.containsKey(EXTRA_MASTER_KEY_ID)) { + Timber.e("Missing required extra master_key_id!"); finish(); return; } - setFullScreenDialogClose(new View.OnClickListener() { - @Override - public void onClick(View v) { - finish(); - } - }); + setFullScreenDialogClose(v -> finish()); - Timber.i("dataUri: " + mDataUri.toString()); + long masterKeyId = extras.getLong(EXTRA_MASTER_KEY_ID); + UnifiedKeyInfoViewModel viewModel = ViewModelProviders.of(this).get(UnifiedKeyInfoViewModel.class); + viewModel.setMasterKeyId(masterKeyId); - startFragment(savedInstanceState, mDataUri); + if (savedInstanceState == null) { + startFragment(); + } } @Override @@ -58,24 +59,9 @@ public class CertifyFingerprintActivity extends BaseActivity { setContentView(R.layout.certify_fingerprint_activity); } - private void startFragment(Bundle savedInstanceState, Uri dataUri) { - // However, if we're being restored from a previous state, - // then we don't need to do anything and should return or else - // we could end up with overlapping fragments. - if (savedInstanceState != null) { - return; - } - - // Create an instance of the fragment - CertifyFingerprintFragment frag = CertifyFingerprintFragment.newInstance(dataUri); - - // Add the fragment to the 'fragment_container' FrameLayout - // NOTE: We use commitAllowingStateLoss() to prevent weird crashes! - getSupportFragmentManager().beginTransaction() - .replace(R.id.certify_fingerprint_fragment, frag) - .commitAllowingStateLoss(); - // do it immediately! - getSupportFragmentManager().executePendingTransactions(); + private void startFragment() { + CertifyFingerprintFragment frag = CertifyFingerprintFragment.newInstance(); + getSupportFragmentManager().beginTransaction().replace(R.id.certify_fingerprint_fragment, frag).commit(); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintFragment.java index e024c6672..9abb2ad39 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyFingerprintFragment.java @@ -18,79 +18,42 @@ package org.sufficientlysecure.keychain.ui; +import android.arch.lifecycle.ViewModelProviders; 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.support.v4.app.FragmentActivity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; -import org.sufficientlysecure.keychain.provider.KeyRepository; -import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; +import org.sufficientlysecure.keychain.model.SubKey.UnifiedKeyInfo; +import org.sufficientlysecure.keychain.ui.keyview.UnifiedKeyInfoViewModel; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; -import timber.log.Timber; -public class CertifyFingerprintFragment extends Fragment implements LoaderManager.LoaderCallbacks { - +public class CertifyFingerprintFragment extends Fragment { static final int REQUEST_CERTIFY = 1; - public static final String ARG_DATA_URI = "uri"; + private TextView vFingerprint; - private TextView mActionYes; - private TextView mFingerprint; - private TextView mIntro; - private TextView mHeader; + private UnifiedKeyInfoViewModel viewModel; - private static final int LOADER_ID_UNIFIED = 0; - - private Uri mDataUri; - - /** - * Creates new instance of this fragment - */ - public static CertifyFingerprintFragment newInstance(Uri dataUri) { - CertifyFingerprintFragment frag = new CertifyFingerprintFragment(); - Bundle args = new Bundle(); - args.putParcelable(ARG_DATA_URI, dataUri); - - frag.setArguments(args); - - return frag; + public static CertifyFingerprintFragment newInstance() { + return new CertifyFingerprintFragment(); } @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup viewGroup, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.certify_fingerprint_fragment, viewGroup, false); - TextView actionNo = view.findViewById(R.id.certify_fingerprint_button_no); - mActionYes = view.findViewById(R.id.certify_fingerprint_button_yes); + vFingerprint = view.findViewById(R.id.certify_fingerprint_fingerprint); - mFingerprint = view.findViewById(R.id.certify_fingerprint_fingerprint); - mIntro = view.findViewById(R.id.certify_fingerprint_intro); - mHeader = view.findViewById(R.id.certify_fingerprint_fingerprint_header); - - actionNo.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - getActivity().finish(); - } - }); - mActionYes.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - certify(mDataUri); - } - }); + view.findViewById(R.id.certify_fingerprint_button_no).setOnClickListener(v -> requireActivity().finish()); + view.findViewById(R.id.certify_fingerprint_button_yes).setOnClickListener(v -> startCertifyActivity()); return view; } @@ -99,103 +62,35 @@ public class CertifyFingerprintFragment extends Fragment implements LoaderManage public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - Uri dataUri = getArguments().getParcelable(ARG_DATA_URI); - if (dataUri == null) { - Timber.e("Data missing. Should be Uri of key!"); - getActivity().finish(); + viewModel = ViewModelProviders.of(requireActivity()).get(UnifiedKeyInfoViewModel.class); + viewModel.getUnifiedKeyInfoLiveData(requireContext()).observe(this, this::onLoadUnifiedKeyInfo); + } + + private void onLoadUnifiedKeyInfo(UnifiedKeyInfo unifiedKeyInfo) { + if (unifiedKeyInfo == null) { return; } - loadData(dataUri); + String fingerprint = KeyFormattingUtils.convertFingerprintToHex(unifiedKeyInfo.fingerprint()); + vFingerprint.setText(KeyFormattingUtils.formatFingerprint(fingerprint)); } - private void loadData(Uri dataUri) { - mDataUri = dataUri; - - Timber.i("dataUri: " + mDataUri.toString()); - - // Prepare the loaders. Either re-connect with an existing ones, - // or start new ones. - getLoaderManager().initLoader(LOADER_ID_UNIFIED, null, this); - } - - static final String[] UNIFIED_PROJECTION = new String[]{ - KeyRings._ID, KeyRings.FINGERPRINT, - - }; - static final int INDEX_UNIFIED_FINGERPRINT = 1; - - public Loader onCreateLoader(int id, Bundle args) { - switch (id) { - case LOADER_ID_UNIFIED: { - Uri baseUri = KeyRings.buildUnifiedKeyRingUri(mDataUri); - return new CursorLoader(getActivity(), baseUri, UNIFIED_PROJECTION, null, null, null); - } - - default: - return null; - } - } - - public void onLoadFinished(Loader loader, Cursor data) { - /* TODO better error handling? May cause problems when a key is deleted, - * because the notification triggers faster than the activity closes. - */ - // Avoid NullPointerExceptions... - if (data.getCount() == 0) { - return; - } - // Swap the new cursor in. (The framework will take care of closing the - // old cursor once we return.) - switch (loader.getId()) { - case LOADER_ID_UNIFIED: { - if (data.moveToFirst()) { - byte[] fingerprintBlob = data.getBlob(INDEX_UNIFIED_FINGERPRINT); - - displayHexConfirm(fingerprintBlob); - - break; - } - } - - } - } - - private void displayHexConfirm(byte[] fingerprintBlob) { - String fingerprint = KeyFormattingUtils.convertFingerprintToHex(fingerprintBlob); - mFingerprint.setText(KeyFormattingUtils.formatFingerprint(fingerprint)); - } - - /** - * This is called when the last Cursor provided to onLoadFinished() above is about to be closed. - * We need to make sure we are no longer using it. - */ - public void onLoaderReset(Loader loader) { - } - - private void certify(Uri dataUri) { - long keyId = 0; - try { - keyId = KeyRepository.create(getContext()) - .getCachedPublicKeyRing(dataUri) - .extractOrGetMasterKeyId(); - } catch (PgpKeyNotFoundException e) { - Timber.e(e, "key not found!"); - } + private void startCertifyActivity() { Intent certifyIntent = new Intent(getActivity(), CertifyKeyActivity.class); - certifyIntent.putExtras(getActivity().getIntent()); - certifyIntent.putExtra(CertifyKeyActivity.EXTRA_KEY_IDS, new long[]{keyId}); + certifyIntent.putExtras(requireActivity().getIntent()); + certifyIntent.putExtra(CertifyKeyActivity.EXTRA_KEY_IDS, new long[] { viewModel.getMasterKeyId() }); startActivityForResult(certifyIntent, REQUEST_CERTIFY); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { - // always just pass this one through if (requestCode == REQUEST_CERTIFY) { - getActivity().setResult(resultCode, data); - getActivity().finish(); + FragmentActivity activity = requireActivity(); + activity.setResult(resultCode, data); + activity.finish(); return; } + super.onActivityResult(requestCode, resultCode, data); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DeleteKeyDialogActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DeleteKeyDialogActivity.java index d6afada2f..a495deb9a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DeleteKeyDialogActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DeleteKeyDialogActivity.java @@ -17,8 +17,11 @@ package org.sufficientlysecure.keychain.ui; + +import java.util.Date; +import java.util.HashMap; + import android.app.Activity; -import android.support.v7.app.AlertDialog; import android.app.Dialog; import android.content.DialogInterface; import android.content.Intent; @@ -26,6 +29,7 @@ import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v4.app.DialogFragment; import android.support.v4.app.FragmentActivity; +import android.support.v7.app.AlertDialog; import android.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.View; @@ -34,12 +38,11 @@ import android.widget.Spinner; import android.widget.TextView; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.keyimport.HkpKeyserverAddress; import org.sufficientlysecure.keychain.operations.results.DeleteResult; import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.operations.results.RevokeResult; -import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeyRepository; +import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.service.DeleteKeyringParcel; import org.sufficientlysecure.keychain.service.RevokeKeyringParcel; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; @@ -48,9 +51,6 @@ import org.sufficientlysecure.keychain.ui.dialog.CustomAlertDialogBuilder; import org.sufficientlysecure.keychain.ui.util.ThemeChanger; import timber.log.Timber; -import java.util.Date; -import java.util.HashMap; - public class DeleteKeyDialogActivity extends FragmentActivity { public static final String EXTRA_DELETE_MASTER_KEY_IDS = "extra_delete_master_key_ids"; public static final String EXTRA_HAS_SECRET = "extra_has_secret"; @@ -81,6 +81,7 @@ public class DeleteKeyDialogActivity extends FragmentActivity { log.add(OperationResult.LogType.MSG_DEL_ERROR_MULTI_SECRET, 0); returnResult(new DeleteResult(OperationResult.RESULT_ERROR, log, 0, mMasterKeyIds.length)); + return; } if (mMasterKeyIds.length == 1 && mHasSecret) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/keyview/UnifiedKeyInfoViewModel.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/keyview/UnifiedKeyInfoViewModel.java new file mode 100644 index 000000000..de07b3832 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/keyview/UnifiedKeyInfoViewModel.java @@ -0,0 +1,40 @@ +package org.sufficientlysecure.keychain.ui.keyview; + + +import android.arch.lifecycle.LiveData; +import android.arch.lifecycle.ViewModel; +import android.content.Context; + +import org.sufficientlysecure.keychain.livedata.GenericLiveData; +import org.sufficientlysecure.keychain.model.SubKey.UnifiedKeyInfo; +import org.sufficientlysecure.keychain.provider.KeyRepository; +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; + + +public class UnifiedKeyInfoViewModel extends ViewModel { + private Long masterKeyId; + private LiveData unifiedKeyInfoLiveData; + + public void setMasterKeyId(long masterKeyId) { + if (this.masterKeyId != null) { + throw new IllegalStateException("cannot change masterKeyId once set!"); + } + this.masterKeyId = masterKeyId; + } + + public long getMasterKeyId() { + return masterKeyId; + } + + public LiveData getUnifiedKeyInfoLiveData(Context context) { + if (masterKeyId == null) { + throw new IllegalStateException("masterKeyId must be set to retrieve this!"); + } + if (unifiedKeyInfoLiveData == null) { + KeyRepository keyRepository = KeyRepository.create(context); + unifiedKeyInfoLiveData = new GenericLiveData<>(context, KeyRings.buildGenericKeyRingUri(masterKeyId), + () -> keyRepository.getUnifiedKeyInfo(masterKeyId)); + } + return unifiedKeyInfoLiveData; + } +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/keyview/ViewKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/keyview/ViewKeyActivity.java index 2eafd4806..895c273b5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/keyview/ViewKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/keyview/ViewKeyActivity.java @@ -28,8 +28,6 @@ import android.animation.ObjectAnimator; import android.annotation.SuppressLint; import android.app.Activity; import android.app.ActivityOptions; -import android.arch.lifecycle.LiveData; -import android.arch.lifecycle.ViewModel; import android.arch.lifecycle.ViewModelProviders; import android.content.Context; import android.content.Intent; @@ -70,7 +68,6 @@ import org.sufficientlysecure.keychain.Constants; 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.EditKeyResult; import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; @@ -269,7 +266,7 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements qrCodeLayout.setOnClickListener(v -> showQrCodeDialog()); - ViewKeyViewModel viewModel = ViewModelProviders.of(this).get(ViewKeyViewModel.class); + UnifiedKeyInfoViewModel viewModel = ViewModelProviders.of(this).get(UnifiedKeyInfoViewModel.class); viewModel.setMasterKeyId(getIntent().getLongExtra(EXTRA_MASTER_KEY_ID, 0L)); if (savedInstanceState == null && intent.hasExtra(EXTRA_DISPLAY_RESULT)) { @@ -296,30 +293,6 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements } } - public static class ViewKeyViewModel extends ViewModel { - private Long masterKeyId; - private LiveData unifiedKeyInfoLiveData; - - void setMasterKeyId(long masterKeyId) { - if (this.masterKeyId != null) { - throw new IllegalStateException("cannot change masterKeyId once set!"); - } - this.masterKeyId = masterKeyId; - } - - LiveData getUnifiedKeyInfoLiveData(Context context) { - if (masterKeyId == null) { - throw new IllegalStateException("masterKeyId must be set to retrieve this!"); - } - if (unifiedKeyInfoLiveData == null) { - KeyRepository keyRepository = KeyRepository.create(context); - unifiedKeyInfoLiveData = new GenericLiveData<>(context, KeyRings.buildGenericKeyRingUri(masterKeyId), - () -> keyRepository.getUnifiedKeyInfo(masterKeyId)); - } - return unifiedKeyInfoLiveData; - } - } - @Override protected void initLayout() { setContentView(R.layout.view_key_activity); @@ -467,7 +440,7 @@ public class ViewKeyActivity extends BaseSecurityTokenActivity implements private void certifyFingerprint() { Intent intent = new Intent(this, CertifyFingerprintActivity.class); - intent.setData(KeyRings.buildUnifiedKeyRingUri(unifiedKeyInfo.master_key_id())); + intent.putExtra(CertifyFingerprintActivity.EXTRA_MASTER_KEY_ID, unifiedKeyInfo.master_key_id()); startActivityForResult(intent, REQUEST_CERTIFY); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/keyview/ViewKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/keyview/ViewKeyFragment.java index 2a7d83ad8..d81d0d7ea 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/keyview/ViewKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/keyview/ViewKeyFragment.java @@ -46,11 +46,9 @@ import org.sufficientlysecure.keychain.model.SubKey.UnifiedKeyInfo; import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType; import org.sufficientlysecure.keychain.provider.AutocryptPeerDao; -import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.ui.adapter.IdentityAdapter; import org.sufficientlysecure.keychain.ui.adapter.IdentityAdapter.IdentityClickListener; import org.sufficientlysecure.keychain.ui.dialog.UserIdInfoDialogFragment; -import org.sufficientlysecure.keychain.ui.keyview.ViewKeyActivity.ViewKeyViewModel; import org.sufficientlysecure.keychain.ui.keyview.loader.IdentityDao.AutocryptPeerInfo; import org.sufficientlysecure.keychain.ui.keyview.loader.IdentityDao.IdentityInfo; import org.sufficientlysecure.keychain.ui.keyview.loader.IdentityDao.LinkedIdInfo; @@ -119,7 +117,7 @@ public class ViewKeyFragment extends Fragment implements OnMenuItemClickListener Context context = requireContext(); - ViewKeyViewModel viewKeyViewModel = ViewModelProviders.of(requireActivity()).get(ViewKeyViewModel.class); + UnifiedKeyInfoViewModel viewKeyViewModel = ViewModelProviders.of(requireActivity()).get(UnifiedKeyInfoViewModel.class); LiveData unifiedKeyInfoLiveData = viewKeyViewModel.getUnifiedKeyInfoLiveData(requireContext()); unifiedKeyInfoLiveData.observe(this, this::onLoadUnifiedKeyInfo); @@ -277,7 +275,7 @@ public class ViewKeyFragment extends Fragment implements OnMenuItemClickListener private void addLinkedIdentity() { Intent intent = new Intent(requireContext(), LinkedIdWizard.class); - intent.setData(KeyRings.buildUnifiedKeyRingUri(unifiedKeyInfo.master_key_id())); + intent.putExtra(LinkedIdWizard.EXTRA_MASTER_KEY_ID, unifiedKeyInfo.master_key_id()); startActivity(intent); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateFinalFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateFinalFragment.java index ee24386cb..55552ae03 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateFinalFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateFinalFragment.java @@ -17,6 +17,8 @@ package org.sufficientlysecure.keychain.ui.linked; + +import android.arch.lifecycle.ViewModelProviders; import android.graphics.PorterDuff; import android.os.AsyncTask; import android.os.Bundle; @@ -25,7 +27,6 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.view.LayoutInflater; import android.view.View; -import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; @@ -34,6 +35,7 @@ import android.widget.ViewAnimator; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.linked.LinkedAttribute; import org.sufficientlysecure.keychain.linked.LinkedTokenResource; +import org.sufficientlysecure.keychain.model.SubKey.UnifiedKeyInfo; import org.sufficientlysecure.keychain.operations.results.LinkedVerifyResult; import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; @@ -41,68 +43,57 @@ import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.ui.base.CryptoOperationFragment; +import org.sufficientlysecure.keychain.ui.keyview.UnifiedKeyInfoViewModel; import org.sufficientlysecure.keychain.ui.util.Notify; public abstract class LinkedIdCreateFinalFragment extends CryptoOperationFragment { - - protected LinkedIdWizard mLinkedIdWizard; - private ImageView mVerifyImage; private TextView mVerifyStatus; private ViewAnimator mVerifyAnimator; + private long masterKeyId; + byte[] fingerprint; + // This is a resource, set AFTER it has been verified LinkedTokenResource mVerifiedResource = null; private ViewAnimator mVerifyButtonAnimator; - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - mLinkedIdWizard = (LinkedIdWizard) getActivity(); - } - protected abstract View newView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState); - @Override @NonNull - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + UnifiedKeyInfoViewModel viewModel = ViewModelProviders.of(requireActivity()).get(UnifiedKeyInfoViewModel.class); + viewModel.getUnifiedKeyInfoLiveData(requireContext()).observe(this, this::onLoadUnifiedKeyInfo); + } + + private void onLoadUnifiedKeyInfo(UnifiedKeyInfo unifiedKeyInfo) { + this.masterKeyId = unifiedKeyInfo.master_key_id(); + this.fingerprint = unifiedKeyInfo.fingerprint(); + } + + @NonNull + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final View view = newView(inflater, container, savedInstanceState); View nextButton = view.findViewById(R.id.next_button); if (nextButton != null) { - nextButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - cryptoOperation(); - } - }); + nextButton.setOnClickListener(v -> cryptoOperation()); } - view.findViewById(R.id.back_button).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - mLinkedIdWizard.loadFragment(null, null, LinkedIdWizard.FRAG_ACTION_TO_LEFT); - } - }); + view.findViewById(R.id.back_button).setOnClickListener( + v -> ((LinkedIdWizard) requireActivity()).loadFragment(null, LinkedIdWizard.FRAG_ACTION_TO_LEFT)); mVerifyAnimator = view.findViewById(R.id.verify_progress); mVerifyImage = view.findViewById(R.id.verify_image); mVerifyStatus = view.findViewById(R.id.verify_status); mVerifyButtonAnimator = view.findViewById(R.id.verify_buttons); - view.findViewById(R.id.button_verify).setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - proofVerify(); - } - }); + view.findViewById(R.id.button_verify).setOnClickListener(v -> proofVerify()); - view.findViewById(R.id.button_retry).setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - proofVerify(); - } - }); + view.findViewById(R.id.button_retry).setOnClickListener(v -> proofVerify()); setVerifyProgress(false, null); mVerifyStatus.setText(R.string.linked_verify_pending); @@ -154,7 +145,7 @@ public abstract class LinkedIdCreateFinalFragment extends CryptoOperationFragmen return new LinkedVerifyResult(LinkedVerifyResult.RESULT_ERROR, log); } - LinkedVerifyResult result = resource.verify(getActivity(), mLinkedIdWizard.mFingerprint); + LinkedVerifyResult result = resource.verify(getActivity(), fingerprint); // ux flow: this operation should take at last a second timer = System.currentTimeMillis() -timer; @@ -211,7 +202,7 @@ public abstract class LinkedIdCreateFinalFragment extends CryptoOperationFragmen @Override public Parcelable createOperationInput() { SaveKeyringParcel.Builder builder= - SaveKeyringParcel.buildChangeKeyringParcel(mLinkedIdWizard.mMasterKeyId, mLinkedIdWizard.mFingerprint); + SaveKeyringParcel.buildChangeKeyringParcel(masterKeyId, fingerprint); WrappedUserAttribute ua = LinkedAttribute.fromResource(mVerifiedResource).toUserAttribute(); builder.addUserAttribute(ua); return builder.build(); @@ -219,7 +210,7 @@ public abstract class LinkedIdCreateFinalFragment extends CryptoOperationFragmen @Override public void onCryptoOperationSuccess(OperationResult result) { - getActivity().finish(); + requireActivity().finish(); } @Override diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateGithubFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateGithubFragment.java index bc6c79dae..81594bcb4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateGithubFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateGithubFragment.java @@ -33,13 +33,11 @@ import java.util.Random; import android.app.Activity; import android.app.Dialog; +import android.arch.lifecycle.ViewModelProviders; import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnDismissListener; import android.content.Intent; import android.net.Uri; import android.os.AsyncTask; -import android.os.Build; import android.os.Build.VERSION; import android.os.Build.VERSION_CODES; import android.os.Bundle; @@ -47,11 +45,9 @@ import android.os.Handler; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.app.ActivityOptionsCompat; -import android.support.v4.app.FragmentActivity; import android.util.Base64; import android.view.LayoutInflater; import android.view.View; -import android.view.View.OnClickListener; import android.view.ViewGroup; import android.webkit.CookieManager; import android.webkit.WebView; @@ -69,10 +65,12 @@ import org.sufficientlysecure.keychain.BuildConfig; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.linked.LinkedAttribute; import org.sufficientlysecure.keychain.linked.resources.GithubResource; +import org.sufficientlysecure.keychain.model.SubKey.UnifiedKeyInfo; import org.sufficientlysecure.keychain.operations.results.EditKeyResult; import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.ui.base.CryptoOperationFragment; +import org.sufficientlysecure.keychain.ui.keyview.UnifiedKeyInfoViewModel; import org.sufficientlysecure.keychain.ui.keyview.ViewKeyActivity; import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.ui.util.Notify.Style; @@ -109,7 +107,7 @@ public class LinkedIdCreateGithubFragment extends CryptoOperationFragment { + LinkedIdWizard activity = (LinkedIdWizard) requireActivity(); + activity.loadFragment(null, LinkedIdWizard.FRAG_ACTION_TO_LEFT); }); - view.findViewById(R.id.button_send).setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - step1GetOAuthCode(); - // for animation testing - // onCryptoOperationSuccess(null); - } + view.findViewById(R.id.button_send).setOnClickListener(v -> { + step1GetOAuthCode(); + // for animation testing + // onCryptoOperationSuccess(null); }); return view; @@ -152,34 +141,29 @@ public class LinkedIdCreateGithubFragment extends CryptoOperationFragment oAuthRequest("github.com/login/oauth/authorize", BuildConfig.GITHUB_CLIENT_ID, "gist"), 300); } private void showRetryForOAuth() { - - mRetryButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - v.setOnClickListener(null); - step1GetOAuthCode(); - } + mRetryButton.setOnClickListener(v -> { + v.setOnClickListener(null); + step1GetOAuthCode(); }); mButtonContainer.setDisplayedChild(3); @@ -402,14 +386,11 @@ public class LinkedIdCreateGithubFragment extends CryptoOperationFragment { + WrappedUserAttribute ua = LinkedAttribute.fromResource(resource).toUserAttribute(); + mSkpBuilder = SaveKeyringParcel.buildChangeKeyringParcel(mMasterKeyId, mFingerprint); + mSkpBuilder.addUserAttribute(ua); + cryptoOperation(); }, 250); } @@ -429,31 +410,28 @@ public class LinkedIdCreateGithubFragment extends CryptoOperationFragment { + Activity activity = requireActivity(); + Intent intent = ViewKeyActivity.getViewKeyActivityIntent(requireActivity(), mMasterKeyId); + // intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - intent.putExtra(ViewKeyActivity.EXTRA_LINKED_TRANSITION, true); - View linkedItem = mButtonContainer.getChildAt(2); + if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { + intent.putExtra(ViewKeyActivity.EXTRA_LINKED_TRANSITION, true); + View linkedItem = mButtonContainer.getChildAt(2); - Bundle options = ActivityOptionsCompat.makeSceneTransitionAnimation( - activity, linkedItem, linkedItem.getTransitionName()).toBundle(); - activity.startActivity(intent, options); - mFinishOnStop = true; - } else { - activity.startActivity(intent); - activity.finish(); - } + Bundle options = ActivityOptionsCompat.makeSceneTransitionAnimation( + activity, linkedItem, linkedItem.getTransitionName()).toBundle(); + activity.startActivity(intent, options); + mFinishOnStop = true; + } else { + activity.startActivity(intent); + activity.finish(); } }, 1000); } @Override - public void onSaveInstanceState(Bundle outState) { + public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); // cookies are automatically saved, we don't want that @@ -463,7 +441,7 @@ public class LinkedIdCreateGithubFragment extends CryptoOperationFragment { + v.setOnClickListener(null); + mButtonContainer.setDisplayedChild(1); + setState(State.LID_PROCESS); + cryptoOperation(); }); mButtonContainer.setDisplayedChild(3); setState(State.LID_ERROR); @@ -573,12 +548,7 @@ public class LinkedIdCreateGithubFragment extends CryptoOperationFragment step1GetOAuthToken()); auth_dialog.show(); web.loadUrl("https://" + hostAndPath + diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateHttpsStep1Fragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateHttpsStep1Fragment.java index 8a1fd1cc1..4ec67e948 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateHttpsStep1Fragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateHttpsStep1Fragment.java @@ -17,24 +17,22 @@ package org.sufficientlysecure.keychain.ui.linked; + import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.v4.app.Fragment; import android.text.Editable; import android.text.TextWatcher; import android.util.Patterns; import android.view.LayoutInflater; import android.view.View; -import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.EditText; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.linked.resources.GenericHttpsResource; + public class LinkedIdCreateHttpsStep1Fragment extends Fragment { - - LinkedIdWizard mLinkedIdWizard; - EditText mEditUri; public static LinkedIdCreateHttpsStep1Fragment newInstance() { @@ -47,44 +45,23 @@ public class LinkedIdCreateHttpsStep1Fragment extends Fragment { } @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - - mLinkedIdWizard = (LinkedIdWizard) getActivity(); - - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final View view = inflater.inflate(R.layout.linked_create_https_fragment_step1, container, false); - view.findViewById(R.id.next_button).setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - - String uri = "https://" + mEditUri.getText(); - - if (!checkUri(uri)) { - return; - } - - String proofText = GenericHttpsResource.generateText(getActivity(), - mLinkedIdWizard.mFingerprint); - - LinkedIdCreateHttpsStep2Fragment frag = - LinkedIdCreateHttpsStep2Fragment.newInstance(uri, proofText); - - mLinkedIdWizard.loadFragment(null, frag, LinkedIdWizard.FRAG_ACTION_TO_RIGHT); + view.findViewById(R.id.next_button).setOnClickListener(v -> { + String uri = "https://" + mEditUri.getText(); + if (!checkUri(uri)) { + return; } + + LinkedIdCreateHttpsStep2Fragment frag = LinkedIdCreateHttpsStep2Fragment.newInstance(uri); + + ((LinkedIdWizard) requireActivity()).loadFragment(frag, LinkedIdWizard.FRAG_ACTION_TO_RIGHT); }); - view.findViewById(R.id.back_button).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - mLinkedIdWizard.loadFragment(null, null, LinkedIdWizard.FRAG_ACTION_TO_LEFT); - } - }); + view.findViewById(R.id.back_button).setOnClickListener( + v -> ((LinkedIdWizard) requireActivity()).loadFragment(null, LinkedIdWizard.FRAG_ACTION_TO_LEFT)); mEditUri = view.findViewById(R.id.linked_create_https_uri); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateHttpsStep2Fragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateHttpsStep2Fragment.java index 42e6ebd44..e8b350058 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateHttpsStep2Fragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateHttpsStep2Fragment.java @@ -17,47 +17,46 @@ package org.sufficientlysecure.keychain.ui.linked; -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; -import android.os.Environment; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.widget.EditText; - -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; -import org.sufficientlysecure.keychain.linked.resources.GenericHttpsResource; -import org.sufficientlysecure.keychain.ui.util.Notify; -import org.sufficientlysecure.keychain.ui.util.Notify.Style; -import org.sufficientlysecure.keychain.util.FileHelper; import java.io.FileNotFoundException; import java.io.PrintWriter; import java.net.URI; import java.net.URISyntaxException; -public class LinkedIdCreateHttpsStep2Fragment extends LinkedIdCreateFinalFragment { +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.os.Environment; +import android.support.annotation.NonNull; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.EditText; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.linked.resources.GenericHttpsResource; +import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; +import org.sufficientlysecure.keychain.ui.util.Notify; +import org.sufficientlysecure.keychain.ui.util.Notify.Style; +import org.sufficientlysecure.keychain.util.FileHelper; +import timber.log.Timber; + +public class LinkedIdCreateHttpsStep2Fragment extends LinkedIdCreateFinalFragment { private static final int REQUEST_CODE_OUTPUT = 0x00007007; - public static final String ARG_URI = "uri", ARG_TEXT = "text"; + public static final String ARG_URI = "uri"; EditText mEditUri; URI mResourceUri; String mResourceString; - public static LinkedIdCreateHttpsStep2Fragment newInstance - (String uri, String proofText) { + public static LinkedIdCreateHttpsStep2Fragment newInstance(String uri) { LinkedIdCreateHttpsStep2Fragment frag = new LinkedIdCreateHttpsStep2Fragment(); Bundle args = new Bundle(); args.putString(ARG_URI, uri); - args.putString(ARG_TEXT, proofText); frag.setArguments(args); return frag; @@ -75,47 +74,33 @@ public class LinkedIdCreateHttpsStep2Fragment extends LinkedIdCreateFinalFragmen try { mResourceUri = new URI(getArguments().getString(ARG_URI)); } catch (URISyntaxException e) { - e.printStackTrace(); - getActivity().finish(); + Timber.e(e); + requireActivity().finish(); } - mResourceString = getArguments().getString(ARG_TEXT); - - } - - protected View newView(LayoutInflater inflater, - ViewGroup container, Bundle savedInstanceState) { - return inflater.inflate(R.layout.linked_create_https_fragment_step2, container, false); + mResourceString = GenericHttpsResource.generateText(requireActivity(), fingerprint); } @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + protected View newView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + return inflater.inflate(R.layout.linked_create_https_fragment_step2, container, false); + } + + @NonNull + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = super.onCreateView(inflater, container, savedInstanceState); - if (view != null) { + view.findViewById(R.id.button_send).setOnClickListener(v -> proofSend()); + view.findViewById(R.id.button_save).setOnClickListener(v -> proofSave()); - view.findViewById(R.id.button_send).setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - proofSend(); - } - }); - - view.findViewById(R.id.button_save).setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - proofSave(); - } - }); - - mEditUri = view.findViewById(R.id.linked_create_https_uri); - mEditUri.setText(mResourceUri.toString()); - } + mEditUri = view.findViewById(R.id.linked_create_https_uri); + mEditUri.setText(mResourceUri.toString()); return view; } - private void proofSend () { + private void proofSend() { Intent sendIntent = new Intent(); sendIntent.setAction(Intent.ACTION_SEND); sendIntent.putExtra(Intent.EXTRA_TEXT, mResourceString); @@ -123,7 +108,7 @@ public class LinkedIdCreateHttpsStep2Fragment extends LinkedIdCreateFinalFragmen startActivity(sendIntent); } - private void proofSave () { + private void proofSave() { String state = Environment.getExternalStorageState(); if (!Environment.MEDIA_MOUNTED.equals(state)) { Notify.create(getActivity(), "External storage not available!", Style.ERROR).show(); @@ -138,8 +123,7 @@ public class LinkedIdCreateHttpsStep2Fragment extends LinkedIdCreateFinalFragmen private void saveFile(Uri uri) { try { - PrintWriter out = - new PrintWriter(getActivity().getContentResolver().openOutputStream(uri)); + PrintWriter out = new PrintWriter(requireActivity().getContentResolver().openOutputStream(uri)); out.print(mResourceString); if (out.checkError()) { Notify.create(getActivity(), "Error writing file!", Style.ERROR).show(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateTwitterStep1Fragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateTwitterStep1Fragment.java index e93a2c7fd..41d3f2adb 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateTwitterStep1Fragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateTwitterStep1Fragment.java @@ -19,6 +19,7 @@ package org.sufficientlysecure.keychain.ui.linked; import android.os.AsyncTask; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; @@ -30,30 +31,14 @@ import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.ui.util.Notify; public class LinkedIdCreateTwitterStep1Fragment extends Fragment { - - LinkedIdWizard mLinkedIdWizard; - EditText mEditHandle; public static LinkedIdCreateTwitterStep1Fragment newInstance() { - LinkedIdCreateTwitterStep1Fragment frag = new LinkedIdCreateTwitterStep1Fragment(); - - Bundle args = new Bundle(); - frag.setArguments(args); - - return frag; + return new LinkedIdCreateTwitterStep1Fragment(); } @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - - mLinkedIdWizard = (LinkedIdWizard) getActivity(); - - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final View view = inflater.inflate(R.layout.linked_create_twitter_fragment_step1, container, false); view.findViewById(R.id.next_button).setOnClickListener(new OnClickListener() { @@ -96,19 +81,15 @@ public class LinkedIdCreateTwitterStep1Fragment extends Fragment { LinkedIdCreateTwitterStep2Fragment frag = LinkedIdCreateTwitterStep2Fragment.newInstance(handle); - mLinkedIdWizard.loadFragment(null, frag, LinkedIdWizard.FRAG_ACTION_TO_RIGHT); + ((LinkedIdWizard) requireActivity()).loadFragment(frag, LinkedIdWizard.FRAG_ACTION_TO_RIGHT); } }.execute(); } }); - view.findViewById(R.id.back_button).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - mLinkedIdWizard.loadFragment(null, null, LinkedIdWizard.FRAG_ACTION_TO_LEFT); - } - }); + view.findViewById(R.id.back_button).setOnClickListener( + v -> ((LinkedIdWizard) requireActivity()).loadFragment(null, LinkedIdWizard.FRAG_ACTION_TO_LEFT)); mEditHandle = view.findViewById(R.id.linked_create_twitter_handle); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateTwitterStep2Fragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateTwitterStep2Fragment.java index 9bd00c0db..7e5ca0051 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateTwitterStep2Fragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdCreateTwitterStep2Fragment.java @@ -17,20 +17,23 @@ package org.sufficientlysecure.keychain.ui.linked; + import android.content.Intent; import android.net.Uri; import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.text.Html; +import android.text.Spanned; import android.view.LayoutInflater; import android.view.View; -import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.TextView; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; import org.sufficientlysecure.keychain.linked.LinkedTokenResource; import org.sufficientlysecure.keychain.linked.resources.TwitterResource; +import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; public class LinkedIdCreateTwitterStep2Fragment extends LinkedIdCreateFinalFragment { @@ -39,9 +42,7 @@ public class LinkedIdCreateTwitterStep2Fragment extends LinkedIdCreateFinalFragm String mResourceHandle; String mResourceString; - public static LinkedIdCreateTwitterStep2Fragment newInstance - (String handle) { - + public static LinkedIdCreateTwitterStep2Fragment newInstance(String handle) { LinkedIdCreateTwitterStep2Fragment frag = new LinkedIdCreateTwitterStep2Fragment(); Bundle args = new Bundle(); @@ -52,39 +53,23 @@ public class LinkedIdCreateTwitterStep2Fragment extends LinkedIdCreateFinalFragm } @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - mResourceString = - TwitterResource.generate(mLinkedIdWizard.mFingerprint); + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + mResourceString = TwitterResource.generate(fingerprint); mResourceHandle = getArguments().getString(ARG_HANDLE); - } + @NonNull @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = super.onCreateView(inflater, container, savedInstanceState); - if (view != null) { - view.findViewById(R.id.button_send).setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - proofSend(); - } - }); + view.findViewById(R.id.button_send).setOnClickListener(v -> proofSend()); + view.findViewById(R.id.button_share).setOnClickListener(v -> proofShare()); - view.findViewById(R.id.button_share).setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - proofShare(); - } - }); - - ((TextView) view.findViewById(R.id.linked_tweet_published)).setText( - Html.fromHtml(getString(R.string.linked_create_twitter_2_3, mResourceHandle)) - ); - } + Spanned tweetText = Html.fromHtml(getString(R.string.linked_create_twitter_2_3, mResourceHandle)); + ((TextView) view.findViewById(R.id.linked_tweet_published)).setText(tweetText); return view; } @@ -109,13 +94,12 @@ public class LinkedIdCreateTwitterStep2Fragment extends LinkedIdCreateFinalFragm } private void proofSend() { - Uri.Builder builder = Uri.parse("https://twitter.com/intent/tweet").buildUpon(); builder.appendQueryParameter("text", mResourceString); Uri uri = builder.build(); Intent intent = new Intent(Intent.ACTION_VIEW, uri); - getActivity().startActivity(intent); + startActivity(intent); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdSelectFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdSelectFragment.java index b7c00552e..cd8262aaf 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdSelectFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdSelectFragment.java @@ -17,7 +17,9 @@ package org.sufficientlysecure.keychain.ui.linked; + import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; @@ -25,81 +27,33 @@ import android.view.ViewGroup; import org.sufficientlysecure.keychain.R; + public class LinkedIdSelectFragment extends Fragment { - - LinkedIdWizard mLinkedIdWizard; - - /** - * Creates new instance of this fragment - */ public static LinkedIdSelectFragment newInstance() { - LinkedIdSelectFragment frag = new LinkedIdSelectFragment(); - - Bundle args = new Bundle(); - frag.setArguments(args); - - return frag; + return new LinkedIdSelectFragment(); } @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.linked_select_fragment, container, false); - view.findViewById(R.id.linked_create_https_button) - .setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - LinkedIdCreateHttpsStep1Fragment frag = - LinkedIdCreateHttpsStep1Fragment.newInstance(); + view.findViewById(R.id.linked_create_https_button).setOnClickListener(v -> { + LinkedIdCreateHttpsStep1Fragment frag = LinkedIdCreateHttpsStep1Fragment.newInstance(); + ((LinkedIdWizard) requireActivity()).loadFragment(frag, LinkedIdWizard.FRAG_ACTION_TO_RIGHT); + }); - mLinkedIdWizard.loadFragment(null, frag, LinkedIdWizard.FRAG_ACTION_TO_RIGHT); - } - }); + view.findViewById(R.id.linked_create_twitter_button).setOnClickListener(v -> { + LinkedIdCreateTwitterStep1Fragment frag = LinkedIdCreateTwitterStep1Fragment.newInstance(); + ((LinkedIdWizard) requireActivity()).loadFragment(frag, LinkedIdWizard.FRAG_ACTION_TO_RIGHT); + }); - /* - view.findViewById(R.id.linked_create_dns_button) - .setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - LinkedIdCreateDnsStep1Fragment frag = - LinkedIdCreateDnsStep1Fragment.newInstance(); - - mLinkedIdWizard.loadFragment(null, frag, LinkedIdWizard.FRAG_ACTION_TO_RIGHT); - } - }); - */ - - view.findViewById(R.id.linked_create_twitter_button) - .setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - LinkedIdCreateTwitterStep1Fragment frag = - LinkedIdCreateTwitterStep1Fragment.newInstance(); - - mLinkedIdWizard.loadFragment(null, frag, LinkedIdWizard.FRAG_ACTION_TO_RIGHT); - } - }); - - view.findViewById(R.id.linked_create_github_button) - .setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - LinkedIdCreateGithubFragment frag = - LinkedIdCreateGithubFragment.newInstance(); - - mLinkedIdWizard.loadFragment(null, frag, LinkedIdWizard.FRAG_ACTION_TO_RIGHT); - } - }); + view.findViewById(R.id.linked_create_github_button).setOnClickListener(v -> { + LinkedIdCreateGithubFragment frag = LinkedIdCreateGithubFragment.newInstance(); + ((LinkedIdWizard) requireActivity()).loadFragment(frag, LinkedIdWizard.FRAG_ACTION_TO_RIGHT); + }); return view; } - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - - mLinkedIdWizard = (LinkedIdWizard) getActivity(); - } - } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdWizard.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdWizard.java index 28d9a22c5..bea6df04b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdWizard.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/linked/LinkedIdWizard.java @@ -18,64 +18,60 @@ package org.sufficientlysecure.keychain.ui.linked; +import android.arch.lifecycle.ViewModelProviders; import android.content.Context; -import android.content.Intent; -import android.net.Uri; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentTransaction; -import android.support.v4.app.NavUtils; -import android.support.v4.app.TaskStackBuilder; -import android.view.MenuItem; import android.view.View; import android.view.inputmethod.InputMethodManager; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; -import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing; -import org.sufficientlysecure.keychain.provider.KeyRepository; -import org.sufficientlysecure.keychain.provider.KeychainContract; -import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; +import org.sufficientlysecure.keychain.model.SubKey.UnifiedKeyInfo; import org.sufficientlysecure.keychain.ui.base.BaseActivity; +import org.sufficientlysecure.keychain.ui.keyview.UnifiedKeyInfoViewModel; import timber.log.Timber; public class LinkedIdWizard extends BaseActivity { + public static final String EXTRA_MASTER_KEY_ID = "master_key_id"; public static final int FRAG_ACTION_START = 0; public static final int FRAG_ACTION_TO_RIGHT = 1; public static final int FRAG_ACTION_TO_LEFT = 2; - long mMasterKeyId; - byte[] mFingerprint; - @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setTitle(getString(R.string.title_linked_id_create)); - try { - Uri uri = getIntent().getData(); - uri = KeychainContract.KeyRings.buildUnifiedKeyRingUri(uri); - CachedPublicKeyRing ring = KeyRepository.create(this).getCachedPublicKeyRing(uri); - if (!ring.hasAnySecret()) { - Timber.e("Linked Identities can only be added to secret keys!"); - finish(); - return; - } - - mMasterKeyId = ring.extractOrGetMasterKeyId(); - mFingerprint = ring.getFingerprint(); - } catch (PgpKeyNotFoundException e) { - Timber.e("Invalid uri given, key does not exist!"); + Bundle extras = getIntent().getExtras(); + if (extras == null || !extras.containsKey(EXTRA_MASTER_KEY_ID)) { + Timber.e("Missing required extra master_key_id!"); finish(); return; } + long masterKeyId = extras.getLong(EXTRA_MASTER_KEY_ID); + UnifiedKeyInfoViewModel viewModel = ViewModelProviders.of(this).get(UnifiedKeyInfoViewModel.class); + viewModel.setMasterKeyId(masterKeyId); + viewModel.getUnifiedKeyInfoLiveData(this).observe(this, this::onLoadUnifiedKeyInfo); + + hideKeyboard(); + // pass extras into fragment - LinkedIdSelectFragment frag = LinkedIdSelectFragment.newInstance(); - loadFragment(null, frag, FRAG_ACTION_START); + if (savedInstanceState == null) { + LinkedIdSelectFragment frag = LinkedIdSelectFragment.newInstance(); + loadFragment(frag, FRAG_ACTION_START); + } + } + + private void onLoadUnifiedKeyInfo(UnifiedKeyInfo unifiedKeyInfo) { + if (!unifiedKeyInfo.has_any_secret()) { + Timber.e("Linked Identities can only be added to secret keys!"); + finish(); + } } @Override @@ -83,16 +79,7 @@ public class LinkedIdWizard extends BaseActivity { setContentView(R.layout.create_key_activity); } - public void loadFragment(Bundle savedInstanceState, Fragment fragment, int action) { - // However, if we're being restored from a previous state, - // then we don't need to do anything and should return or else - // we could end up with overlapping fragments. - if (savedInstanceState != null) { - return; - } - - hideKeyboard(); - + public void loadFragment(Fragment fragment, int action) { // Add the fragment to the 'fragment_container' FrameLayout // NOTE: We use commitAllowingStateLoss() to prevent weird crashes! FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); @@ -115,50 +102,17 @@ public class LinkedIdWizard extends BaseActivity { break; } - // do it immediately! getSupportFragmentManager().executePendingTransactions(); } private void hideKeyboard() { - InputMethodManager inputManager = (InputMethodManager) - getSystemService(Context.INPUT_METHOD_SERVICE); + InputMethodManager inputManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - // check if no view has focus View v = getCurrentFocus(); - if (v == null) + if (v == null || inputManager == null) { return; + } inputManager.hideSoftInputFromWindow(v.getWindowToken(), 0); } - - @Override - public void onBackPressed() { - if (!getFragmentManager().popBackStackImmediate()) { - navigateBack(); - } - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - // Respond to the action bar's Up/Home button - case android.R.id.home: - navigateBack(); - return true; - } - return super.onOptionsItemSelected(item); - } - - private void navigateBack() { - Intent upIntent = NavUtils.getParentActivityIntent(this); - upIntent.setData(KeyRings.buildGenericKeyRingUri(mMasterKeyId)); - // This activity is NOT part of this app's task, so create a new task - // when navigating up, with a synthesized back stack. - TaskStackBuilder.create(this) - // Add all of this activity's parents to the back stack - .addNextIntentWithParentStack(upIntent) - // Navigate up to the closest parent - .startActivities(); - } - }