make linked identity list homogeneous

This commit is contained in:
Vincent Breitmoser
2015-03-05 13:13:43 +01:00
parent 7b3bc4ca98
commit 5d2c81d715
12 changed files with 157 additions and 113 deletions

View File

@@ -6,18 +6,14 @@ import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.operations.results.LinkedVerifyResult; import org.sufficientlysecure.keychain.operations.results.LinkedVerifyResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType; import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
import org.sufficientlysecure.keychain.pgp.linked.resources.GenericHttpsResource;
import org.sufficientlysecure.keychain.pgp.linked.resources.UnknownResource;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
import java.net.URI; import java.net.URI;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern;
public abstract class LinkedCookieResource extends LinkedResource { public abstract class LinkedCookieResource extends LinkedResource {

View File

@@ -3,6 +3,7 @@ package org.sufficientlysecure.keychain.pgp.linked;
import org.spongycastle.bcpg.UserAttributeSubpacket; import org.spongycastle.bcpg.UserAttributeSubpacket;
import org.spongycastle.util.Strings; import org.spongycastle.util.Strings;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute; import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
@@ -11,6 +12,10 @@ import java.net.URI;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.Arrays; import java.util.Arrays;
import android.content.Context;
import android.support.annotation.DrawableRes;
public class LinkedIdentity extends RawLinkedIdentity { public class LinkedIdentity extends RawLinkedIdentity {
public final LinkedResource mResource; public final LinkedResource mResource;
@@ -72,4 +77,17 @@ public class LinkedIdentity extends RawLinkedIdentity {
return new RawLinkedIdentity(nonce, res.toUri()); return new RawLinkedIdentity(nonce, res.toUri());
} }
public @DrawableRes int getDisplayIcon() {
return mResource.getDisplayIcon();
}
public String getDisplayTitle(Context context) {
return mResource.getDisplayTitle(context);
}
public String getDisplayComment(Context context) {
return mResource.getDisplayComment(context);
}
} }

View File

@@ -3,7 +3,7 @@ package org.sufficientlysecure.keychain.pgp.linked;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.pgp.linked.resources.DnsResource; import org.sufficientlysecure.keychain.pgp.linked.resources.DnsResource;
import org.sufficientlysecure.keychain.pgp.linked.resources.GenericHttpsResource; import org.sufficientlysecure.keychain.pgp.linked.resources.GenericHttpsResource;
import org.sufficientlysecure.keychain.pgp.linked.resources.UnknownResource; import org.sufficientlysecure.keychain.pgp.linked.resources.TwitterResource;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
import java.net.URI; import java.net.URI;
@@ -12,6 +12,9 @@ import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import android.content.Context;
import android.support.annotation.DrawableRes;
public abstract class LinkedResource { public abstract class LinkedResource {
protected final URI mSubUri; protected final URI mSubUri;
@@ -58,8 +61,8 @@ public abstract class LinkedResource {
String[] pieces = specific.split("@", 2); String[] pieces = specific.split("@", 2);
URI subUri = URI.create(pieces[1]); URI subUri = URI.create(pieces[1]);
Set<String> flags = new HashSet<String>(); Set<String> flags = new HashSet<>();
HashMap<String,String> params = new HashMap<String,String>(); HashMap<String,String> params = new HashMap<>();
if (!pieces[0].isEmpty()) { if (!pieces[0].isEmpty()) {
String[] rawParams = pieces[0].split(";"); String[] rawParams = pieces[0].split(";");
for (String param : rawParams) { for (String param : rawParams) {
@@ -90,9 +93,17 @@ public abstract class LinkedResource {
if (res != null) { if (res != null) {
return res; return res;
} }
res = TwitterResource.create(flags, params, subUri);
if (res != null) {
return res;
}
return null; return null;
} }
public abstract @DrawableRes int getDisplayIcon();
public abstract String getDisplayTitle(Context context);
public abstract String getDisplayComment(Context context);
} }

View File

@@ -1,11 +1,15 @@
package org.sufficientlysecure.keychain.pgp.linked; package org.sufficientlysecure.keychain.pgp.linked;
import org.spongycastle.util.Strings; import org.spongycastle.util.Strings;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute; import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute;
import java.net.URI; import java.net.URI;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import android.content.Context;
import android.support.annotation.DrawableRes;
/** The RawLinkedIdentity contains raw parsed data from a Linked Identity subpacket. */ /** The RawLinkedIdentity contains raw parsed data from a Linked Identity subpacket. */
public class RawLinkedIdentity { public class RawLinkedIdentity {
@@ -42,4 +46,16 @@ public class RawLinkedIdentity {
return 1234567; return 1234567;
} }
public @DrawableRes int getDisplayIcon() {
return R.drawable.ic_warning_grey_24dp;
}
public String getDisplayTitle(Context context) {
return "unknown";
}
public String getDisplayComment(Context context) {
return null;
}
} }

View File

@@ -1,7 +1,9 @@
package org.sufficientlysecure.keychain.pgp.linked.resources; package org.sufficientlysecure.keychain.pgp.linked.resources;
import android.content.Context; import android.content.Context;
import android.support.annotation.DrawableRes;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
import org.sufficientlysecure.keychain.pgp.linked.LinkedCookieResource; import org.sufficientlysecure.keychain.pgp.linked.LinkedCookieResource;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
@@ -100,4 +102,19 @@ public class DnsResource extends LinkedCookieResource {
protected Matcher matchResource(OperationLog log, int indent, String res) { protected Matcher matchResource(OperationLog log, int indent, String res) {
return magicPattern.matcher(res); return magicPattern.matcher(res);
} }
@Override
public @DrawableRes int getDisplayIcon() {
return R.drawable.dns;
}
@Override
public String getDisplayTitle(Context context) {
return "dns";
}
@Override
public String getDisplayComment(Context context) {
return null;
}
} }

View File

@@ -1,6 +1,7 @@
package org.sufficientlysecure.keychain.pgp.linked.resources; package org.sufficientlysecure.keychain.pgp.linked.resources;
import android.content.Context; import android.content.Context;
import android.support.annotation.DrawableRes;
import com.textuality.keybase.lib.Search; import com.textuality.keybase.lib.Search;
@@ -100,4 +101,20 @@ public class GenericHttpsResource extends LinkedCookieResource {
return new GenericHttpsResource(flags, params, uri); return new GenericHttpsResource(flags, params, uri);
} }
@Override
public @DrawableRes
int getDisplayIcon() {
return R.drawable.ssl_lock;
}
@Override
public String getDisplayTitle(Context context) {
return "https";
}
@Override
public String getDisplayComment(Context context) {
return null;
}
} }

