Pass an args bundle to launchAssistAction.

In order to track the input device that was used to trigger assist, the
input device id is sent as an extra in the assist intent whenever it is
available. This is particularly useful on TVs, when an app may want to
know whether the input device has a microphone.

Bug: 21666123
Change-Id: I0f8c09e2f617606bef481bdff924cb6b9b47dd12
diff --git a/api/current.txt b/api/current.txt
index 0208840..499c0b9 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -8277,6 +8277,7 @@
     field public static final deprecated java.lang.String EXTRA_ALLOW_REPLACE = "android.intent.extra.ALLOW_REPLACE";
     field public static final java.lang.String EXTRA_ALTERNATE_INTENTS = "android.intent.extra.ALTERNATE_INTENTS";
     field public static final java.lang.String EXTRA_ASSIST_CONTEXT = "android.intent.extra.ASSIST_CONTEXT";
+    field public static final java.lang.String EXTRA_ASSIST_INPUT_DEVICE_ID = "android.intent.extra.ASSIST_INPUT_DEVICE_ID";
     field public static final java.lang.String EXTRA_ASSIST_INPUT_HINT_KEYBOARD = "android.intent.extra.ASSIST_INPUT_HINT_KEYBOARD";
     field public static final java.lang.String EXTRA_ASSIST_PACKAGE = "android.intent.extra.ASSIST_PACKAGE";
     field public static final java.lang.String EXTRA_ASSIST_UID = "android.intent.extra.ASSIST_UID";
@@ -24476,10 +24477,10 @@
 
   public final class AlarmClock {
     ctor public AlarmClock();
+    field public static final java.lang.String ACTION_DISMISS_ALARM = "android.intent.action.DISMISS_ALARM";
     field public static final java.lang.String ACTION_SET_ALARM = "android.intent.action.SET_ALARM";
     field public static final java.lang.String ACTION_SET_TIMER = "android.intent.action.SET_TIMER";
     field public static final java.lang.String ACTION_SHOW_ALARMS = "android.intent.action.SHOW_ALARMS";
-    field public static final java.lang.String ACTION_DISMISS_ALARM = "android.intent.action.DISMISS_ALARM";
     field public static final java.lang.String ACTION_SNOOZE_ALARM = "android.intent.action.SNOOZE_ALARM";
     field public static final java.lang.String ALARM_SEARCH_MODE_ALL = "android.all";
     field public static final java.lang.String ALARM_SEARCH_MODE_LABEL = "android.label";
diff --git a/api/system-current.txt b/api/system-current.txt
index 1392b46..09e67af 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -8509,6 +8509,7 @@
     field public static final deprecated java.lang.String EXTRA_ALLOW_REPLACE = "android.intent.extra.ALLOW_REPLACE";
     field public static final java.lang.String EXTRA_ALTERNATE_INTENTS = "android.intent.extra.ALTERNATE_INTENTS";
     field public static final java.lang.String EXTRA_ASSIST_CONTEXT = "android.intent.extra.ASSIST_CONTEXT";
+    field public static final java.lang.String EXTRA_ASSIST_INPUT_DEVICE_ID = "android.intent.extra.ASSIST_INPUT_DEVICE_ID";
     field public static final java.lang.String EXTRA_ASSIST_INPUT_HINT_KEYBOARD = "android.intent.extra.ASSIST_INPUT_HINT_KEYBOARD";
     field public static final java.lang.String EXTRA_ASSIST_PACKAGE = "android.intent.extra.ASSIST_PACKAGE";
     field public static final java.lang.String EXTRA_ASSIST_UID = "android.intent.extra.ASSIST_UID";
@@ -26406,10 +26407,10 @@
 
   public final class AlarmClock {
     ctor public AlarmClock();
+    field public static final java.lang.String ACTION_DISMISS_ALARM = "android.intent.action.DISMISS_ALARM";
     field public static final java.lang.String ACTION_SET_ALARM = "android.intent.action.SET_ALARM";
     field public static final java.lang.String ACTION_SET_TIMER = "android.intent.action.SET_TIMER";
     field public static final java.lang.String ACTION_SHOW_ALARMS = "android.intent.action.SHOW_ALARMS";
-    field public static final java.lang.String ACTION_DISMISS_ALARM = "android.intent.action.DISMISS_ALARM";
     field public static final java.lang.String ACTION_SNOOZE_ALARM = "android.intent.action.SNOOZE_ALARM";
     field public static final java.lang.String ALARM_SEARCH_MODE_ALL = "android.all";
     field public static final java.lang.String ALARM_SEARCH_MODE_LABEL = "android.label";
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index b6cec60..9112f12 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -2208,7 +2208,8 @@
             int requestType = data.readInt();
             String hint = data.readString();
             int userHandle = data.readInt();
-            boolean res = launchAssistIntent(intent, requestType, hint, userHandle);
+            Bundle args = data.readBundle();
+            boolean res = launchAssistIntent(intent, requestType, hint, userHandle, args);
             reply.writeNoException();
             reply.writeInt(res ? 1 : 0);
             return true;
@@ -5378,8 +5379,8 @@
         reply.recycle();
     }
 
-    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle)
-            throws RemoteException {
+    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
+            Bundle args) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
@@ -5387,6 +5388,7 @@
         data.writeInt(requestType);
         data.writeString(hint);
         data.writeInt(userHandle);
