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 276598f4b..0b4100de1 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java @@ -145,6 +145,7 @@ public class KeychainContract { public static final String HAS_CERTIFY = "has_certify"; public static final String HAS_AUTHENTICATE = "has_authenticate"; 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() .appendPath(BASE_KEY_RINGS).build(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java index fc7c93eea..99b583ed2 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -342,6 +342,9 @@ public class KeychainProvider extends ContentProvider { projectionMap.put(KeyRings.IS_EXPIRED, "(" + Tables.KEYS + "." + Keys.EXPIRY + " IS NOT NULL AND " + Tables.KEYS + "." + Keys.EXPIRY + " < " + 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); if (projection == null) { @@ -410,6 +413,11 @@ public class KeychainProvider extends ContentProvider { + " AND ( kC." + Keys.EXPIRY + " IS NULL OR kC." + Keys.EXPIRY + " >= " + 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"); // in case there are multiple verifying certificates diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeySectionedListAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeySectionedListAdapter.java index da7612143..1c5f266b0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeySectionedListAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeySectionedListAdapter.java @@ -19,10 +19,13 @@ package org.sufficientlysecure.keychain.ui.adapter; import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; import android.database.Cursor; import android.database.MatrixCursor; import android.database.MergeCursor; import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; import android.support.v4.content.ContextCompat; import android.text.TextUtils; import android.text.format.DateUtils; @@ -38,6 +41,7 @@ import com.futuremind.recyclerviewfastscroll.SectionTitleProvider; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; 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.Highlighter; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; @@ -47,6 +51,8 @@ import org.sufficientlysecure.keychain.util.Log; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; import java.util.List; public class KeySectionedListAdapter extends SectionCursorAdapter 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 0; } + + public List 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 { @@ -614,4 +657,24 @@ public class KeySectionedListAdapter extends SectionCursorAdapter 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; + } + } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/adapter/CursorAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/adapter/CursorAdapter.java index 75b1c9ff0..e9fb2f035 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/adapter/CursorAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/adapter/CursorAdapter.java @@ -392,7 +392,8 @@ public abstract class CursorAdapter + android:focusable="false" + tools:layout_marginTop="30dp"> + android:paddingBottom="4dp"> + + + + + + + android:orientation="horizontal" + tools:visibility="gone"> + \ No newline at end of file