diff options
author | Jim Miller <jaggies@google.com> | 2012-06-18 19:23:39 -0700 |
---|---|---|
committer | Jim Miller <jaggies@google.com> | 2012-06-19 15:00:13 -0700 |
commit | 45308b1b3b1582d048845df2ee5301241e52a5cf (patch) | |
tree | 42befbc7aa70ffd9eea09fe3ba29681b84b437a4 | |
parent | c2585467107995f3130872eb7b721f3dbbcdf505 (diff) | |
download | frameworks_base-45308b1b3b1582d048845df2ee5301241e52a5cf.zip frameworks_base-45308b1b3b1582d048845df2ee5301241e52a5cf.tar.gz frameworks_base-45308b1b3b1582d048845df2ee5301241e52a5cf.tar.bz2 |
Fix 6667238: allow market apps to support ACTION_ASSIST
This change allows market apps and 3rd parties to supply an activity
that responds to ACTION_ASSIST (e.g. market apps).
It also adds a test app to respond to the ASSIST intent and force
the intent disambiguation dialog to appear.
Change-Id: I5a78863c6a9546d18c66275187d178f6a1c9ee17
17 files changed, 254 insertions, 116 deletions
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java index e8bd546..d1d5131 100644 --- a/core/java/android/app/SearchManager.java +++ b/core/java/android/app/SearchManager.java @@ -840,29 +840,17 @@ public class SearchManager } /** - * Returns true if the global assist activity is available. - * @return True if the assistant is available. - * - * @hide - */ - public final boolean isAssistantAvailable() { - Intent intent = getAssistIntent(); - return intent != null - && mContext.getPackageManager().queryIntentActivities(intent, - PackageManager.MATCH_DEFAULT_ONLY).size() > 0; - } - - /** - * Gets an intent to launch the global assist activity, or null if not available. + * Gets an intent for launching installed assistant activity, or null if not available. * @return The assist intent. * * @hide */ - public final Intent getAssistIntent() { - ComponentName globalSearchActivity = getGlobalSearchActivity(); - if (globalSearchActivity != null) { - Intent intent = new Intent(Intent.ACTION_ASSIST); - intent.setPackage(globalSearchActivity.getPackageName()); + public static final Intent getAssistIntent(Context context) { + PackageManager pm = context.getPackageManager(); + Intent intent = new Intent(Intent.ACTION_ASSIST); + ComponentName component = intent.resolveActivity(pm); + if (component != null) { + intent.setComponent(component); return intent; } return null; diff --git a/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java b/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java index adea586..fc44878 100644 --- a/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java +++ b/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java @@ -29,7 +29,6 @@ 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; @@ -1209,25 +1208,32 @@ public class GlowPadView extends View { 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); + boolean replaced = false; + if (component != null) { + 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); + replaced = 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); } - } 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; + if (!replaced) { + // Restore the original drawable + replaceTargetDrawables(mContext.getResources(), existingResId, existingResId); + } + return replaced; } } diff --git a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java index acab41e..475fb6d 100644 --- a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java @@ -53,7 +53,6 @@ public class SearchPanelView extends FrameLayout implements private static final String ASSIST_ICON_METADATA_NAME = "com.android.systemui.action_assist_icon"; private final Context mContext; - private final SearchManager mSearchManager; private BaseStatusBar mBar; private StatusBarTouchProxy mStatusBarTouchProxy; @@ -68,25 +67,13 @@ public class SearchPanelView extends FrameLayout implements public SearchPanelView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); mContext = context; - mSearchManager = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE); - if (mSearchManager == null) { - Slog.w(TAG, "Search manager not available"); - } - } - - public boolean isAssistantAvailable() { - return mSearchManager != null && mSearchManager.isAssistantAvailable(); - } - - private Intent getAssistIntent() { - return mSearchManager != null ? mSearchManager.getAssistIntent() : null; } private void startAssistActivity() { // Close Recent Apps if needed mBar.animateCollapse(CommandQueue.FLAG_EXCLUDE_SEARCH_PANEL); // Launch Assist - Intent intent = getAssistIntent(); + Intent intent = SearchManager.getAssistIntent(mContext); if (intent == null) return; try { ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext, @@ -150,19 +137,17 @@ public class SearchPanelView extends FrameLayout implements // TODO: fetch views mGlowPadView = (GlowPadView) findViewById(R.id.glow_pad_view); mGlowPadView.setOnTriggerListener(mGlowPadViewListener); - if (mSearchManager != null) { - ComponentName component = mSearchManager.getGlobalSearchActivity(); - if (component != null) { - if (!mGlowPadView.replaceTargetDrawablesIfPresent(component, - ASSIST_ICON_METADATA_NAME, - com.android.internal.R.drawable.ic_action_assist_generic)) { - Slog.w(TAG, "Couldn't grab icon from component " + component); - } - } else { - Slog.w(TAG, "No search icon specified in component " + component); + } + + private void maybeSwapSearchIcon() { + Intent intent = SearchManager.getAssistIntent(mContext); + if (intent != null) { + ComponentName component = intent.getComponent(); + if (component == null || !mGlowPadView.replaceTargetDrawablesIfPresent(component, + ASSIST_ICON_METADATA_NAME, + com.android.internal.R.drawable.ic_action_assist_generic)) { + if (DEBUG) Slog.v(TAG, "Couldn't grab icon for component " + component); } - } else { - Slog.w(TAG, "No SearchManager"); } } @@ -210,6 +195,7 @@ public class SearchPanelView extends FrameLayout implements } mShowing = show; if (show) { + maybeSwapSearchIcon(); if (getVisibility() != View.VISIBLE) { setVisibility(View.VISIBLE); // Don't start the animation until we've created the layer, which is done @@ -289,4 +275,8 @@ public class SearchPanelView extends FrameLayout implements transitioner.setAnimator(LayoutTransition.DISAPPEARING, null); return transitioner; } + + public boolean isAssistantAvailable() { + return SearchManager.getAssistIntent(mContext) != null; + } } diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java index 33dda09..ec954fe 100644 --- a/policy/src/com/android/internal/policy/impl/LockScreen.java +++ b/policy/src/com/android/internal/policy/impl/LockScreen.java @@ -83,7 +83,6 @@ class LockScreen extends LinearLayout implements KeyguardScreen { private View mUnlockWidget; private boolean mCameraDisabled; private boolean mSearchDisabled; - private SearchManager mSearchManager; // Is there a vibrator private final boolean mHasVibrator; @@ -253,23 +252,6 @@ class LockScreen extends LinearLayout implements KeyguardScreen { } } - private boolean isAssistantAvailable() { - SearchManager searchManager = getSearchManager(); - return searchManager != null && searchManager.isAssistantAvailable(); - } - - private Intent getAssistIntent() { - SearchManager searchManager = getSearchManager(); - return searchManager != null ? searchManager.getAssistIntent() : null; - } - - private SearchManager getSearchManager() { - if (mSearchManager == null) { - mSearchManager = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE); - } - return mSearchManager; - } - class GlowPadViewMethods implements GlowPadView.OnTriggerListener, UnlockWidgetCommonMethods { private final GlowPadView mGlowPadView; @@ -297,27 +279,21 @@ class LockScreen extends LinearLayout implements KeyguardScreen { // 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) { - // XXX Hack. We need to substitute the icon here but haven't formalized - // the public API. The "_google" metadata will be going away, so - // DON'T USE IT! - boolean replaced = mGlowPadView.replaceTargetDrawablesIfPresent(component, - ASSIST_ICON_METADATA_NAME + "_google", - com.android.internal.R.drawable.ic_action_assist_generic); - - if (!replaced && !mGlowPadView.replaceTargetDrawablesIfPresent(component, - ASSIST_ICON_METADATA_NAME, - com.android.internal.R.drawable.ic_action_assist_generic)) { - Slog.w(TAG, "Couldn't grab icon from package " + component); - } - } else { - Slog.w(TAG, "No search icon specified in package " + component); + Intent intent = SearchManager.getAssistIntent(mContext); + if (intent != null) { + // XXX Hack. We need to substitute the icon here but haven't formalized + // the public API. The "_google" metadata will be going away, so + // DON'T USE IT! + ComponentName component = intent.getComponent(); + boolean replaced = mGlowPadView.replaceTargetDrawablesIfPresent(component, + ASSIST_ICON_METADATA_NAME + "_google", + com.android.internal.R.drawable.ic_action_assist_generic); + + if (!replaced && !mGlowPadView.replaceTargetDrawablesIfPresent(component, + ASSIST_ICON_METADATA_NAME, + com.android.internal.R.drawable.ic_action_assist_generic)) { + Slog.w(TAG, "Couldn't grab icon from package " + component); } - } else { - Slog.w(TAG, "No SearchManager"); } } @@ -337,7 +313,7 @@ class LockScreen extends LinearLayout implements KeyguardScreen { final int resId = mGlowPadView.getResourceIdForTarget(target); switch (resId) { case com.android.internal.R.drawable.ic_action_assist_generic: - Intent assistIntent = getAssistIntent(); + Intent assistIntent = SearchManager.getAssistIntent(mContext); if (assistIntent != null) { launchActivity(assistIntent); } else { @@ -550,7 +526,7 @@ class LockScreen extends LinearLayout implements KeyguardScreen { } else if (disabledBySimState) { Log.v(TAG, "Camera disabled by Sim State"); } - boolean searchActionAvailable = isAssistantAvailable(); + boolean searchActionAvailable = SearchManager.getAssistIntent(mContext) != null; mCameraDisabled = disabledByAdmin || disabledBySimState || !cameraTargetPresent; mSearchDisabled = disabledBySimState || !searchActionAvailable || !searchTargetPresent; mUnlockWidgetMethods.updateResources(); diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index 35f71ec..4785abd 100755 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -2081,6 +2081,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { Intent intent = new Intent(Intent.ACTION_SEARCH_LONG_PRESS); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); try { + // TODO: This only stops the factory-installed search manager. + // Need to formalize an API to handle others SearchManager searchManager = getSearchManager(); if (searchManager != null) { searchManager.stopSearch(); @@ -2093,19 +2095,15 @@ public class PhoneWindowManager implements WindowManagerPolicy { private void launchAssistAction() { sendCloseSystemWindows(SYSTEM_DIALOG_REASON_ASSIST); - - SearchManager searchManager = getSearchManager(); - if (searchManager != null) { - Intent intent = searchManager.getAssistIntent(); - if (intent != null) { - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK - | Intent.FLAG_ACTIVITY_SINGLE_TOP - | Intent.FLAG_ACTIVITY_CLEAR_TOP); - try { - mContext.startActivity(intent); - } catch (ActivityNotFoundException e) { - Slog.w(TAG, "No activity to handle assist action.", e); - } + Intent intent = SearchManager.getAssistIntent(mContext); + if (intent != null) { + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_SINGLE_TOP + | Intent.FLAG_ACTIVITY_CLEAR_TOP); + try { + mContext.startActivity(intent); + } catch (ActivityNotFoundException e) { + Slog.w(TAG, "No activity to handle assist action.", e); } } } diff --git a/tests/Assistant/Android.mk b/tests/Assistant/Android.mk new file mode 100644 index 0000000..bf8cc29 --- /dev/null +++ b/tests/Assistant/Android.mk @@ -0,0 +1,11 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := Assistant + +LOCAL_MODULE_TAGS := tests +LOCAL_CERTIFICATE := platform + +include $(BUILD_PACKAGE) diff --git a/tests/Assistant/AndroidManifest.xml b/tests/Assistant/AndroidManifest.xml new file mode 100644 index 0000000..b5d4d51 --- /dev/null +++ b/tests/Assistant/AndroidManifest.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2008 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.google.android.test.assistant"> + + <application android:label="@string/activity_title"> + + <activity android:name=".AssistActivity" + android:theme="@android:style/Theme.NoTitleBar"> + + <!-- Handle assist intent --> + <intent-filter> + <action android:name="android.intent.action.ASSIST" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + + <!-- Provide icon for search --> + <meta-data android:name="com.android.systemui.action_assist_icon" + android:resource="@drawable/ic_action_assist" /> + + </activity> + + </application> + +</manifest> diff --git a/tests/Assistant/res/drawable-hdpi/ic_action_assist_activated.png b/tests/Assistant/res/drawable-hdpi/ic_action_assist_activated.png Binary files differnew file mode 100644 index 0000000..cea8ac4 --- /dev/null +++ b/tests/Assistant/res/drawable-hdpi/ic_action_assist_activated.png diff --git a/tests/Assistant/res/drawable-hdpi/ic_action_assist_normal.png b/tests/Assistant/res/drawable-hdpi/ic_action_assist_normal.png Binary files differnew file mode 100644 index 0000000..bb7702d --- /dev/null +++ b/tests/Assistant/res/drawable-hdpi/ic_action_assist_normal.png diff --git a/tests/Assistant/res/drawable-mdpi/ic_action_assist_activated.png b/tests/Assistant/res/drawable-mdpi/ic_action_assist_activated.png Binary files differnew file mode 100644 index 0000000..5841d82 --- /dev/null +++ b/tests/Assistant/res/drawable-mdpi/ic_action_assist_activated.png diff --git a/tests/Assistant/res/drawable-mdpi/ic_action_assist_normal.png b/tests/Assistant/res/drawable-mdpi/ic_action_assist_normal.png Binary files differnew file mode 100644 index 0000000..3851f03 --- /dev/null +++ b/tests/Assistant/res/drawable-mdpi/ic_action_assist_normal.png diff --git a/tests/Assistant/res/drawable-xhdpi/ic_action_assist_activated.png b/tests/Assistant/res/drawable-xhdpi/ic_action_assist_activated.png Binary files differnew file mode 100644 index 0000000..778db19 --- /dev/null +++ b/tests/Assistant/res/drawable-xhdpi/ic_action_assist_activated.png diff --git a/tests/Assistant/res/drawable-xhdpi/ic_action_assist_normal.png b/tests/Assistant/res/drawable-xhdpi/ic_action_assist_normal.png Binary files differnew file mode 100644 index 0000000..ad49125 --- /dev/null +++ b/tests/Assistant/res/drawable-xhdpi/ic_action_assist_normal.png diff --git a/tests/Assistant/res/drawable/ic_action_assist.xml b/tests/Assistant/res/drawable/ic_action_assist.xml new file mode 100644 index 0000000..05c4bf5 --- /dev/null +++ b/tests/Assistant/res/drawable/ic_action_assist.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2012 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<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_activated" /> + +</selector> diff --git a/tests/Assistant/res/layout/assist_intent_activity.xml b/tests/Assistant/res/layout/assist_intent_activity.xml new file mode 100644 index 0000000..49785bc --- /dev/null +++ b/tests/Assistant/res/layout/assist_intent_activity.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +** +** Copyright 2009, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License") +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<!-- This is the general lock screen which shows information about the + state of the device, as well as instructions on how to get past it + depending on the state of the device. It is the same for landscape + and portrait.--> +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="center"> + + <TextView android:id="@+id/label" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/search_label" + /> + + <EditText android:id="@+id/search_input" + android:layout_width="match_parent" + android:layout_height="wrap_content" + /> + +</LinearLayout> + diff --git a/tests/Assistant/res/values/strings.xml b/tests/Assistant/res/values/strings.xml new file mode 100644 index 0000000..a59c1ef --- /dev/null +++ b/tests/Assistant/res/values/strings.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2007 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<resources> + <string name="activity_title">Assistant</string> + <string name="search_label">Orilla Search Engine</string> +</resources> diff --git a/tests/Assistant/src/com/google/android/test/assistant/AssistActivity.java b/tests/Assistant/src/com/google/android/test/assistant/AssistActivity.java new file mode 100644 index 0000000..51894a1 --- /dev/null +++ b/tests/Assistant/src/com/google/android/test/assistant/AssistActivity.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.android.test.assistant; + +import android.app.Activity; +import android.os.Bundle; +import com.google.android.test.assistant.R; + +public class AssistActivity extends Activity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.assist_intent_activity); + } + +} |