View File

@@ -1,6 +1,7 @@
package org.sufficientlysecure.keychain.pgp.linked.resources; package org.sufficientlysecure.keychain.pgp.linked.resources;
import android.content.Context; import android.content.Context;
import android.support.annotation.DrawableRes;
import android.util.Base64; import android.util.Base64;
import com.textuality.keybase.lib.JWalk; import com.textuality.keybase.lib.JWalk;
@@ -16,6 +17,7 @@ import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams; import org.apache.http.params.BasicHttpParams;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
import org.sufficientlysecure.keychain.pgp.linked.LinkedCookieResource; import org.sufficientlysecure.keychain.pgp.linked.LinkedCookieResource;
@@ -121,4 +123,22 @@ public class TwitterResource extends LinkedCookieResource {
return getTwitterStream("Valodim"); return getTwitterStream("Valodim");
} }
@Override
public @DrawableRes int getDisplayIcon() {
return R.drawable.twitter;
}
@Override
public String getDisplayTitle(Context context) {
return "twitter";
}
@Override
public String getDisplayComment(Context context) {
return null;
}
public static LinkedCookieResource create(Set<String> flags, HashMap<String, String> params, URI subUri) {
return null;
}
} }

View File

@@ -1,21 +0,0 @@
package org.sufficientlysecure.keychain.pgp.linked.resources;
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
import org.sufficientlysecure.keychain.pgp.linked.LinkedCookieResource;
import java.net.URI;
import java.util.HashMap;
import java.util.Set;
public class UnknownResource extends LinkedCookieResource {
public UnknownResource(Set<String> flags, HashMap<String,String> params, URI uri) {
super(flags, params, uri);
}
@Override
protected String fetchResource(OperationLog log, int indent) {
return null;
}
}

View File

