diff options
author | Bjorn Bringert <bringert@android.com> | 2009-07-14 10:27:07 +0100 |
---|---|---|
committer | Bjorn Bringert <bringert@android.com> | 2009-07-14 13:52:01 +0100 |
commit | c1d82e68eb4aae1b575e82b08e71a87670cc1532 (patch) | |
tree | e9af68d63b218d62c1bc52202dabf9457fc3bfd6 /core/java/android/app/SuggestionsAdapter.java | |
parent | 3a27b29e41777e58fbcdca440a00676915ebea4f (diff) | |
download | frameworks_base-c1d82e68eb4aae1b575e82b08e71a87670cc1532.zip frameworks_base-c1d82e68eb4aae1b575e82b08e71a87670cc1532.tar.gz frameworks_base-c1d82e68eb4aae1b575e82b08e71a87670cc1532.tar.bz2 |
Use activity icon when search suggestion icon is missing
New left-hand side icon fallback logic in search dialog:
1. If the search dialog gets no icon column, it shows no
icon (like before). This would handle the case of in-app
search where the provider does not include icons.
2. If the icon column is empty, or there is an error converting
the icon id or URI to a drawable, the search dialog identifies
the suggestion source by looking at the
SUGGEST_COLUMN_INTENT_COMPONENT_NAME.
3. If SUGGEST_COLUMN_INTENT_COMPONENT_NAME is empty or not set,
the current searchable activity is considered the suggestion source.
4. Try to get the activity icon of the suggestion source.
5. Fall back to the application icon of the suggestion source
if there is no activity icon.
6. Fall back to some generic icon if there is no application icon.
Fixes http://b/issue?id=1905757
Diffstat (limited to 'core/java/android/app/SuggestionsAdapter.java')
-rw-r--r-- | core/java/android/app/SuggestionsAdapter.java | 127 |
1 files changed, 116 insertions, 11 deletions
diff --git a/core/java/android/app/SuggestionsAdapter.java b/core/java/android/app/SuggestionsAdapter.java index c8e952f..58e66b6 100644 --- a/core/java/android/app/SuggestionsAdapter.java +++ b/core/java/android/app/SuggestionsAdapter.java @@ -16,8 +16,13 @@ package android.app; +import android.app.SearchManager.DialogCursorProtocol; +import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.ColorStateList; import android.content.res.Resources; import android.database.Cursor; @@ -38,8 +43,6 @@ import android.widget.ImageView; import android.widget.ResourceCursorAdapter; import android.widget.TextView; -import static android.app.SearchManager.DialogCursorProtocol; - import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; @@ -310,19 +313,39 @@ class SuggestionsAdapter extends ResourceCursorAdapter { text2 = cursor.getString(mText2Col); } ((SuggestionItemView)view).setTextStrings(text1, text2, isHtml, mProviderContext); - setViewIcon(cursor, views.mIcon1, mIconName1Col); - setViewIcon(cursor, views.mIcon2, mIconName2Col); + if (views.mIcon1 != null) { + setViewDrawable(views.mIcon1, getIcon1(cursor)); + } + if (views.mIcon2 != null) { + setViewDrawable(views.mIcon2, getIcon2(cursor)); + } } - private void setViewIcon(Cursor cursor, ImageView v, int iconNameCol) { - if (v == null) { - return; - } - if (iconNameCol < 0) { - return; + private Drawable getIcon1(Cursor cursor) { + if (mIconName1Col < 0) { + return null; } - String value = cursor.getString(iconNameCol); + String value = cursor.getString(mIconName1Col); Drawable drawable = getDrawableFromResourceValue(value); + if (drawable != null) { + return drawable; + } + return getDefaultIcon1(cursor); + } + + private Drawable getIcon2(Cursor cursor) { + if (mIconName2Col < 0) { + return null; + } + String value = cursor.getString(mIconName2Col); + return getDrawableFromResourceValue(value); + } + + /** + * Sets the drawable in an image view, makes sure the view is only visible if there + * is a drawable. + */ + private void setViewDrawable(ImageView v, Drawable drawable) { // Set the icon even if the drawable is null, since we need to clear any // previous icon. v.setImageDrawable(drawable); @@ -474,6 +497,88 @@ class SuggestionsAdapter extends ResourceCursorAdapter { } /** + * Gets the left-hand side icon that will be used for the current suggestion + * if the suggestion contains an icon column but no icon or a broken icon. + * + * @param cursor A cursor positioned at the current suggestion. + * @return A non-null drawable. + */ + private Drawable getDefaultIcon1(Cursor cursor) { + // First check the component that the suggestion is originally from + String c = getColumnString(cursor, SearchManager.SUGGEST_COLUMN_INTENT_COMPONENT_NAME); + if (c != null) { + ComponentName component = ComponentName.unflattenFromString(c); + if (component != null) { + Drawable drawable = getActivityIconWithCache(component); + if (drawable != null) { + return drawable; + } + } else { + Log.w(LOG_TAG, "Bad component name: " + c); + } + } + + // Then check the component that gave us the suggestion + Drawable drawable = getActivityIconWithCache(mSearchable.getSearchActivity()); + if (drawable != null) { + return drawable; + } + + // Fall back to a default icon + return mContext.getPackageManager().getDefaultActivityIcon(); + } + + /** + * Gets the activity or application icon for an activity. + * Uses the local icon cache for fast repeated lookups. + * + * @param component Name of an activity. + * @return A drawable, or {@code null} if neither the activity nor the application + * has an icon set. + */ + private Drawable getActivityIconWithCache(ComponentName component) { + // First check the icon cache + String componentIconKey = component.flattenToShortString(); + // Using containsKey() since we also store null values. + if (mOutsideDrawablesCache.containsKey(componentIconKey)) { + return mOutsideDrawablesCache.get(componentIconKey); + } + // Then try the activity or application icon + Drawable drawable = getActivityIcon(component); + // Stick it in the cache so we don't do this lookup again. + mOutsideDrawablesCache.put(componentIconKey, drawable); + return drawable; + } + + /** + * Gets the activity or application icon for an activity. + * + * @param component Name of an activity. + * @return A drawable, or {@code null} if neither the acitivy or the application + * have an icon set. + */ + private Drawable getActivityIcon(ComponentName component) { + PackageManager pm = mContext.getPackageManager(); + final ActivityInfo activityInfo; + try { + activityInfo = pm.getActivityInfo(component, PackageManager.GET_META_DATA); + } catch (NameNotFoundException ex) { + Log.w(LOG_TAG, ex.toString()); + return null; + } + int iconId = activityInfo.getIconResource(); + if (iconId == 0) return null; + String pkg = component.getPackageName(); + Drawable drawable = pm.getDrawable(pkg, iconId, activityInfo.applicationInfo); + if (drawable == null) { + Log.w(LOG_TAG, "Invalid icon resource " + iconId + " for " + + component.flattenToShortString()); + return null; + } + return drawable; + } + + /** * Gets the value of a string column by name. * * @param cursor Cursor to read the value from. |