Add more onTopLauncher support.

- Add onTopLauncher checking for TaskRecord.
- Add onTopLauncher to the window manager.

Bug: 28425537
Change-Id: Ic9e53db891dc42463a1a77b106ba93438a052181
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 0601219..3d786f1 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -107,12 +107,14 @@
      *                        they are in.
      * @param homeTask True if this is the task.
      * @param targetSdkVersion The application's target SDK version
+     * @param isOnTopLauncher True if this task is an on-top launcher.
      */
     void addAppToken(int addPos, IApplicationToken token, int taskId, int stackId,
             int requestedOrientation, boolean fullscreen, boolean showWhenLocked, int userId,
             int configChanges, boolean voiceInteraction, boolean launchTaskBehind,
             in Rect taskBounds, in Configuration configuration, int taskResizeMode,
-            boolean alwaysFocusable, boolean homeTask, int targetSdkVersion, int rotationAnimationHint);
+            boolean alwaysFocusable, boolean homeTask, int targetSdkVersion,
+            int rotationAnimationHint, boolean isOnTopLauncher);
     /**
      *
      * @param token The token we are adding to the input task Id.
@@ -124,9 +126,10 @@
      * @param config Configuration that is being used with this task.
      * @param taskResizeMode The resize mode of the task.
      * @param homeTask True if this is the task.
+     * @param isOnTopLauncher True if this task is an on-top launcher.
      */
     void setAppTask(IBinder token, int taskId, int stackId, in Rect taskBounds,
-            in Configuration config, int taskResizeMode, boolean homeTask);
+            in Configuration config, int taskResizeMode, boolean homeTask, boolean isOnTopLauncher);
     void setAppOrientation(IApplicationToken token, int requestedOrientation);
     int getAppOrientation(IApplicationToken token);
     void setFocusedApp(IBinder token, boolean moveFocusNow);
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 99e3ebc..ffee68d 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -5209,7 +5209,7 @@
                 (r.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0, r.userId, r.info.configChanges,
                 task.voiceSession != null, r.mLaunchTaskBehind, bounds, task.mOverrideConfig,
                 task.mResizeMode, r.isAlwaysFocusable(), task.isHomeTask(),
-                r.appInfo.targetSdkVersion, r.mRotationAnimationHint);
+                r.appInfo.targetSdkVersion, r.mRotationAnimationHint, task.isOnTopLauncher());
         r.taskConfigOverride = task.mOverrideConfig;
     }
 
@@ -5262,7 +5262,7 @@
     private void setAppTask(ActivityRecord r, TaskRecord task) {
         final Rect bounds = task.updateOverrideConfigurationFromLaunchBounds();
         mWindowManager.setAppTask(r.appToken, task.taskId, mStackId, bounds, task.mOverrideConfig,
-                task.mResizeMode, task.isHomeTask());
+                task.mResizeMode, task.isHomeTask(), task.isOnTopLauncher());
         r.taskConfigOverride = task.mOverrideConfig;
     }
 
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index b2b752c..c2c8e3d 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -66,6 +66,7 @@
 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
 import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
+import static android.content.pm.ActivityInfo.FLAG_ON_TOP_LAUNCHER;
 import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
 import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
 import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
@@ -176,6 +177,8 @@
                             // ActivityManager.LOCK_TASK_LAUNCH_MODE_*
     private boolean mPrivileged;    // The root activity application of this task holds
                                     // privileged permissions.
+    private boolean mIsOnTopLauncher; // Whether this task is an on-top launcher. See
+                                      // android.R.attr#onTopLauncher.
 
     /** Can't be put in lockTask mode. */
     final static int LOCK_TASK_AUTH_DONT_LOCK = 0;
@@ -474,6 +477,7 @@
             autoRemoveRecents = false;
         }
         mResizeMode = info.resizeMode;
+        mIsOnTopLauncher = (info.flags & FLAG_ON_TOP_LAUNCHER) != 0;
         mLockTaskMode = info.lockTaskLaunchMode;
         mPrivileged = (info.applicationInfo.privateFlags & PRIVATE_FLAG_PRIVILEGED) != 0;
         setLockTaskAuth();
@@ -1024,6 +1028,10 @@
                 || ActivityInfo.isResizeableMode(mResizeMode)) && !mTemporarilyUnresizable;
     }
 
+    boolean isOnTopLauncher() {
+        return isHomeTask() && mIsOnTopLauncher;
+    }
+
     boolean inCropWindowsResizeMode() {
         return !isResizeable() && mResizeMode == RESIZE_MODE_CROP_WINDOWS;
     }
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 423b134..7394309 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -92,12 +92,16 @@
 
     private boolean mHomeTask;
 