@@ -89,8 +89,6 @@ public class ViewKeyFragment extends LoaderFragment implements
mLinkedIdsCard = (CardView) view.findViewById(R.id.card_linked_ids); mLinkedIdsCard = (CardView) view.findViewById(R.id.card_linked_ids);
mLinkedIds = (ListView) view.findViewById(R.id.view_key_linked_ids); mLinkedIds = (ListView) view.findViewById(R.id.view_key_linked_ids);
mLinkedIdsAdapter = new LinkedIdsAdapter(getActivity(), null, 0);
mLinkedIds.setAdapter(mLinkedIdsAdapter);
mUserIds.setOnItemClickListener(new AdapterView.OnItemClickListener() { mUserIds.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override @Override
@@ -171,7 +169,6 @@ public class ViewKeyFragment extends LoaderFragment implements
Log.i(Constants.TAG, "mDataUri: " + mDataUri); Log.i(Constants.TAG, "mDataUri: " + mDataUri);
getLoaderManager().initLoader(LOADER_ID_UNIFIED, null, this); getLoaderManager().initLoader(LOADER_ID_UNIFIED, null, this);
getLoaderManager().initLoader(LOADER_ID_LINKED_IDS, null, this);
} }
public Loader<Cursor> onCreateLoader(int id, Bundle args) { public Loader<Cursor> onCreateLoader(int id, Bundle args) {
@@ -211,6 +208,10 @@ public class ViewKeyFragment extends LoaderFragment implements
mUserIds.setAdapter(mUserIdsAdapter); mUserIds.setAdapter(mUserIdsAdapter);
getLoaderManager().initLoader(LOADER_ID_USER_IDS, null, this); getLoaderManager().initLoader(LOADER_ID_USER_IDS, null, this);
mLinkedIdsAdapter = new LinkedIdsAdapter(getActivity(), null, 0, !mIsSecret);
mLinkedIds.setAdapter(mLinkedIdsAdapter);
getLoaderManager().initLoader(LOADER_ID_LINKED_IDS, null, this);
break; break;
} }
} }

View File

