show trust id package icon in key list
This commit is contained in:
@@ -145,6 +145,7 @@ public class KeychainContract {
|
|||||||
public static final String HAS_CERTIFY = "has_certify";
|
public static final String HAS_CERTIFY = "has_certify";
|
||||||
public static final String HAS_AUTHENTICATE = "has_authenticate";
|
public static final String HAS_AUTHENTICATE = "has_authenticate";
|
||||||
public static final String HAS_DUPLICATE_USER_ID = "has_duplicate_user_id";
|
public static final String HAS_DUPLICATE_USER_ID = "has_duplicate_user_id";
|
||||||
|
public static final String API_KNOWN_TO_PACKAGE_NAMES = "known_to_apps";
|
||||||
|
|
||||||
public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon()
|
public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon()
|
||||||
.appendPath(BASE_KEY_RINGS).build();
|
.appendPath(BASE_KEY_RINGS).build();
|
||||||
|
|||||||
@@ -342,6 +342,9 @@ public class KeychainProvider extends ContentProvider {
|
|||||||
projectionMap.put(KeyRings.IS_EXPIRED,
|
projectionMap.put(KeyRings.IS_EXPIRED,
|
||||||
"(" + Tables.KEYS + "." + Keys.EXPIRY + " IS NOT NULL AND " + Tables.KEYS + "." + Keys.EXPIRY
|
"(" + Tables.KEYS + "." + Keys.EXPIRY + " IS NOT NULL AND " + Tables.KEYS + "." + Keys.EXPIRY
|
||||||
+ " < " + new Date().getTime() / 1000 + ") AS " + KeyRings.IS_EXPIRED);
|
+ " < " + new Date().getTime() / 1000 + ") AS " + KeyRings.IS_EXPIRED);
|
||||||
|
projectionMap.put(KeyRings.API_KNOWN_TO_PACKAGE_NAMES,
|
||||||
|
"GROUP_CONCAT(aTI." + ApiTrustIdentity.PACKAGE_NAME + ") AS "
|
||||||
|
+ KeyRings.API_KNOWN_TO_PACKAGE_NAMES);
|
||||||
qb.setProjectionMap(projectionMap);
|
qb.setProjectionMap(projectionMap);
|
||||||
|
|
||||||
if (projection == null) {
|
if (projection == null) {
|
||||||
@@ -410,6 +413,11 @@ public class KeychainProvider extends ContentProvider {
|
|||||||
+ " AND ( kC." + Keys.EXPIRY + " IS NULL OR kC." + Keys.EXPIRY
|
+ " AND ( kC." + Keys.EXPIRY + " IS NULL OR kC." + Keys.EXPIRY
|
||||||
+ " >= " + new Date().getTime() / 1000 + " )"
|
+ " >= " + new Date().getTime() / 1000 + " )"
|
||||||
+ ")" : "")
|
+ ")" : "")
|
||||||
|
+ (plist.contains(KeyRings.API_KNOWN_TO_PACKAGE_NAMES) ?
|
||||||
|
" LEFT JOIN " + Tables.API_TRUST_IDENTITIES + " AS aTI ON ("
|
||||||
|
+"aTI." + Keys.MASTER_KEY_ID
|
||||||
|
+ " = " + Tables.KEYS + "." + Keys.MASTER_KEY_ID
|
||||||
|
+ ")" : "")
|
||||||
);
|
);
|
||||||
qb.appendWhere(Tables.KEYS + "." + Keys.RANK + " = 0");
|
qb.appendWhere(Tables.KEYS + "." + Keys.RANK + " = 0");
|
||||||
// in case there are multiple verifying certificates
|
// in case there are multiple verifying certificates
|
||||||
|
|||||||
@@ -19,10 +19,13 @@
|
|||||||
package org.sufficientlysecure.keychain.ui.adapter;
|
package org.sufficientlysecure.keychain.ui.adapter;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.database.MatrixCursor;
|
import android.database.MatrixCursor;
|
||||||
import android.database.MergeCursor;
|
import android.database.MergeCursor;
|
||||||
import android.graphics.PorterDuff;
|
import android.graphics.PorterDuff;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
import android.support.v4.content.ContextCompat;
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.text.format.DateUtils;
|
import android.text.format.DateUtils;
|
||||||
@@ -38,6 +41,7 @@ import com.futuremind.recyclerviewfastscroll.SectionTitleProvider;
|
|||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
||||||
|
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||||
import org.sufficientlysecure.keychain.ui.util.FormattingUtils;
|
import org.sufficientlysecure.keychain.ui.util.FormattingUtils;
|
||||||
import org.sufficientlysecure.keychain.ui.util.Highlighter;
|
import org.sufficientlysecure.keychain.ui.util.Highlighter;
|
||||||
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
|
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
|
||||||
@@ -47,6 +51,8 @@ import org.sufficientlysecure.keychain.util.Log;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class KeySectionedListAdapter extends SectionCursorAdapter<KeySectionedListAdapter.KeyListCursor, Character,
|
public class KeySectionedListAdapter extends SectionCursorAdapter<KeySectionedListAdapter.KeyListCursor, Character,
|
||||||
@@ -348,12 +354,13 @@ public class KeySectionedListAdapter extends SectionCursorAdapter<KeySectionedLi
|
|||||||
public class KeyItemViewHolder extends SectionCursorAdapter.ViewHolder
|
public class KeyItemViewHolder extends SectionCursorAdapter.ViewHolder
|
||||||
implements View.OnClickListener, View.OnLongClickListener {
|
implements View.OnClickListener, View.OnLongClickListener {
|
||||||
|
|
||||||
private TextView mMainUserId;
|
private final ViewGroup mTrustIdIcons;
|
||||||
private TextView mMainUserIdRest;
|
private final TextView mMainUserId;
|
||||||
private TextView mCreationDate;
|
private final TextView mMainUserIdRest;
|
||||||
private ImageView mStatus;
|
private final TextView mCreationDate;
|
||||||
private View mSlinger;
|
private final ImageView mStatus;
|
||||||
private ImageButton mSlingerButton;
|
private final View mSlinger;
|
||||||
|
private final ImageButton mSlingerButton;
|
||||||
|
|
||||||
KeyItemViewHolder(View itemView) {
|
KeyItemViewHolder(View itemView) {
|
||||||
super(itemView);
|
super(itemView);
|
||||||
@@ -364,6 +371,7 @@ public class KeySectionedListAdapter extends SectionCursorAdapter<KeySectionedLi
|
|||||||
mSlinger = itemView.findViewById(R.id.key_list_item_slinger_view);
|
mSlinger = itemView.findViewById(R.id.key_list_item_slinger_view);
|
||||||
mSlingerButton = (ImageButton) itemView.findViewById(R.id.key_list_item_slinger_button);
|
mSlingerButton = (ImageButton) itemView.findViewById(R.id.key_list_item_slinger_button);
|
||||||
mCreationDate = (TextView) itemView.findViewById(R.id.key_list_item_creation);
|
mCreationDate = (TextView) itemView.findViewById(R.id.key_list_item_creation);
|
||||||
|
mTrustIdIcons = (ViewGroup) itemView.findViewById(R.id.key_list_item_tid_icon);
|
||||||
|
|
||||||
itemView.setClickable(true);
|
itemView.setClickable(true);
|
||||||
itemView.setLongClickable(true);
|
itemView.setLongClickable(true);
|
||||||
@@ -485,6 +493,31 @@ public class KeySectionedListAdapter extends SectionCursorAdapter<KeySectionedLi
|
|||||||
} else {
|
} else {
|
||||||
mCreationDate.setVisibility(View.GONE);
|
mCreationDate.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // set icons
|
||||||
|
List<String> packageNames = keyItem.getTrustIdPackages();
|
||||||
|
|
||||||
|
LayoutInflater layoutInflater = LayoutInflater.from(getContext());
|
||||||
|
while (mTrustIdIcons.getChildCount() < packageNames.size()) {
|
||||||
|
layoutInflater.inflate(R.layout.trust_id_icon, mTrustIdIcons, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
int visibleIcons = 0;
|
||||||
|
for (int i = 0; i < packageNames.size(); i++) {
|
||||||
|
ImageView imageView = (ImageView) mTrustIdIcons.getChildAt(i);
|
||||||
|
Drawable drawable = getDrawableForPackageName(packageNames.get(i));
|
||||||
|
if (drawable == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
imageView.setImageDrawable(drawable);
|
||||||
|
imageView.setVisibility(View.VISIBLE);
|
||||||
|
visibleIcons += 1;
|
||||||
|
}
|
||||||
|
for (int i = visibleIcons; i < mTrustIdIcons.getChildCount(); i++) {
|
||||||
|
mTrustIdIcons.getChildAt(i).setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -562,7 +595,8 @@ public class KeySectionedListAdapter extends SectionCursorAdapter<KeySectionedLi
|
|||||||
KeychainContract.KeyRings.VERIFIED,
|
KeychainContract.KeyRings.VERIFIED,
|
||||||
KeychainContract.KeyRings.HAS_ANY_SECRET,
|
KeychainContract.KeyRings.HAS_ANY_SECRET,
|
||||||
KeychainContract.KeyRings.FINGERPRINT,
|
KeychainContract.KeyRings.FINGERPRINT,
|
||||||
KeychainContract.KeyRings.HAS_ENCRYPT
|
KeychainContract.KeyRings.HAS_ENCRYPT,
|
||||||
|
KeychainContract.KeyRings.API_KNOWN_TO_PACKAGE_NAMES
|
||||||
));
|
));
|
||||||
|
|
||||||
PROJECTION = arr.toArray(new String[arr.size()]);
|
PROJECTION = arr.toArray(new String[arr.size()]);
|
||||||
@@ -603,6 +637,15 @@ public class KeySectionedListAdapter extends SectionCursorAdapter<KeySectionedLi
|
|||||||
int index = getColumnIndexOrThrow(KeychainContract.KeyRings.VERIFIED);
|
int index = getColumnIndexOrThrow(KeychainContract.KeyRings.VERIFIED);
|
||||||
return getInt(index) > 0;
|
return getInt(index) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<String> getTrustIdPackages() {
|
||||||
|
int index = getColumnIndexOrThrow(KeyRings.API_KNOWN_TO_PACKAGE_NAMES);
|
||||||
|
String packageNames = getString(index);
|
||||||
|
if (packageNames == null) {
|
||||||
|
return Collections.EMPTY_LIST;
|
||||||
|
}
|
||||||
|
return Arrays.asList(packageNames.split(","));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface KeyListListener {
|
public interface KeyListListener {
|
||||||
@@ -614,4 +657,24 @@ public class KeySectionedListAdapter extends SectionCursorAdapter<KeySectionedLi
|
|||||||
|
|
||||||
void onSelectionStateChanged(int selectedCount);
|
void onSelectionStateChanged(int selectedCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private HashMap<String, Drawable> appIconCache = new HashMap<>();
|
||||||
|
|
||||||
|
private Drawable getDrawableForPackageName(String packageName) {
|
||||||
|
if (appIconCache.containsKey(packageName)) {
|
||||||
|
return appIconCache.get(packageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
PackageManager pm = getContext().getPackageManager();
|
||||||
|
try {
|
||||||
|
ApplicationInfo ai = pm.getApplicationInfo(packageName, 0);
|
||||||
|
|
||||||
|
Drawable appIcon = pm.getApplicationIcon(ai);
|
||||||
|
appIconCache.put(packageName, appIcon);
|
||||||
|
|
||||||
|
return appIcon;
|
||||||
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -392,7 +392,8 @@ public abstract class CursorAdapter<C extends CursorAdapter.AbstractCursor, VH e
|
|||||||
KeychainContract.KeyRings.CREATION,
|
KeychainContract.KeyRings.CREATION,
|
||||||
KeychainContract.KeyRings.NAME,
|
KeychainContract.KeyRings.NAME,
|
||||||
KeychainContract.KeyRings.EMAIL,
|
KeychainContract.KeyRings.EMAIL,
|
||||||
KeychainContract.KeyRings.COMMENT
|
KeychainContract.KeyRings.COMMENT,
|
||||||
|
KeychainContract.KeyRings.API_KNOWN_TO_PACKAGE_NAMES
|
||||||
));
|
));
|
||||||
|
|
||||||
PROJECTION = arr.toArray(new String[arr.size()]);
|
PROJECTION = arr.toArray(new String[arr.size()]);
|
||||||
|
|||||||
@@ -11,7 +11,8 @@
|
|||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:descendantFocusability="blocksDescendants"
|
android:descendantFocusability="blocksDescendants"
|
||||||
android:background="@drawable/list_item_ripple"
|
android:background="@drawable/list_item_ripple"
|
||||||
android:focusable="false">
|
android:focusable="false"
|
||||||
|
tools:layout_marginTop="30dp">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/key_list_item_data"
|
android:id="@+id/key_list_item_data"
|
||||||
@@ -24,8 +25,7 @@
|
|||||||
android:paddingLeft="8dp"
|
android:paddingLeft="8dp"
|
||||||
android:paddingRight="4dp"
|
android:paddingRight="4dp"
|
||||||
android:paddingTop="4dp"
|
android:paddingTop="4dp"
|
||||||
android:paddingBottom="4dp"
|
android:paddingBottom="4dp">
|
||||||
tools:visibility="gone">
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/key_list_item_name"
|
android:id="@+id/key_list_item_name"
|
||||||
@@ -55,12 +55,26 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:id="@+id/key_list_item_tid_icon"
|
||||||
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<include layout="@layout/trust_id_icon" />
|
||||||
|
-->
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/key_list_item_slinger_view"
|
android:id="@+id/key_list_item_slinger_view"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="?android:attr/listPreferredItemHeight"
|
android:layout_height="?android:attr/listPreferredItemHeight"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal"
|
||||||
|
tools:visibility="gone">
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="1dip"
|
android:layout_width="1dip"
|
||||||
|
|||||||
8
OpenKeychain/src/main/res/layout/trust_id_icon.xml
Normal file
8
OpenKeychain/src/main/res/layout/trust_id_icon.xml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ImageView
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_margin="4dp"
|
||||||
|
tools:src="@drawable/apps_k9" />
|
||||||
Reference in New Issue
Block a user