OSDN Git Service

Fix 6592932: add means to replace assist icon from given package
authorJim Miller <jaggies@google.com>
Fri, 1 Jun 2012 00:49:13 +0000 (17:49 -0700)
committerJim Miller <jaggies@google.com>
Fri, 1 Jun 2012 21:08:28 +0000 (14:08 -0700)
This provides the means to replace the assist icon shown in keyguard and the
navigation gesture for assist.  It's done by adding metadata called
"com.android.systemui.action_assist_icon" to the activity that handles
android.intent.action.ASSIST.  It should point to a StateListDrawable
in that package with the required states.  For example:

<meta-data android:name="com.android.systemui.action_assist_icon"
    android:resource="@drawable/ic_android_systemui_action_assist" />

And then something like this in drawable/ic_android_systemui_action_assist.xml :

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="true"
        android:state_active="false"
        android:state_focused="false"
        android:drawable="@drawable/ic_action_assist_normal" />
    <item android:state_enabled="true"
        android:state_active="true"
        android:state_focused="false"
        android:drawable="@drawable/ic_action_assist_activated" />
    <item android:state_enabled="true"
        android:state_active="false"
        android:state_focused="true"
        android:drawable="@drawable/ic_action_assist_focused" />
</selector>

Change-Id: Ibc29360e179fed68253ff06a07b1bb2b982d0dab

core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
core/java/com/android/internal/widget/multiwaveview/TargetDrawable.java
core/res/res/drawable/ic_lockscreen_search.xml
packages/SystemUI/src/com/android/systemui/SearchPanelView.java
policy/src/com/android/internal/policy/impl/LockScreen.java

index b2c3091..89dbd1b 100644 (file)
@@ -23,12 +23,16 @@ import android.animation.ObjectAnimator;
 import android.animation.TimeInterpolator;
 import android.animation.ValueAnimator;
 import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
 import android.graphics.RectF;
 import android.graphics.drawable.Drawable;
+import android.os.Bundle;
 import android.os.Vibrator;
 import android.text.TextUtils;
 import android.util.AttributeSet;
@@ -1233,4 +1237,62 @@ public class MultiWaveView extends View {
         }
         return -1;
     }
+
+    private boolean replaceTargetDrawables(Resources res, int existingResourceId,
+            int newResourceId) {
+        if (existingResourceId == 0 || newResourceId == 0) {
+            return false;
+        }
+
+        boolean result = false;
+        final ArrayList<TargetDrawable> drawables = mTargetDrawables;
+        final int size = drawables.size();
+        for (int i = 0; i < size; i++) {
+            final TargetDrawable target = drawables.get(i);
+            if (target != null && target.getResourceId() == existingResourceId) {
+                target.setDrawable(res, newResourceId);
+                result = true;
+            }
+        }
+
+        if (result) {
+            requestLayout(); // in case any given drawable's size changes
+        }
+
+        return result;
+    }
+
+    /**
+     * Searches the given package for a resource to use to replace the Drawable on the
+     * target with the given resource id
+     * @param component of the .apk that contains the resource
+     * @param name of the metadata in the .apk
+     * @param existingResId the resource id of the target to search for
+     * @return true if found in the given package and replaced at least one target Drawables
+     */
+    public boolean replaceTargetDrawablesIfPresent(ComponentName component, String name,
+                int existingResId) {
+        if (existingResId == 0) return false;
+
+        try {
+            PackageManager packageManager = mContext.getPackageManager();
+            // Look for the search icon specified in the activity meta-data
+            Bundle metaData = packageManager.getActivityInfo(
+                    component, PackageManager.GET_META_DATA).metaData;
+            if (metaData != null) {
+                int iconResId = metaData.getInt(name);
+                if (iconResId != 0) {
+                    Resources res = packageManager.getResourcesForActivity(component);
+                    return replaceTargetDrawables(res, existingResId, iconResId);
+                }
+            }
+        } catch (NameNotFoundException e) {
+            Log.w(TAG, "Failed to swap drawable; "
+                    + component.flattenToShortString() + " not found", e);
+        } catch (Resources.NotFoundException nfe) {
+            Log.w(TAG, "Failed to swap drawable from "
+                    + component.flattenToShortString(), nfe);
+        }
+        return false;
+    }
 }