@@ -34,9 +34,7 @@ import android.widget.TextView;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.pgp.linked.LinkedIdentity; import org.sufficientlysecure.keychain.pgp.linked.LinkedIdentity;
import org.sufficientlysecure.keychain.pgp.linked.LinkedResource;
import org.sufficientlysecure.keychain.pgp.linked.RawLinkedIdentity; import org.sufficientlysecure.keychain.pgp.linked.RawLinkedIdentity;
import org.sufficientlysecure.keychain.pgp.linked.resources.DnsResource;
import org.sufficientlysecure.keychain.provider.KeychainContract.Certs; import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets; import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets;
import org.sufficientlysecure.keychain.ui.linked.LinkedIdViewFragment; import org.sufficientlysecure.keychain.ui.linked.LinkedIdViewFragment;
@@ -48,59 +46,45 @@ import java.util.WeakHashMap;
public class LinkedIdsAdapter extends UserAttributesAdapter { public class LinkedIdsAdapter extends UserAttributesAdapter {
private final boolean mShowCertification;
protected LayoutInflater mInflater; protected LayoutInflater mInflater;
WeakHashMap<Integer,RawLinkedIdentity> mLinkedIdentityCache = new WeakHashMap<>(); WeakHashMap<Integer,RawLinkedIdentity> mLinkedIdentityCache = new WeakHashMap<>();
public LinkedIdsAdapter(Context context, Cursor c, int flags) { public LinkedIdsAdapter(Context context, Cursor c, int flags, boolean showCertification) {
super(context, c, flags); super(context, c, flags);
mInflater = LayoutInflater.from(context); mInflater = LayoutInflater.from(context);
mShowCertification = showCertification;
} }
@Override @Override
public void bindView(View view, Context context, Cursor cursor) { public void bindView(View view, Context context, Cursor cursor) {
RawLinkedIdentity id = getItem(cursor.getPosition());
ViewHolder holder = (ViewHolder) view.getTag(); ViewHolder holder = (ViewHolder) view.getTag();
int isVerified = cursor.getInt(INDEX_VERIFIED); if (mShowCertification) {
switch (isVerified) { holder.vVerified.setVisibility(View.VISIBLE);
case Certs.VERIFIED_SECRET: int isVerified = cursor.getInt(INDEX_VERIFIED);
KeyFormattingUtils.setStatusImage(mContext, holder.vVerified, switch (isVerified) {
null, State.VERIFIED, KeyFormattingUtils.DEFAULT_COLOR); case Certs.VERIFIED_SECRET:
break; KeyFormattingUtils.setStatusImage(mContext, holder.vVerified,
case Certs.VERIFIED_SELF: null, State.VERIFIED, KeyFormattingUtils.DEFAULT_COLOR);
KeyFormattingUtils.setStatusImage(mContext, holder.vVerified, break;
null, State.UNVERIFIED, KeyFormattingUtils.DEFAULT_COLOR); case Certs.VERIFIED_SELF:
break; KeyFormattingUtils.setStatusImage(mContext, holder.vVerified,
default: null, State.UNVERIFIED, KeyFormattingUtils.DEFAULT_COLOR);
KeyFormattingUtils.setStatusImage(mContext, holder.vVerified, break;
null, State.INVALID, KeyFormattingUtils.DEFAULT_COLOR); default:
break; KeyFormattingUtils.setStatusImage(mContext, holder.vVerified,
} null, State.INVALID, KeyFormattingUtils.DEFAULT_COLOR);
break;
if (holder instanceof ViewHolderNonRaw) {
((ViewHolderNonRaw) holder).setData(mContext, (LinkedIdentity) id);
}
}
@Override
public int getItemViewType(int position) {
RawLinkedIdentity id = getItem(position);
if (id instanceof LinkedIdentity) {
LinkedResource res = ((LinkedIdentity) id).mResource;
if (res instanceof DnsResource) {
return 1;
} }
} else {
holder.vVerified.setVisibility(View.GONE);
} }
return 0; RawLinkedIdentity id = getItem(cursor.getPosition());
} holder.setData(mContext, id);
@Override
public int getViewTypeCount() {
return 2;
} }
@Override @Override
@@ -126,23 +110,10 @@ public class LinkedIdsAdapter extends UserAttributesAdapter {
@Override @Override
public View newView(Context context, Cursor cursor, ViewGroup parent) { public View newView(Context context, Cursor cursor, ViewGroup parent) {
int type = getItemViewType(cursor.getPosition()); View v = mInflater.inflate(R.layout.linked_id_item, null);
switch(type) { ViewHolder holder = new ViewHolder(v);
case 0: { v.setTag(holder);
View v = mInflater.inflate(R.layout.linked_id_item_unknown, null); return v;
ViewHolder holder = new ViewHolder(v);
v.setTag(holder);
return v;
}
case 1: {
View v = mInflater.inflate(R.layout.linked_id_item_dns, null);
ViewHolder holder = new ViewHolderDns(v);
v.setTag(holder);
return v;
}
default:
throw new AssertionError("all cases must be covered in LinkedIdsAdapter.newView!");
}
} }
// don't show revoked user ids, irrelevant for average users // don't show revoked user ids, irrelevant for average users
@@ -162,35 +133,32 @@ public class LinkedIdsAdapter extends UserAttributesAdapter {
static class ViewHolder { static class ViewHolder {
ImageView vVerified; ImageView vVerified;
ImageView vIcon;
TextView vTitle;
TextView vComment;
ViewHolder(View view) { ViewHolder(View view) {
vVerified = (ImageView) view.findViewById(R.id.user_id_item_certified); vVerified = (ImageView) view.findViewById(R.id.user_id_item_certified);
} vIcon = (ImageView) view.findViewById(R.id.linked_id_type_icon);
} vTitle = (TextView) view.findViewById(R.id.linked_id_title);
vComment = (TextView) view.findViewById(R.id.linked_id_comment);
static abstract class ViewHolderNonRaw extends ViewHolder {
ViewHolderNonRaw(View view) {
super(view);
} }
abstract void setData(Context context, LinkedIdentity id); void setData(Context context, RawLinkedIdentity id) {
}
static class ViewHolderDns extends ViewHolderNonRaw { vTitle.setText(id.getDisplayTitle(context));
TextView vFqdn;
ViewHolderDns(View view) { String comment = id.getDisplayComment(context);
super(view); if (comment != null) {
vComment.setVisibility(View.VISIBLE);
vComment.setText(comment);
} else {
vComment.setVisibility(View.GONE);
}
vIcon.setImageResource(id.getDisplayIcon());
vFqdn = (TextView) view.findViewById(R.id.linked_id_dns_fqdn);
} }
@Override
void setData(Context context, LinkedIdentity id) {
DnsResource res = (DnsResource) id.mResource;
vFqdn.setText(res.getFqdn());
}
} }
@Override @Override
@@ -198,4 +166,5 @@ public class LinkedIdsAdapter extends UserAttributesAdapter {
mLinkedIdentityCache.clear(); mLinkedIdentityCache.clear();
super.notifyDataSetChanged(); super.notifyDataSetChanged();
} }
} }

View File

@@ -7,7 +7,7 @@
android:singleLine="true"> android:singleLine="true">
<ImageView <ImageView
android:layout_width="wrap_content" android:layout_width="32dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/linked_id_type_icon" android:id="@+id/linked_id_type_icon"
android:layout_marginLeft="14dp" android:layout_marginLeft="14dp"
@@ -26,14 +26,14 @@
android:layout_weight="1"> android:layout_weight="1">
<TextView <TextView
android:id="@+id/linked_id_dns_fqdn" android:id="@+id/linked_id_title"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="www.example.com" android:text="Title"
android:textAppearance="?android:attr/textAppearanceMedium" /> android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView <TextView
android:id="@+id/user_id_item_comment" android:id="@+id/linked_id_comment"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="@color/tertiary_text_light" android:textColor="@color/tertiary_text_light"

View File

@@ -37,8 +37,8 @@
android:id="@+id/user_id_item_certified_layout" android:id="@+id/user_id_item_certified_layout"
android:layout_width="22dp" android:layout_width="22dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginRight="8dp" android:layout_marginRight="12dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="12dp"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:orientation="vertical"> android:orientation="vertical">