+    // Whether this task is an on-top launcher task, which is determined by the root activity.
+    private boolean mIsOnTopLauncher;
+
     Task(int taskId, TaskStack stack, int userId, WindowManagerService service, Rect bounds,
-            Configuration config) {
+            Configuration config, boolean isOnTopLauncher) {
         mTaskId = taskId;
         mStack = stack;
         mUserId = userId;
         mService = service;
+        mIsOnTopLauncher = isOnTopLauncher;
         setBounds(bounds, config);
     }
 
@@ -282,6 +286,10 @@
                 && (ActivityInfo.isResizeableMode(mResizeMode) || mService.mForceResizableTasks);
     }
 
+    boolean isOnTopLauncher() {
+        return mIsOnTopLauncher;
+    }
+
     boolean cropWindowsToStackBounds() {
         return !mHomeTask && (isResizeable() || mResizeMode == RESIZE_MODE_CROP_WINDOWS);
     }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 08d42fb..a9ce794 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -3362,7 +3362,7 @@
     }
 
     private Task createTaskLocked(int taskId, int stackId, int userId, AppWindowToken atoken,
-            Rect bounds, Configuration config) {
+            Rect bounds, Configuration config, boolean isOnTopLauncher) {
         if (DEBUG_STACK) Slog.i(TAG_WM, "createTaskLocked: taskId=" + taskId + " stackId=" + stackId
                 + " atoken=" + atoken + " bounds=" + bounds);
         final TaskStack stack = mStackIdToStack.get(stackId);
@@ -3370,7 +3370,7 @@
             throw new IllegalArgumentException("addAppToken: invalid stackId=" + stackId);
         }
         EventLog.writeEvent(EventLogTags.WM_TASK_CREATED, taskId, stackId);
-        Task task = new Task(taskId, stack, userId, this, bounds, config);
+        Task task = new Task(taskId, stack, userId, this, bounds, config, isOnTopLauncher);
         mTaskIdToTask.put(taskId, task);
         stack.addTask(task, !atoken.mLaunchTaskBehind /* toTop */, atoken.showForAllUsers);
         return task;
@@ -3381,7 +3381,8 @@
             int requestedOrientation, boolean fullscreen, boolean showForAllUsers, int userId,
             int configChanges, boolean voiceInteraction, boolean launchTaskBehind,
             Rect taskBounds, Configuration config, int taskResizeMode, boolean alwaysFocusable,
-            boolean homeTask, int targetSdkVersion, int rotationAnimationHint) {
+            boolean homeTask, int targetSdkVersion, int rotationAnimationHint,
+            boolean isOnTopLauncher) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "addAppToken()")) {
             throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
@@ -3423,7 +3424,8 @@
 
             Task task = mTaskIdToTask.get(taskId);
             if (task == null) {
-                task = createTaskLocked(taskId, stackId, userId, atoken, taskBounds, config);
+                task = createTaskLocked(taskId, stackId, userId, atoken, taskBounds, config,
+                        isOnTopLauncher);
             }
             task.addAppToken(addPos, atoken, taskResizeMode, homeTask);
 
@@ -3437,7 +3439,7 @@
 
     @Override
     public void setAppTask(IBinder token, int taskId, int stackId, Rect taskBounds,
-            Configuration config, int taskResizeMode, boolean homeTask) {
+            Configuration config, int taskResizeMode, boolean homeTask, boolean isOnTopLauncher) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "setAppTask()")) {
             throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
@@ -3455,7 +3457,8 @@
             Task newTask = mTaskIdToTask.get(taskId);
             if (newTask == null) {
                 newTask = createTaskLocked(
-                        taskId, stackId, oldTask.mUserId, atoken, taskBounds, config);
+                        taskId, stackId, oldTask.mUserId, atoken, taskBounds, config,
+                        isOnTopLauncher);
             }
             newTask.addAppToken(Integer.MAX_VALUE /* at top */, atoken, taskResizeMode, homeTask);
         }
diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
index 063dd86..8424344 100644
--- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
@@ -93,7 +93,7 @@
 
         try {
             mWm.addAppToken(0, null, 0, 0, 0, false, false, 0, 0, false, false, null,
-                    Configuration.EMPTY, 0, false, false, 0, -1);
+                    Configuration.EMPTY, 0, false, false, 0, -1, false);
             fail("IWindowManager.addAppToken did not throw SecurityException as"
                     + " expected");
         } catch (SecurityException e) {
@@ -103,7 +103,7 @@
         }
 
         try {
-            mWm.setAppTask(null, 0, INVALID_STACK_ID, null, null, 0, false);
+            mWm.setAppTask(null, 0, INVALID_STACK_ID, null, null, 0, false, false);
             fail("IWindowManager.setAppGroupId did not throw SecurityException as"
                     + " expected");
         } catch (SecurityException e) {