diff options
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyFragment.java')
-rw-r--r-- | OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyFragment.java | 164 |
1 files changed, 141 insertions, 23 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyFragment.java index a929d52f0..7be695de0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyFragment.java @@ -18,52 +18,73 @@ package org.sufficientlysecure.keychain.ui; + +import java.io.IOException; +import java.util.List; + +import android.annotation.TargetApi; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.graphics.Bitmap; import android.net.Uri; +import android.os.Build; +import android.os.Build.VERSION_CODES; import android.os.Bundle; +import android.os.Handler; import android.provider.ContactsContract; import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; import android.support.v7.widget.CardView; +import android.transition.Fade; +import android.transition.Transition; +import android.transition.TransitionInflater; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.*; +import android.view.ViewTreeObserver; +import android.view.ViewTreeObserver.OnPreDrawListener; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ListView; +import android.widget.TextView; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround; import org.sufficientlysecure.keychain.provider.KeychainContract; +import org.sufficientlysecure.keychain.ui.adapter.LinkedIdsAdapter; import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter; import org.sufficientlysecure.keychain.ui.dialog.UserIdInfoDialogFragment; +import org.sufficientlysecure.keychain.ui.linked.LinkedIdViewFragment; +import org.sufficientlysecure.keychain.ui.linked.LinkedIdViewFragment.OnIdentityLoadedListener; import org.sufficientlysecure.keychain.util.ContactHelper; import org.sufficientlysecure.keychain.util.Log; - -import java.util.List; +import org.sufficientlysecure.keychain.util.Preferences; public class ViewKeyFragment extends LoaderFragment implements LoaderManager.LoaderCallbacks<Cursor> { public static final String ARG_DATA_URI = "uri"; + public static final String ARG_POSTPONE_TYPE = "postpone_type"; private ListView mUserIds; //private ListView mLinkedSystemContact; - boolean mIsSecret = false; + enum PostponeType { + NONE, LINKED; + } - CardView mSystemContactCard; - LinearLayout mSystemContactLayout; - ImageView mSystemContactPicture; - TextView mSystemContactName; + boolean mIsSecret = false; private static final int LOADER_ID_UNIFIED = 0; private static final int LOADER_ID_USER_IDS = 1; private static final int LOADER_ID_LINKED_CONTACT = 2; + private static final int LOADER_ID_LINKED_IDS = 3; private static final String LOADER_EXTRA_LINKED_CONTACT_MASTER_KEY_ID = "loader_linked_contact_master_key_id"; @@ -71,16 +92,29 @@ public class ViewKeyFragment extends LoaderFragment implements = "loader_linked_contact_is_secret"; private UserIdsAdapter mUserIdsAdapter; + private LinkedIdsAdapter mLinkedIdsAdapter; private Uri mDataUri; + private PostponeType mPostponeType; + + private CardView mSystemContactCard; + private LinearLayout mSystemContactLayout; + private ImageView mSystemContactPicture; + private TextView mSystemContactName; + + private ListView mLinkedIds; + private CardView mLinkedIdsCard; + private byte[] mFingerprint; + private TextView mLinkedIdsExpander; /** * Creates new instance of this fragment */ - public static ViewKeyFragment newInstance(Uri dataUri) { + public static ViewKeyFragment newInstance(Uri dataUri, PostponeType postponeType) { ViewKeyFragment frag = new ViewKeyFragment(); Bundle args = new Bundle(); args.putParcelable(ARG_DATA_URI, dataUri); + args.putInt(ARG_POSTPONE_TYPE, postponeType.ordinal()); frag.setArguments(args); @@ -93,6 +127,11 @@ public class ViewKeyFragment extends LoaderFragment implements View view = inflater.inflate(R.layout.view_key_fragment, getContainer()); mUserIds = (ListView) view.findViewById(R.id.view_key_user_ids); + mLinkedIdsCard = (CardView) view.findViewById(R.id.card_linked_ids); + + mLinkedIds = (ListView) view.findViewById(R.id.view_key_linked_ids); + + mLinkedIdsExpander = (TextView) view.findViewById(R.id.view_key_linked_ids_expander); mUserIds.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override @@ -100,6 +139,12 @@ public class ViewKeyFragment extends LoaderFragment implements showUserIdInfo(position); } }); + mLinkedIds.setOnItemClickListener(new OnItemClickListener() { + @Override + public void onItemClick(AdapterView<?> parent, View view, int position, long id) { + showLinkedId(position); + } + }); mSystemContactCard = (CardView) view.findViewById(R.id.linked_system_contact_card); mSystemContactLayout = (LinearLayout) view.findViewById(R.id.system_contact_layout); @@ -109,6 +154,47 @@ public class ViewKeyFragment extends LoaderFragment implements return root; } + private void showLinkedId(final int position) { + final LinkedIdViewFragment frag; + try { + frag = mLinkedIdsAdapter.getLinkedIdFragment(mDataUri, position, mFingerprint); + } catch (IOException e) { + e.printStackTrace(); + return; + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + Transition trans = TransitionInflater.from(getActivity()) + .inflateTransition(R.transition.linked_id_card_trans); + // setSharedElementReturnTransition(trans); + setExitTransition(new Fade()); + frag.setSharedElementEnterTransition(trans); + } + + getFragmentManager().beginTransaction() + .add(R.id.view_key_fragment, frag) + .hide(frag) + .commit(); + + frag.setOnIdentityLoadedListener(new OnIdentityLoadedListener() { + @Override + public void onIdentityLoaded() { + new Handler().post(new Runnable() { + @Override + public void run() { + getFragmentManager().beginTransaction() + .show(frag) + .addSharedElement(mLinkedIdsCard, "card_linked_ids") + .remove(ViewKeyFragment.this) + .addToBackStack("linked_id") + .commit(); + } + }); + } + }); + + } + private void showUserIdInfo(final int position) { if (!mIsSecret) { final boolean isRevoked = mUserIdsAdapter.getIsRevoked(position); @@ -129,8 +215,6 @@ public class ViewKeyFragment extends LoaderFragment implements * Hides card if no linked system contact exists. Sets name, picture * and onClickListener for the linked system contact's layout. * In the case of a secret key, "me" (own profile) contact details are loaded. - * - * @param contactId */ private void loadLinkedSystemContact(final long contactId) { // contact doesn't exist, stop @@ -188,7 +272,6 @@ public class ViewKeyFragment extends LoaderFragment implements * ContactsContract.Contact table) * * @param contactId _ID for row in ContactsContract.Contacts table - * @param context */ private void launchContactActivity(final long contactId, Context context) { Intent intent = new Intent(Intent.ACTION_VIEW); @@ -202,6 +285,7 @@ public class ViewKeyFragment extends LoaderFragment implements super.onActivityCreated(savedInstanceState); Uri dataUri = getArguments().getParcelable(ARG_DATA_URI); + mPostponeType = PostponeType.values()[getArguments().getInt(ARG_POSTPONE_TYPE, 0)]; if (dataUri == null) { Log.e(Constants.TAG, "Data missing. Should be Uri of key!"); getActivity().finish(); @@ -225,12 +309,17 @@ public class ViewKeyFragment extends LoaderFragment implements }; static final int INDEX_MASTER_KEY_ID = 1; + @SuppressWarnings("unused") static final int INDEX_USER_ID = 2; + @SuppressWarnings("unused") static final int INDEX_IS_REVOKED = 3; + @SuppressWarnings("unused") static final int INDEX_IS_EXPIRED = 4; + @SuppressWarnings("unused") static final int INDEX_VERIFIED = 5; static final int INDEX_HAS_ANY_SECRET = 6; static final int INDEX_FINGERPRINT = 7; + @SuppressWarnings("unused") static final int INDEX_HAS_ENCRYPT = 8; private static final String[] RAWCONTACT_PROJECTION = { @@ -246,21 +335,26 @@ public class ViewKeyFragment extends LoaderFragment implements // Prepare the loaders. Either re-connect with an existing ones, // or start new ones. - // TODO Is this loader the same as the one in the activity? getLoaderManager().initLoader(LOADER_ID_UNIFIED, null, this); } @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { - setContentShown(false); switch (id) { case LOADER_ID_UNIFIED: { + setContentShown(false, false); Uri baseUri = KeychainContract.KeyRings.buildUnifiedKeyRingUri(mDataUri); return new CursorLoader(getActivity(), baseUri, UNIFIED_PROJECTION, null, null, null); } - case LOADER_ID_USER_IDS: + + case LOADER_ID_USER_IDS: { return UserIdsAdapter.createLoader(getActivity(), mDataUri); + } + + case LOADER_ID_LINKED_IDS: { + return LinkedIdsAdapter.createLoader(getActivity(), mDataUri); + } //we need a separate loader for linked contact to ensure refreshing on verification case LOADER_ID_LINKED_CONTACT: { @@ -310,19 +404,21 @@ public class ViewKeyFragment extends LoaderFragment implements if (data.moveToFirst()) { mIsSecret = data.getInt(INDEX_HAS_ANY_SECRET) != 0; + mFingerprint = data.getBlob(INDEX_FINGERPRINT); + long masterKeyId = data.getLong(INDEX_MASTER_KEY_ID); // load user ids after we know if it's a secret key mUserIdsAdapter = new UserIdsAdapter(getActivity(), null, 0, !mIsSecret, null); mUserIds.setAdapter(mUserIdsAdapter); getLoaderManager().initLoader(LOADER_ID_USER_IDS, null, this); - long masterKeyId = data.getLong(INDEX_MASTER_KEY_ID); - // we need to load linked contact here to prevent lag introduced by loader - // for the linked contact - long contactId = ContactHelper.findContactId( - getActivity().getContentResolver(), - masterKeyId); - loadLinkedSystemContact(contactId); + if (Preferences.getPreferences(getActivity()).getExperimentalEnableLinkedIdentities()) { + mLinkedIdsAdapter = + new LinkedIdsAdapter(getActivity(), null, 0, mIsSecret, mLinkedIdsExpander); + mLinkedIds.setAdapter(mLinkedIdsAdapter); + getLoaderManager().initLoader(LOADER_ID_LINKED_IDS, null, this); + } + Bundle linkedContactData = new Bundle(); linkedContactData.putLong(LOADER_EXTRA_LINKED_CONTACT_MASTER_KEY_ID, masterKeyId); @@ -336,10 +432,28 @@ public class ViewKeyFragment extends LoaderFragment implements } case LOADER_ID_USER_IDS: { + setContentShown(true, false); mUserIdsAdapter.swapCursor(data); break; } + case LOADER_ID_LINKED_IDS: { + mLinkedIdsAdapter.swapCursor(data); + mLinkedIdsCard.setVisibility(mLinkedIdsAdapter.getCount() > 0 ? View.VISIBLE : View.GONE); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && mPostponeType == PostponeType.LINKED) { + mLinkedIdsCard.getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() { + @TargetApi(VERSION_CODES.LOLLIPOP) + @Override + public boolean onPreDraw() { + mLinkedIdsCard.getViewTreeObserver().removeOnPreDrawListener(this); + getActivity().startPostponedEnterTransition(); + return true; + } + }); + } + break; + } + case LOADER_ID_LINKED_CONTACT: { if (data.moveToFirst()) {// if we have a linked contact long contactId = data.getLong(INDEX_CONTACT_ID); @@ -349,7 +463,6 @@ public class ViewKeyFragment extends LoaderFragment implements } } - setContentShown(true); } /** @@ -363,6 +476,11 @@ public class ViewKeyFragment extends LoaderFragment implements mUserIdsAdapter.swapCursor(null); break; } + case LOADER_ID_LINKED_IDS: { + mLinkedIdsCard.setVisibility(View.GONE); + mLinkedIdsAdapter.swapCursor(null); + break; + } } } |