+        data.writeBundle(args);
         mRemote.transact(LAUNCH_ASSIST_INTENT_TRANSACTION, data, reply, 0);
         reply.readException();
         boolean res = reply.readInt() != 0;
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 249cdb2..6d84229 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -438,8 +438,8 @@
     public void reportAssistContextExtras(IBinder token, Bundle extras,
             AssistStructure structure, AssistContent content) throws RemoteException;
 
-    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle)
-            throws RemoteException;
+    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
+            Bundle args) throws RemoteException;
 
     public void killUid(int uid, String reason) throws RemoteException;
 
diff --git a/core/java/android/app/ISearchManager.aidl b/core/java/android/app/ISearchManager.aidl
index 6d27910..6094012 100644
--- a/core/java/android/app/ISearchManager.aidl
+++ b/core/java/android/app/ISearchManager.aidl
@@ -31,5 +31,5 @@
    ComponentName getGlobalSearchActivity();
    ComponentName getWebSearchActivity();
    ComponentName getAssistIntent(int userHandle);
-   boolean launchAssistAction(String hint, int userHandle);
+   boolean launchAssistAction(String hint, int userHandle, in Bundle args);
 }
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index fa27631..45799a1 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -985,12 +985,12 @@
      * Launch an assist action for the current top activity.
      * @hide
      */