index 6392093..30f5f2f 100644 (file)
@@ -44,7 +44,7 @@ public class TargetDrawable {
     private float mAlpha = 1.0f;
     private Drawable mDrawable;
     private boolean mEnabled = true;
-    private int mResourceId;
+    private final int mResourceId;
 
     /* package */ static class DrawableWithAlpha extends Drawable {
         private float mAlpha = 1.0f;
@@ -78,6 +78,12 @@ public class TargetDrawable {
 
     public TargetDrawable(Resources res, int resId) {
         mResourceId = resId;
+        setDrawable(res, resId);
+    }
+
+    public void setDrawable(Resources res, int resId) {
+        // Note we explicitly don't set mResourceId to resId since we allow the drawable to be
+        // swapped at runtime and want to re-use the existing resource id for identification.
         Drawable drawable = resId == 0 ? null : res.getDrawable(resId);
         // Mutate the drawable so we can animate shared drawable properties.
         mDrawable = drawable != null ? drawable.mutate() : null;
index 4040153..d7a5b00 100644 (file)
@@ -31,6 +31,6 @@
         android:state_enabled="true"
         android:state_active="false"
         android:state_focused="true"
-        android:drawable="@drawable/ic_lockscreen_google_activated" />
+        android:drawable="@drawable/ic_lockscreen_google_focused" />
 
 </selector>
index af88a06..1cd8d50 100644 (file)
@@ -50,6 +50,8 @@ public class SearchPanelView extends FrameLayout implements
     private static final int SEARCH_PANEL_HOLD_DURATION = 500;
     static final String TAG = "SearchPanelView";
     static final boolean DEBUG = TabletStatusBar.DEBUG || PhoneStatusBar.DEBUG || false;
+    private static final String ASSIST_ICON_METADATA_NAME =
+            "com.android.systemui.action_assist_icon";
     private final Context mContext;
     private BaseStatusBar mBar;
     private StatusBarTouchProxy mStatusBarTouchProxy;
@@ -168,6 +170,21 @@ public class SearchPanelView extends FrameLayout implements
         // TODO: fetch views
         mMultiWaveView = (MultiWaveView) findViewById(R.id.multi_wave_view);
         mMultiWaveView.setOnTriggerListener(mMultiWaveViewListener);
+        SearchManager searchManager = getSearchManager();
+        if (searchManager != null) {
+            ComponentName component = searchManager.getGlobalSearchActivity();
+            if (component != null) {
+                if (!mMultiWaveView.replaceTargetDrawablesIfPresent(component,
+                        ASSIST_ICON_METADATA_NAME,
+                        com.android.internal.R.drawable.ic_lockscreen_search)) {
+                    Slog.w(TAG, "Couldn't grab icon from component " + component);
+                }
+            } else {
+                Slog.w(TAG, "No search icon specified in component " + component);
+            }
+        } else {
+            Slog.w(TAG, "No SearchManager");
+        }
     }
 
     private boolean pointInside(int x, int y, View v) {
index 30cb530..d37207c 100644 (file)
@@ -62,6 +62,8 @@ class LockScreen extends LinearLayout implements KeyguardScreen {
     private static final String ENABLE_MENU_KEY_FILE = "/data/local/enable_menu_key";
     private static final int WAIT_FOR_ANIMATION_TIMEOUT = 0;
     private static final int STAY_ON_WHILE_GRABBED_TIMEOUT = 30000;
+    private static final String ASSIST_ICON_METADATA_NAME =
+            "com.android.systemui.action_assist_icon";
 
     private LockPatternUtils mLockPatternUtils;
     private KeyguardUpdateMonitor mUpdateMonitor;
@@ -290,8 +292,6 @@ class LockScreen extends LinearLayout implements KeyguardScreen {
 
         MultiWaveViewMethods(MultiWaveView multiWaveView) {
             mMultiWaveView = multiWaveView;
-
-            // TODO: get search icon.  See Launcher.updateGlobalSearchIcon()
         }
 
         public boolean isTargetPresent(int resId) {
@@ -310,6 +310,26 @@ class LockScreen extends LinearLayout implements KeyguardScreen {
             if (mMultiWaveView.getTargetResourceId() != resId) {
                 mMultiWaveView.setTargetResources(resId);
             }
+
+            // Update the search icon with drawable from the search .apk
+            if (!mSearchDisabled) {
+                SearchManager searchManager = getSearchManager();
+                if (searchManager != null) {
+                    ComponentName component = searchManager.getGlobalSearchActivity();
+                    if (component != null) {
+                        if (!mMultiWaveView.replaceTargetDrawablesIfPresent(component,
+                                ASSIST_ICON_METADATA_NAME,
+                                com.android.internal.R.drawable.ic_lockscreen_search)) {
+                            Slog.w(TAG, "Couldn't grab icon from package " + component);
+                        }
+                    } else {
+                        Slog.w(TAG, "No search icon specified in package " + component);
+                    }
+                } else {
+                    Slog.w(TAG, "No SearchManager");
+                }
+            }
+
             setEnabled(com.android.internal.R.drawable.ic_lockscreen_camera, !mCameraDisabled);
             setEnabled(com.android.internal.R.drawable.ic_lockscreen_search, !mSearchDisabled);
         }