Make ASSIST launch VIS and add a new keycode for TV (ALL_APPS)

    - KEYCODE_ASSIST: Looks for default VIS in system partition
      and launches it.
    - Ensure foreground activity assist context extras are collected
      and sent to VIS.
    - KEYCODE_ALL_APPS: Sends Intent.ACTION_ALL_APPS. For TV,
      this targets default launcher package in system partition.

Test: Manual: ASSIST: adb shell input keyevent 219
Test: Manual: ALL_APPS: adb shell input keyevent 284
Test: also tested with --longpress for these keys
Test: Manual: Checked with dummy app populating overridden
      onProvideAssistData()
Test: Keypresses after overriding ALL_APPS and ASSIST
      on Nexus Remote

Bug: 37950079
Bug: 38496261
Change-Id: I96d9de67d4a442a8c6cb7feec28fc9aeb0dcbc18
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 829b2b7..a2147b7 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -804,8 +804,11 @@
     public static final int KEYCODE_SYSTEM_NAVIGATION_LEFT = 282;
     /** Key code constant: Consumed by the system for navigation right */
     public static final int KEYCODE_SYSTEM_NAVIGATION_RIGHT = 283;
+    /** Key code constant: Show all apps
+     * @hide */
+    public static final int KEYCODE_ALL_APPS = 284;
 
-    private static final int LAST_KEYCODE = KEYCODE_SYSTEM_NAVIGATION_RIGHT;
+    private static final int LAST_KEYCODE = KEYCODE_ALL_APPS;
 
     // NOTE: If you add a new keycode here you must also add it to:
     //  isSystem()
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 8151ceb..12d707b 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1891,6 +1891,7 @@
         <enum name="KEYCODE_SYSTEM_NAVIGATION_DOWN" value="281" />
         <enum name="KEYCODE_SYSTEM_NAVIGATION_LEFT" value="282" />
         <enum name="KEYCODE_SYSTEM_NAVIGATION_RIGHT" value="283" />
+        <enum name="KEYCODE_ALL_APPS" value="284" />
     </attr>
 
     <!-- ***************************************************************** -->
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index dad3125..85fa7a1 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -13231,7 +13231,6 @@
                 return;
             }
         }
-
         // We are now ready to launch the assist activity.
         IResultReceiver sendReceiver = null;
         Bundle sendBundle = null;
@@ -13261,17 +13260,24 @@
             return;
         }
 
-        long ident = Binder.clearCallingIdentity();
+        final long ident = Binder.clearCallingIdentity();
         try {
-            pae.intent.replaceExtras(pae.extras);
-            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
-                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
-            closeSystemDialogs("assist");
-            try {
-                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
-            } catch (ActivityNotFoundException e) {
-                Slog.w(TAG, "No activity to handle assist action.", e);
+            if (TextUtils.equals(pae.intent.getAction(),
+                    android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
+                pae.intent.putExtras(pae.extras);
+                mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
+            } else {
+                pae.intent.replaceExtras(pae.extras);
+                pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                        | Intent.FLAG_ACTIVITY_SINGLE_TOP
+                        | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+                closeSystemDialogs("assist");
+
+                try {
+                    mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
+                } catch (ActivityNotFoundException e) {
+                    Slog.w(TAG, "No activity to handle assist action.", e);
+                }
             }
         } finally {
             Binder.restoreCallingIdentity(ident);
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 27159fa..0610b77 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -829,6 +829,7 @@
     private static final int MSG_ACCESSIBILITY_TV = 23;
     private static final int MSG_DISPATCH_BACK_KEY_TO_AUTOFILL = 24;
     private static final int MSG_SYSTEM_KEY_PRESS = 25;
+    private static final int MSG_HANDLE_ALL_APPS = 26;
 
     private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS = 0;
     private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION = 1;
@@ -921,6 +922,9 @@
                 case MSG_SYSTEM_KEY_PRESS:
                     sendSystemKeyToStatusBar(msg.arg1);
                     break;
+                case MSG_HANDLE_ALL_APPS:
+                    launchAllAppsAction();
+                    break;
             }
         }
     }
