diff options
6 files changed, 101 insertions, 18 deletions
diff --git a/core/java/android/app/ISearchManager.aidl b/core/java/android/app/ISearchManager.aidl index 688cdfd..074d343 100644 --- a/core/java/android/app/ISearchManager.aidl +++ b/core/java/android/app/ISearchManager.aidl @@ -30,4 +30,5 @@ interface ISearchManager { List<ResolveInfo> getGlobalSearchActivities(); ComponentName getGlobalSearchActivity(); ComponentName getWebSearchActivity(); + ComponentName getAssistIntent(int userHandle); } diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java index d1d5131..b8c9937 100644 --- a/core/java/android/app/SearchManager.java +++ b/core/java/android/app/SearchManager.java @@ -31,6 +31,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.RemoteException; import android.os.ServiceManager; +import android.os.UserId; import android.text.TextUtils; import android.util.Log; import android.util.Slog; @@ -845,14 +846,28 @@ public class SearchManager * * @hide */ - 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); + public Intent getAssistIntent(Context context) { + return getAssistIntent(context, UserId.myUserId()); + } + + /** + * Gets an intent for launching installed assistant activity, or null if not available. + * @return The assist intent. + * + * @hide + */ + public Intent getAssistIntent(Context context, int userHandle) { + try { + ComponentName comp = mService.getAssistIntent(userHandle); + if (comp == null) { + return null; + } + Intent intent = new Intent(Intent.ACTION_ASSIST); + intent.setComponent(comp); return intent; + } catch (RemoteException re) { + Log.e(TAG, "getAssistIntent() failed: " + re); + return null; } - return null; } } diff --git a/core/java/android/server/search/SearchManagerService.java b/core/java/android/server/search/SearchManagerService.java index a1f6735..b4f5e12 100644 --- a/core/java/android/server/search/SearchManagerService.java +++ b/core/java/android/server/search/SearchManagerService.java @@ -18,6 +18,9 @@ package android.server.search; import com.android.internal.content.PackageMonitor; +import android.app.ActivityManager; +import android.app.ActivityManagerNative; +import android.app.AppGlobals; import android.app.ISearchManager; import android.app.SearchManager; import android.app.SearchableInfo; @@ -27,14 +30,18 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.IPackageManager; +import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.database.ContentObserver; import android.os.Binder; import android.os.Process; +import android.os.RemoteException; import android.os.UserId; import android.os.UserManager; import android.provider.Settings; import android.util.Log; +import android.util.Slog; import android.util.SparseArray; import java.util.List; @@ -207,4 +214,48 @@ public class SearchManagerService extends ISearchManager.Stub { return getSearchables(UserId.getCallingUserId()).getWebSearchActivity(); } + @Override + public ComponentName getAssistIntent(int userHandle) { + try { + if (userHandle != UserId.getCallingUserId()) { + // Requesting a different user, make sure that they have the permission + if (ActivityManager.checkComponentPermission( + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, + Binder.getCallingUid(), -1, true) + == PackageManager.PERMISSION_GRANTED) { + // Translate to the current user id, if caller wasn't aware + if (userHandle == UserId.USER_CURRENT) { + long identity = Binder.clearCallingIdentity(); + userHandle = ActivityManagerNative.getDefault().getCurrentUser().id; + Binder.restoreCallingIdentity(identity); + } + } else { + String msg = "Permission Denial: " + + "Request to getAssistIntent for " + userHandle + + " but is calling from user " + UserId.getCallingUserId() + + "; this requires " + + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; + Slog.w(TAG, msg); + return null; + } + } + IPackageManager pm = AppGlobals.getPackageManager(); + Intent assistIntent = new Intent(Intent.ACTION_ASSIST); + ResolveInfo info = + pm.resolveIntent(assistIntent, + assistIntent.resolveTypeIfNeeded(mContext.getContentResolver()), + PackageManager.MATCH_DEFAULT_ONLY, userHandle); + if (info != null) { + return new ComponentName( + info.activityInfo.applicationInfo.packageName, + info.activityInfo.name); + } + } catch (RemoteException re) { + // Local call + Log.e(TAG, "RemoteException in getAssistIntent: " + re); + } catch (Exception e) { + Log.e(TAG, "Exception in getAssistIntent: " + e); + } + return null; + } } diff --git a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java index 475fb6d..b36e71a 100644 --- a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java @@ -24,6 +24,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.res.Resources; +import android.os.UserId; import android.os.Vibrator; import android.provider.Settings; import android.util.AttributeSet; @@ -73,14 +74,15 @@ public class SearchPanelView extends FrameLayout implements // Close Recent Apps if needed mBar.animateCollapse(CommandQueue.FLAG_EXCLUDE_SEARCH_PANEL); // Launch Assist - Intent intent = SearchManager.getAssistIntent(mContext); + Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE)) + .getAssistIntent(mContext, UserId.USER_CURRENT); if (intent == null) return; try { ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext, R.anim.search_launch_enter, R.anim.search_launch_exit, getHandler(), this); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - mContext.startActivity(intent, opts.toBundle()); + mContext.startActivityAsUser(intent, opts.toBundle(), UserId.USER_CURRENT); } catch (ActivityNotFoundException e) { Slog.w(TAG, "Activity not found for " + intent.getAction()); onAnimationStarted(); @@ -140,7 +142,8 @@ public class SearchPanelView extends FrameLayout implements } private void maybeSwapSearchIcon() { - Intent intent = SearchManager.getAssistIntent(mContext); + Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE)) + .getAssistIntent(mContext, UserId.USER_CURRENT); if (intent != null) { ComponentName component = intent.getComponent(); if (component == null || !mGlowPadView.replaceTargetDrawablesIfPresent(component, @@ -277,6 +280,7 @@ public class SearchPanelView extends FrameLayout implements } public boolean isAssistantAvailable() { - return SearchManager.getAssistIntent(mContext) != null; + return ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE)) + .getAssistIntent(mContext, UserId.USER_CURRENT) != null; } } diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java index 82181d3..8645172 100644 --- a/policy/src/com/android/internal/policy/impl/LockScreen.java +++ b/policy/src/com/android/internal/policy/impl/LockScreen.java @@ -32,6 +32,7 @@ import android.content.Context; import android.content.Intent; import android.content.res.Configuration; import android.content.res.Resources; +import android.os.UserId; import android.os.Vibrator; import android.view.KeyEvent; import android.view.LayoutInflater; @@ -275,7 +276,8 @@ class LockScreen extends LinearLayout implements KeyguardScreen { // Update the search icon with drawable from the search .apk if (!mSearchDisabled) { - Intent intent = SearchManager.getAssistIntent(mContext); + Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE)) + .getAssistIntent(mContext, UserId.USER_CURRENT); 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 @@ -309,7 +311,9 @@ 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 = SearchManager.getAssistIntent(mContext); + Intent assistIntent = + ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE)) + .getAssistIntent(mContext, UserId.USER_CURRENT); if (assistIntent != null) { launchActivity(assistIntent); } else { @@ -335,6 +339,10 @@ class LockScreen extends LinearLayout implements KeyguardScreen { } } + /** + * Launches the said intent for the current foreground user. + * @param intent + */ private void launchActivity(Intent intent) { intent.setFlags( Intent.FLAG_ACTIVITY_NEW_TASK @@ -346,7 +354,7 @@ class LockScreen extends LinearLayout implements KeyguardScreen { Log.w(TAG, "can't dismiss keyguard on launch"); } try { - mContext.startActivity(intent); + mContext.startActivityAsUser(intent, UserId.USER_CURRENT); } catch (ActivityNotFoundException e) { Log.w(TAG, "Activity not found for intent + " + intent.getAction()); } @@ -522,7 +530,9 @@ class LockScreen extends LinearLayout implements KeyguardScreen { } else if (disabledBySimState) { Log.v(TAG, "Camera disabled by Sim State"); } - boolean searchActionAvailable = SearchManager.getAssistIntent(mContext) != null; + boolean searchActionAvailable = + ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE)) + .getAssistIntent(mContext, UserId.USER_CURRENT) != 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 8c627a3..769b513 100755 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -55,6 +55,7 @@ import android.os.ServiceManager; import android.os.SystemClock; import android.os.SystemProperties; import android.os.UEventObserver; +import android.os.UserId; import android.os.Vibrator; import android.provider.Settings; @@ -2110,7 +2111,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (searchManager != null) { searchManager.stopSearch(); } - mContext.startActivity(intent); + mContext.startActivityAsUser(intent, UserId.USER_CURRENT); } catch (ActivityNotFoundException e) { Slog.w(TAG, "No activity to handle assist long press action.", e); } @@ -2118,13 +2119,14 @@ public class PhoneWindowManager implements WindowManagerPolicy { private void launchAssistAction() { sendCloseSystemWindows(SYSTEM_DIALOG_REASON_ASSIST); - Intent intent = SearchManager.getAssistIntent(mContext); + Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE)) + .getAssistIntent(mContext, UserId.USER_CURRENT); if (intent != null) { intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP); try { - mContext.startActivity(intent); + mContext.startActivityAsUser(intent, UserId.USER_CURRENT); } catch (ActivityNotFoundException e) { Slog.w(TAG, "No activity to handle assist action.", e); } |