-    public boolean launchAssistAction(String hint, int userHandle) {
+    public boolean launchAssistAction(String hint, int userHandle, Bundle args) {
         try {
             if (mService == null) {
                 return false;
             }
-            return mService.launchAssistAction(hint, userHandle);
+            return mService.launchAssistAction(hint, userHandle, args);
         } catch (RemoteException re) {
             Log.e(TAG, "launchAssistAction() failed: " + re);
             return false;
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index c01ce4f..5c23204 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1274,6 +1274,13 @@
             "android.intent.extra.ASSIST_INPUT_HINT_KEYBOARD";
 
     /**
+     * An optional field on {@link #ACTION_ASSIST} containing the InputDevice id
+     * that was used to invoke the assist.
+     */
+    public static final String EXTRA_ASSIST_INPUT_DEVICE_ID =
+            "android.intent.extra.ASSIST_INPUT_DEVICE_ID";
+
+    /**
      * Activity Action: List all available applications
      * <p>Input: Nothing.
      * <p>Output: nothing.
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 14065b1..c010dfe 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -75,6 +75,7 @@
 import android.app.ActivityManager;
 import android.app.KeyguardManager;
 import android.content.Context;
+import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.content.res.Resources.Theme;
@@ -4319,8 +4320,10 @@
         if (!result && (getContext().getResources().getConfiguration().uiMode
                 & Configuration.UI_MODE_TYPE_MASK) == Configuration.UI_MODE_TYPE_TELEVISION) {
             // On TVs, if the app doesn't implement search, we want to launch assist.
+            Bundle args = new Bundle();
+            args.putInt(Intent.EXTRA_ASSIST_INPUT_DEVICE_ID, event.getDeviceId());
             return ((SearchManager)getContext().getSystemService(Context.SEARCH_SERVICE))
-                    .launchAssistAction(null, UserHandle.myUserId());
+                    .launchAssistAction(null, UserHandle.myUserId(), args);
         }
         return result;
     }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 64e30e5..d0b3671 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -10643,7 +10643,7 @@
     @Override
     public Bundle getAssistContextExtras(int requestType) {
         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
-                UserHandle.getCallingUserId(), PENDING_ASSIST_EXTRAS_TIMEOUT);
+                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
         if (pae == null) {
             return null;
         }
@@ -10666,11 +10666,11 @@
     @Override
     public void requestAssistContextExtras(int requestType, IResultReceiver receiver) {
         enqueueAssistContext(requestType, null, null, receiver, UserHandle.getCallingUserId(),
-                PENDING_ASSIST_EXTRAS_LONG_TIMEOUT);
+                null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT);
     }
 
     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
-            IResultReceiver receiver, int userHandle, long timeout) {
+            IResultReceiver receiver, int userHandle, Bundle args, long timeout) {
         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
                 "enqueueAssistContext()");
         synchronized (this) {
@@ -10689,6 +10689,9 @@
             }
             PendingAssistExtras pae;
             Bundle extras = new Bundle();
+            if (args != null) {
+                extras.putAll(args);
+            }
             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
             extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
@@ -10774,8 +10777,9 @@
         }
     }
 
-    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
-        return enqueueAssistContext(requestType, intent, hint, null, userHandle,
+    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
+            Bundle args) {
+        return enqueueAssistContext(requestType, intent, hint, null, userHandle, args,
                 PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
     }
 
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 46793b9..b668bba 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -1204,7 +1204,7 @@
         launchHomeFromHotKey();
     }
 
-    private void handleLongPressOnHome() {
+    private void handleLongPressOnHome(int deviceId) {
         if (mLongPressOnHomeBehavior != LONG_PRESS_HOME_NOTHING) {
             mHomeConsumed = true;
             performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
@@ -1212,7 +1212,7 @@
             if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_SYSTEM_UI) {
                 toggleRecentApps();
             } else if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_ASSIST) {
-                launchAssistAction();
+                launchAssistAction(null, deviceId);
             }
         }
     }
@@ -2637,7 +2637,7 @@
                 }
             } else if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {
                 if (!keyguardOn) {
-                    handleLongPressOnHome();
+                    handleLongPressOnHome(event.getDeviceId());
                 }
             }
             return -1;
@@ -2717,7 +2717,7 @@
                     mAssistKeyLongPressed = false;
                 } else {
                     if (!keyguardOn) {
-                        launchAssistAction();
+                        launchAssistAction(null, event.getDeviceId());
                     }
                 }
             }
@@ -2779,7 +2779,7 @@
             if (down) {
                 mPendingMetaAction = true;
             } else if (mPendingMetaAction) {
-                launchAssistAction(Intent.EXTRA_ASSIST_INPUT_HINT_KEYBOARD);
+                launchAssistAction(Intent.EXTRA_ASSIST_INPUT_HINT_KEYBOARD, event.getDeviceId());
             }
             return -1;
         }
@@ -3000,26 +3000,22 @@
     }
 
     private void launchAssistAction() {
-        launchAssistAction(null);
+        launchAssistAction(null, Integer.MIN_VALUE);
     }
 
     private void launchAssistAction(String hint) {
+        launchAssistAction(hint, Integer.MIN_VALUE);
+    }
+
+    private void launchAssistAction(String hint, int deviceId) {
         sendCloseSystemWindows(SYSTEM_DIALOG_REASON_ASSIST);
-        Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
-                .getAssistIntent(mContext, true, UserHandle.USER_CURRENT);
-        if (intent != null) {
-            if (hint != null) {
-                intent.putExtra(hint, true);
-            }
-            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
-                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
-            try {
-                startActivityAsUser(intent, UserHandle.CURRENT);
-            } catch (ActivityNotFoundException e) {
-                Slog.w(TAG, "No activity to handle assist action.", e);
-            }
+        Bundle args = null;
+        if (deviceId > Integer.MIN_VALUE) {
+            args = new Bundle();
+            args.putInt(Intent.EXTRA_ASSIST_INPUT_DEVICE_ID, deviceId);
         }
+        ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
+                .launchAssistAction(hint, UserHandle.myUserId(), args);
     }
 
     private void startActivityAsUser(Intent intent, UserHandle handle) {
diff --git a/services/core/java/com/android/server/search/SearchManagerService.java b/services/core/java/com/android/server/search/SearchManagerService.java
index 2b2b2ac..dd2286f 100644
--- a/services/core/java/com/android/server/search/SearchManagerService.java
+++ b/services/core/java/com/android/server/search/SearchManagerService.java
@@ -34,6 +34,7 @@
 import android.content.pm.ResolveInfo;
 import android.database.ContentObserver;
 import android.os.Binder;
+import android.os.Bundle;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.UserHandle;
@@ -264,7 +265,7 @@
     }
 
     @Override
-    public boolean launchAssistAction(String hint, int userHandle) {
+    public boolean launchAssistAction(String hint, int userHandle, Bundle args) {
         ComponentName comp = getAssistIntent(userHandle);
         if (comp == null) {
             return false;
@@ -275,7 +276,7 @@
             intent.setComponent(comp);
             IActivityManager am = ActivityManagerNative.getDefault();
             return am.launchAssistIntent(intent, ActivityManager.ASSIST_CONTEXT_BASIC, hint,
-                    userHandle);
+                    userHandle, args);
         } catch (RemoteException e) {
         } finally {
             Binder.restoreCallingIdentity(ident);