@@ -1801,6 +1805,17 @@
 
     private void launchAllAppsAction() {
         Intent intent = new Intent(Intent.ACTION_ALL_APPS);
+        if (mHasFeatureLeanback) {
+            final PackageManager pm = mContext.getPackageManager();
+            Intent intentLauncher = new Intent(Intent.ACTION_MAIN);
+            intentLauncher.addCategory(Intent.CATEGORY_HOME);
+            ResolveInfo resolveInfo = pm.resolveActivityAsUser(intentLauncher,
+                    PackageManager.MATCH_SYSTEM_ONLY,
+                    mCurrentUserId);
+            if (resolveInfo != null) {
+                intent.setPackage(resolveInfo.activityInfo.packageName);
+            }
+        }
         startActivityAsUser(intent, UserHandle.CURRENT);
     }
 
@@ -3620,6 +3635,14 @@
             return -1;
         } else if (mHasFeatureLeanback && interceptAccessibilityGestureTv(keyCode, down)) {
             return -1;
+        } else if (keyCode == KeyEvent.KEYCODE_ALL_APPS) {
+            if (!down) {
+                mHandler.removeMessages(MSG_HANDLE_ALL_APPS);
+                Message msg = mHandler.obtainMessage(MSG_HANDLE_ALL_APPS);
+                msg.setAsynchronous(true);
+                msg.sendToTarget();
+            }
+            return -1;
         }
 
         // Toggle Caps Lock on META-ALT.
diff --git a/services/core/java/com/android/server/search/SearchManagerService.java b/services/core/java/com/android/server/search/SearchManagerService.java
index 8969771..c3fa823 100644
--- a/services/core/java/com/android/server/search/SearchManagerService.java
+++ b/services/core/java/com/android/server/search/SearchManagerService.java
@@ -17,7 +17,6 @@
 package com.android.server.search;
 
 import android.app.ActivityManager;
-import android.app.AppGlobals;
 import android.app.IActivityManager;
 import android.app.ISearchManager;
 import android.app.SearchManager;
@@ -26,7 +25,6 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.database.ContentObserver;
@@ -37,6 +35,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
+import android.service.voice.VoiceInteractionService;
 import android.util.Log;
 import android.util.SparseArray;
 
@@ -272,24 +271,25 @@
         }
     }
 
+    // Check and return VIS component
     private ComponentName getLegacyAssistComponent(int userHandle) {
         try {
             userHandle = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
-                    Binder.getCallingUid(), userHandle, true, false, "getLegacyAssistComponent", 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) {
+                    Binder.getCallingUid(), userHandle, true, false, "getLegacyAssistComponent",
+                    null);
+            PackageManager pm = mContext.getPackageManager();
+            Intent intentAssistProbe = new Intent(VoiceInteractionService.SERVICE_INTERFACE);
+            List<ResolveInfo> infoListVis = pm.queryIntentServicesAsUser(intentAssistProbe,
+                    PackageManager.MATCH_SYSTEM_ONLY, userHandle);
+            if (infoListVis == null || infoListVis.isEmpty()) {
+                return null;
+            } else {
+                ResolveInfo rInfo = infoListVis.get(0);
                 return new ComponentName(
-                        info.activityInfo.applicationInfo.packageName,
-                        info.activityInfo.name);
+                        rInfo.serviceInfo.applicationInfo.packageName,
+                        rInfo.serviceInfo.name);
+
             }
-        } catch (RemoteException re) {
-            // Local call
-            Log.e(TAG, "RemoteException in getLegacyAssistComponent: " + re);
         } catch (Exception e) {
             Log.e(TAG, "Exception in getLegacyAssistComponent: " + e);
         }
@@ -304,9 +304,15 @@
         }
         long ident = Binder.clearCallingIdentity();
         try {
-            Intent intent = new Intent(Intent.ACTION_ASSIST);
+            Intent intent = new Intent(VoiceInteractionService.SERVICE_INTERFACE);
             intent.setComponent(comp);
+
             IActivityManager am = ActivityManager.getService();
+            if (args != null) {
+                args.putInt(Intent.EXTRA_KEY_EVENT, android.view.KeyEvent.KEYCODE_ASSIST);
+            }
+            intent.putExtras(args);
+
             return am.launchAssistIntent(intent, ActivityManager.ASSIST_CONTEXT_BASIC, hint,
                     userHandle, args);
         } catch (RemoteException e) {