Introducing activityType window configuration.

Used to represent the current activity type of the window
configuration which can be undefined, standard, home, recents, or
assistant. This information if currently represented in a few ways in
the window heirarchy e.g. with stack id or with fields in tasks and
activities. This change allows us to represent the idea in a more
structure way without overloading concepts like stack ids.

Test: bit FrameworksServicesTests:com.android.server.wm.ConfigurationContainerTests
Test: bit FrameworksServicesTests:com.android.server.wm.WindowConfigurationTests
Test: go/wm-smoke
Change-Id: I7d7283c72e806972eeb3a8dab448f195dd6cd811
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index f3bc62f..8f68bd6 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3093,7 +3093,7 @@
      */
     void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
         final TaskRecord task = r.getTask();
-        if (task.isApplicationTask()) {
+        if (task.isActivityTypeStandard()) {
             if (mCurAppTimeTracker != r.appTimeTracker) {
                 // We are switching app tracking.  Complete the current one.
                 if (mCurAppTimeTracker != null) {
@@ -9934,7 +9934,7 @@
                     if (!allowed) {
                         // If the caller doesn't have the GET_TASKS permission, then only
                         // allow them to see a small subset of tasks -- their own and home.
-                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
+                        if (!tr.isActivityTypeHome() && tr.effectiveUid != callingUid) {
                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
                             continue;
                         }
@@ -12945,7 +12945,7 @@
         int userId;
         synchronized (this) {
             final ActivityStack focusedStack = getFocusedStack();
-            if (focusedStack == null || focusedStack.isAssistantStack()) {
+            if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
                 return false;
             }
 
@@ -13050,7 +13050,7 @@
 
             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
                     userHandle);
-            pae.isHome = activity.isHomeActivity();
+            pae.isHome = activity.isActivityTypeHome();
 
             // Increment the sessionId if necessary
             if (newSessionId) {
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 4433b84..c481efc 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -33,6 +33,12 @@
 import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_UP;
 import static android.app.AppOpsManager.MODE_ALLOWED;
 import static android.app.AppOpsManager.OP_PICTURE_IN_PICTURE;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.app.WindowConfiguration.activityTypeToString;
 import static android.content.Intent.ACTION_MAIN;
 import static android.content.Intent.CATEGORY_HOME;
 import static android.content.Intent.CATEGORY_LAUNCHER;
@@ -226,12 +232,6 @@
     private final boolean componentSpecified;  // did caller specify an explicit component?
     final boolean rootVoiceInteraction;  // was this the root activity of a voice interaction?
 
-    static final int APPLICATION_ACTIVITY_TYPE = 0;
-    static final int HOME_ACTIVITY_TYPE = 1;
-    static final int RECENTS_ACTIVITY_TYPE = 2;
-    static final int ASSISTANT_ACTIVITY_TYPE = 3;
-    int mActivityType;
-
     private CharSequence nonLocalizedLabel;  // the label information from the package mgr.
     private int labelRes;           // the label information from the package mgr.
     private int icon;               // resource identifier of activity's icon.
@@ -388,7 +388,8 @@
         }
         pw.print(prefix); pw.print("stateNotNeeded="); pw.print(stateNotNeeded);
                 pw.print(" componentSpecified="); pw.print(componentSpecified);
-                pw.print(" mActivityType="); pw.println(mActivityType);
+                pw.print(" mActivityType="); pw.println(
+                        activityTypeToString(getActivityType()));
         if (rootVoiceInteraction) {
             pw.print(prefix); pw.print("rootVoiceInteraction="); pw.println(rootVoiceInteraction);
         }
@@ -495,7 +496,7 @@
         pw.print(prefix); pw.print("frozenBeforeDestroy="); pw.print(frozenBeforeDestroy);
                 pw.print(" forceNewConfig="); pw.println(forceNewConfig);
         pw.print(prefix); pw.print("mActivityType=");
-                pw.println(activityTypeToString(mActivityType));
+                pw.println(activityTypeToString(getActivityType()));
         if (requestedVrComponent != null) {
             pw.print(prefix);
             pw.print("requestedVrComponent=");
@@ -938,7 +939,7 @@
                 task.voiceSession != null, mLaunchTaskBehind, isAlwaysFocusable(),
                 appInfo.targetSdkVersion, mRotationAnimationHint,
                 ActivityManagerService.getInputDispatchingTimeoutLocked(this) * 1000000L,
-                getOverrideConfiguration(), mBounds);
+                new Configuration(getOverrideConfiguration()), mBounds);
 
         task.addActivityToTop(this);
 
@@ -1028,10 +1029,11 @@
 
     private void setActivityType(boolean componentSpecified, int launchedFromUid, Intent intent,
             ActivityOptions options, ActivityRecord sourceRecord) {
+        int activityType = ACTIVITY_TYPE_UNDEFINED;
         if ((!componentSpecified || canLaunchHomeActivity(launchedFromUid, sourceRecord))
                 && isHomeIntent(intent) && !isResolverActivity()) {
             // This sure looks like a home activity!
-            mActivityType = HOME_ACTIVITY_TYPE;
+            activityType = ACTIVITY_TYPE_HOME;
 
             if (info.resizeMode == RESIZE_MODE_FORCE_RESIZEABLE
                     || info.resizeMode == RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION) {
@@ -1039,13 +1041,12 @@
                 info.resizeMode = RESIZE_MODE_UNRESIZEABLE;
             }
         } else if (realActivity.getClassName().contains(RECENTS_PACKAGE_NAME)) {
-            mActivityType = RECENTS_ACTIVITY_TYPE;
+            activityType = ACTIVITY_TYPE_RECENTS;
         } else if (options != null && options.getLaunchStackId() == ASSISTANT_STACK_ID
                 && canLaunchAssistActivity(launchedFromPackage)) {
-            mActivityType = ASSISTANT_ACTIVITY_TYPE;
-        } else {
-            mActivityType = APPLICATION_ACTIVITY_TYPE;
+            activityType = ACTIVITY_TYPE_ASSISTANT;
         }
+        setActivityType(activityType);
     }
 
     void setTaskToAffiliateWith(TaskRecord taskToAffiliateWith) {
@@ -1096,18 +1097,6 @@
         return stack != null && stack.isInStackLocked(this) != null;
     }
 
-    boolean isHomeActivity() {
-        return mActivityType == HOME_ACTIVITY_TYPE;
-    }
-
-    boolean isRecentsActivity() {
-        return mActivityType == RECENTS_ACTIVITY_TYPE;
-    }
-
-    boolean isAssistantActivity() {
-        return mActivityType == ASSISTANT_ACTIVITY_TYPE;
-    }
-
     boolean isPersistable() {
         return (info.persistableMode == PERSIST_ROOT_ONLY ||
                 info.persistableMode == PERSIST_ACROSS_REBOOTS) &&
@@ -1134,7 +1123,7 @@
      * @return whether this activity supports PiP multi-window and can be put in the pinned stack.
      */
     boolean supportsPictureInPicture() {
-        return service.mSupportsPictureInPicture && !isHomeActivity()
+        return service.mSupportsPictureInPicture && isActivityTypeStandard()
                 && info.supportsPictureInPicture();
     }
 
@@ -1160,7 +1149,7 @@
      * @return whether this activity supports non-PiP multi-window.
      */
     private boolean supportsResizeableMultiWindow() {
-        return service.mSupportsMultiWindow && !isHomeActivity()
+        return service.mSupportsMultiWindow && !isActivityTypeHome()
                 && (ActivityInfo.isResizeableMode(info.resizeMode)
                         || service.mForceResizableActivities);
     }
@@ -1537,7 +1526,7 @@
 
         boolean isVisible = !behindFullscreenActivity || mLaunchTaskBehind;
 
-        if (service.mSupportsLeanbackOnly && isVisible && isRecentsActivity()) {
+        if (service.mSupportsLeanbackOnly && isVisible && isActivityTypeRecents()) {
             // On devices that support leanback only (Android TV), Recents activity can only be
             // visible if the home stack is the focused stack or we are in split-screen mode.
             isVisible = mStackSupervisor.getStack(DOCKED_STACK_ID) != null
@@ -1615,7 +1604,7 @@
         newIntents = null;
         stopped = false;
 
-        if (isHomeActivity()) {
+        if (isActivityTypeHome()) {
             ProcessRecord app = task.mActivities.get(0).app;
             if (app != null && app != service.mHomeProcess) {
                 service.mHomeProcess = app;
@@ -2145,7 +2134,7 @@
             config.getOverrideConfiguration());
     }
 
-    void setLastReportedConfiguration(Configuration global, Configuration override) {
+    private void setLastReportedConfiguration(Configuration global, Configuration override) {
         mLastReportedConfiguration.setConfiguration(global, override);
     }
 
@@ -2718,16 +2707,6 @@
         return r;
     }
 
-    private static String activityTypeToString(int type) {
-        switch (type) {
-            case APPLICATION_ACTIVITY_TYPE: return "APPLICATION_ACTIVITY_TYPE";
-            case HOME_ACTIVITY_TYPE: return "HOME_ACTIVITY_TYPE";
-            case RECENTS_ACTIVITY_TYPE: return "RECENTS_ACTIVITY_TYPE";
-            case ASSISTANT_ACTIVITY_TYPE: return "ASSISTANT_ACTIVITY_TYPE";
-            default: return Integer.toString(type);
-        }
-    }
-
     private static boolean isInVrUiMode(Configuration config) {
         return (config.uiMode & UI_MODE_TYPE_MASK) == UI_MODE_TYPE_VR_HEADSET;
     }
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 2da4377..4560d3a 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -23,8 +23,12 @@
 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
-import static android.app.ActivityManager.StackId.RECENTS_STACK_ID;
+import static android.app.ActivityManager.StackId.getActivityTypeForStackId;
 import static android.app.ActivityManager.StackId.getWindowingModeForStackId;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
 import static android.content.pm.ActivityInfo.FLAG_RESUME_WHILE_PAUSING;
@@ -66,9 +70,6 @@
 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
-import static com.android.server.am.ActivityRecord.ASSISTANT_ACTIVITY_TYPE;
-import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
 import static com.android.server.am.ActivityStack.ActivityState.STOPPED;
 import static com.android.server.am.ActivityStack.ActivityState.STOPPING;
 import static com.android.server.am.ActivityStackSupervisor.FindTaskResult;
@@ -486,6 +487,10 @@
         if (windowingMode != WINDOWING_MODE_UNDEFINED) {
             setWindowingMode(windowingMode);
         }
+        final int activityType = getActivityTypeForStackId(mStackId);
+        if (activityType != ACTIVITY_TYPE_UNDEFINED) {
+            setActivityType(activityType);
+        }
     }
 
     /** Adds the stack to specified display and calls WindowManager to do the same. */
@@ -831,14 +836,6 @@
         return hadit;
     }
 
-    final boolean isHomeStack() {
-        return mStackId == HOME_STACK_ID;
-    }
-
-    final boolean isRecentsStack() {
-        return mStackId == RECENTS_STACK_ID;
-    }
-
     final boolean isHomeOrRecentsStack() {
         return StackId.isHomeOrRecentsStack(mStackId);
     }
@@ -851,10 +848,6 @@
         return mStackId == PINNED_STACK_ID;
     }
 
-    final boolean isAssistantStack() {
-        return mStackId == ASSISTANT_STACK_ID;
-    }
-
     final boolean isOnHomeDisplay() {
         return isAttached() && mDisplayId == DEFAULT_DISPLAY;
     }
@@ -975,7 +968,7 @@
                 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": mismatch root " + r);
                 continue;
             }
-            if (r.mActivityType != target.mActivityType) {
+            if (!r.hasCompatibleActivityType(target)) {
                 if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": mismatch activity type");
                 continue;
             }
@@ -1656,7 +1649,8 @@
                 }
 
                 if (!isHomeOrRecentsStack() && r.frontOfTask && task.isOverHomeStack()
-                        && !StackId.isHomeOrRecentsStack(stackBehindId) && !isAssistantStack()) {
+                        && !StackId.isHomeOrRecentsStack(stackBehindId)
+                        && !isActivityTypeAssistant()) {
                     // Stack isn't translucent if it's top activity should have the home stack
                     // behind it and the stack currently behind it isn't the home or recents stack
                     // or the assistant stack.
@@ -1703,7 +1697,7 @@
         if (mStackId == DOCKED_STACK_ID) {
             // If the assistant stack is focused and translucent, then the docked stack is always
             // visible
-            if (topStack.isAssistantStack()) {
+            if (topStack.isActivityTypeAssistant()) {
                 return (topStack.isStackTranslucent(starting, DOCKED_STACK_ID)) ? STACK_VISIBLE
                         : STACK_INVISIBLE;
             }
@@ -1905,39 +1899,22 @@
                     // status of an activity in a previous task affects other.
                     behindFullscreenActivity = stackVisibility == STACK_INVISIBLE;
                 } else if (mStackId == HOME_STACK_ID) {
-                    if (task.isHomeTask()) {
-                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Home task: at " + task
-                                + " stackInvisible=" + stackInvisible
-                                + " behindFullscreenActivity=" + behindFullscreenActivity);
-                        // No other task in the home stack should be visible behind the home activity.
-                        // Home activities is usually a translucent activity with the wallpaper behind
-                        // them. However, when they don't have the wallpaper behind them, we want to
-                        // show activities in the next application stack behind them vs. another
-                        // task in the home stack like recents.
-                        behindFullscreenActivity = true;
-                    } else if (task.isRecentsTask()
-                            && task.getTaskToReturnTo() == APPLICATION_ACTIVITY_TYPE) {
-                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
-                                "Recents task returning to app: at " + task
-                                        + " stackInvisible=" + stackInvisible
-                                        + " behindFullscreenActivity=" + behindFullscreenActivity);
-                        // We don't want any other tasks in the home stack visible if the recents
-                        // activity is going to be returning to an application activity type.
-                        // We do this to preserve the visible order the user used to get into the
-                        // recents activity. The recents activity is normally translucent and if it
-                        // doesn't have the wallpaper behind it the next activity in the home stack
-                        // shouldn't be visible when the home stack is brought to the front to display
-                        // the recents activity from an app.
-                        behindFullscreenActivity = true;
-                    }
+                    if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Home task: at " + task
+                            + " stackInvisible=" + stackInvisible
+                            + " behindFullscreenActivity=" + behindFullscreenActivity);
+                    // No other task in the home stack should be visible behind the home activity.
+                    // Home activities is usually a translucent activity with the wallpaper behind
+                    // them. However, when they don't have the wallpaper behind them, we want to
+                    // show activities in the next application stack behind them vs. another
+                    // task in the home stack like recents.
+                    behindFullscreenActivity = true;
                 } else if (mStackId == FULLSCREEN_WORKSPACE_STACK_ID) {
                     if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Skipping after task=" + task
                             + " returning to non-application type=" + task.getTaskToReturnTo());
                     // Once we reach a fullscreen stack task that has a running activity and should
                     // return to another stack task, then no other activities behind that one should
                     // be visible.
-                    if (task.topRunningActivityLocked() != null &&
-                            task.getTaskToReturnTo() != APPLICATION_ACTIVITY_TYPE) {
+                    if (task.topRunningActivityLocked() != null && !task.returnsToStandardTask()) {
                         behindFullscreenActivity = true;
                     }
                 }
@@ -2334,10 +2311,10 @@
                 // This task is going away but it was supposed to return to the home stack.
                 // Now the task above it has to return to the home task instead.
                 final int taskNdx = mTaskHistory.indexOf(prevTask) + 1;
-                mTaskHistory.get(taskNdx).setTaskToReturnTo(HOME_ACTIVITY_TYPE);
+                mTaskHistory.get(taskNdx).setTaskToReturnTo(ACTIVITY_TYPE_HOME);
             } else if (!isOnHomeDisplay()) {
                 return false;
-            } else if (!isHomeStack()){
+            } else if (!isActivityTypeHome()){
                 if (DEBUG_STATES) Slog.d(TAG_STATES,
                         "resumeTopActivityLocked: Launching home next");
                 return isOnHomeDisplay() &&
@@ -2820,7 +2797,7 @@
 
         // If this is not on the default display, then just set the return type to application
         if (!isOnHomeDisplay()) {
-            task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
+            task.setTaskToReturnTo(ACTIVITY_TYPE_STANDARD);
             return;
         }
 
@@ -2832,8 +2809,8 @@
         }
 
         // If the task was launched from the assistant stack, set the return type to assistant
-        if (lastStack.isAssistantStack()) {
-            task.setTaskToReturnTo(ASSISTANT_ACTIVITY_TYPE);
+        if (lastStack.isActivityTypeAssistant()) {
+            task.setTaskToReturnTo(ACTIVITY_TYPE_ASSISTANT);
             return;
         }
 
@@ -2845,9 +2822,10 @@
             // If it's a last task over home - we default to keep its return to type not to
             // make underlying task focused when this one will be finished.
             int returnToType = isLastTaskOverHome
-                    ? task.getTaskToReturnTo() : APPLICATION_ACTIVITY_TYPE;
+                    ? task.getTaskToReturnTo() : ACTIVITY_TYPE_STANDARD;
             if (fromHomeOrRecents && StackId.allowTopTaskToReturnHome(mStackId)) {
-                returnToType = topTask == null ? HOME_ACTIVITY_TYPE : topTask.taskType;
+                returnToType = topTask == null
+                        ? ACTIVITY_TYPE_HOME : topTask.getActivityType();
             }
             task.setTaskToReturnTo(returnToType);
         }
@@ -3099,7 +3077,7 @@
                 } else {
                     targetTask = createTaskRecord(
                             mStackSupervisor.getNextTaskIdForUserLocked(target.userId),
-                            target.info, null, null, null, false, target.mActivityType);
+                            target.info, null, null, null, false);
                     targetTask.affinityIntent = target.intent;
                     if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Start pushing activity " + target
                             + " out to new task " + targetTask);
@@ -3410,8 +3388,8 @@
                     throw new IllegalStateException("activity no longer associated with task:" + r);
                 }
 
-                final boolean isAssistantOrOverAssistant = task.getStack().isAssistantStack() ||
-                        task.isOverAssistantStack();
+                final boolean isAssistantOrOverAssistant =
+                        task.getStack().isActivityTypeAssistant() || task.isOverAssistantStack();
                 if (r.frontOfTask && isATopFinishingTask(task)
                         && (task.isOverHomeStack() || isAssistantOrOverAssistant)) {
                     // For non-fullscreen or assistant stack, we want to move the focus to the next
@@ -3446,8 +3424,8 @@
      * @param allowFocusSelf Is the focus allowed to remain on the same stack.
      */
     private boolean adjustFocusToNextFocusableStackLocked(String reason, boolean allowFocusSelf) {
-        if (isAssistantStack() && bottomTask() != null &&
-                bottomTask().getTaskToReturnTo() == HOME_ACTIVITY_TYPE) {
+        if (isActivityTypeAssistant() && bottomTask() != null
+                && bottomTask().returnsToHomeTask()) {
             // If the current stack is the assistant stack, then use the return-to type to determine
             // whether to return to the home screen. This is needed to workaround an issue where
             // launching a fullscreen task (and subequently returning from that task) will cause
@@ -3472,8 +3450,8 @@
             return mStackSupervisor.moveHomeStackTaskToTop(reason);
         }
 
-        if (stack.isAssistantStack() && top != null
-                && top.getTask().getTaskToReturnTo() == HOME_ACTIVITY_TYPE) {
+        if (stack.isActivityTypeAssistant() && top != null
+                && top.getTask().returnsToHomeTask()) {
             // It is possible for the home stack to not be directly underneath the assistant stack.
             // For example, the assistant may start an activity in the fullscreen stack. Upon
             // returning to the assistant stack, we must ensure that the home stack is underneath
@@ -3611,7 +3589,7 @@
             if (r.state == ActivityState.RESUMED
                     || r.state == ActivityState.PAUSING
                     || r.state == ActivityState.PAUSED) {
-                if (!r.isHomeActivity() || mService.mHomeProcess != r.app) {
+                if (!r.isActivityTypeHome() || mService.mHomeProcess != r.app) {
                     Slog.w(TAG, "  Force finishing activity "
                             + r.intent.getComponent().flattenToShortString());
                     finishActivityLocked(r, Activity.RESULT_CANCELED, null, reason, false);
@@ -3928,7 +3906,7 @@
         if (srec.frontOfTask && task != null && task.getBaseIntent() != null
                 && task.getBaseIntent().isDocument()) {
             // Okay, this activity is at the root of its task.  What to do, what to do...
-            if (task.getTaskToReturnTo() != ActivityRecord.APPLICATION_ACTIVITY_TYPE) {
+            if (!task.returnsToStandardTask()) {
                 // Finishing won't return to an application, so we need to recreate.
                 return true;
             }
@@ -3938,11 +3916,7 @@
                 Slog.w(TAG, "shouldUpRecreateTask: task not in history for " + srec);
                 return false;
             }
-            if (taskIdx == 0) {
-                // At the bottom of the stack, nothing to go back to.
-                return true;
-            }
-            TaskRecord prevTask = mTaskHistory.get(taskIdx);
+            final TaskRecord prevTask = mTaskHistory.get(taskIdx);
             if (!task.affinity.equals(prevTask.affinity)) {
                 // These are different apps, so need to recreate.
                 return true;
@@ -4527,17 +4501,18 @@
     }
 
     void moveHomeStackTaskToTop() {
+        if (!isActivityTypeHome()) {
+            throw new IllegalStateException("Calling moveHomeStackTaskToTop() on non-home stack: "
+                    + this);
+        }
         final int top = mTaskHistory.size() - 1;
-        for (int taskNdx = top; taskNdx >= 0; --taskNdx) {
-            final TaskRecord task = mTaskHistory.get(taskNdx);
-            if (task.taskType == HOME_ACTIVITY_TYPE) {
-                if (DEBUG_TASKS || DEBUG_STACK) Slog.d(TAG_STACK,
-                        "moveHomeStackTaskToTop: moving " + task);
-                mTaskHistory.remove(taskNdx);
-                mTaskHistory.add(top, task);
-                updateTaskMovement(task, true);
-                return;
-            }
+        if (top >= 0) {
+            final TaskRecord task = mTaskHistory.get(top);
+            if (DEBUG_TASKS || DEBUG_STACK) Slog.d(TAG_STACK,
+                    "moveHomeStackTaskToTop: moving " + task);
+            mTaskHistory.remove(top);
+            mTaskHistory.add(top, task);
+            updateTaskMovement(task, true);
         }
     }
 
@@ -4660,7 +4635,7 @@
         // If true, we should resume the home activity next if the task we are moving to the
         // back is over the home stack. We force to false if the task we are moving to back
         // is the home task and we don't want it resumed after moving to the back.
-        final boolean canGoHome = !tr.isHomeTask() && tr.isOverHomeStack();
+        final boolean canGoHome = !tr.isActivityTypeHome() && tr.isOverHomeStack();
         if (canGoHome) {
             final TaskRecord nextTask = getNextTask(tr);
             if (nextTask != null) {
@@ -4695,7 +4670,7 @@
             }
             if (taskNdx == 1) {
                 // Set the last task before tr to go to home.
-                task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
+                task.setTaskToReturnTo(ACTIVITY_TYPE_HOME);
             }
         }
 
@@ -4705,7 +4680,7 @@
                 // Not ready yet!
                 return false;
             }
-            tr.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
+            tr.setTaskToReturnTo(ACTIVITY_TYPE_STANDARD);
             return mStackSupervisor.resumeHomeStackTask(null, "moveTaskToBack");
         }
 
@@ -4919,7 +4894,7 @@
                         }
                         return true;
                     }
-                    if (r.isHomeActivity()) {
+                    if (r.isActivityTypeHome()) {
                         if (homeActivity != null && homeActivity.equals(r.realActivity)) {
                             Slog.i(TAG, "Skip force-stop again " + r);
                             continue;
@@ -4962,7 +4937,7 @@
             int numActivities = 0;
             int numRunning = 0;
             final ArrayList<ActivityRecord> activities = task.mActivities;
-            if (!allowed && !task.isHomeTask() && task.effectiveUid != callingUid) {
+            if (!allowed && !task.isActivityTypeHome() && task.effectiveUid != callingUid) {
                 continue;
             }
             for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
@@ -5158,7 +5133,7 @@
         if (task.isOverHomeStack() && taskNdx < topTaskNdx) {
             final TaskRecord nextTask = mTaskHistory.get(taskNdx + 1);
             if (!nextTask.isOverHomeStack() && !nextTask.isOverAssistantStack()) {
-                nextTask.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
+                nextTask.setTaskToReturnTo(ACTIVITY_TYPE_HOME);
             }
         }
         mTaskHistory.remove(task);
@@ -5214,9 +5189,9 @@
 
     TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent,
             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
-            boolean toTop, int type) {
-        TaskRecord task = new TaskRecord(mService, taskId, info, intent, voiceSession,
-                voiceInteractor, type);
+            boolean toTop) {
+        final TaskRecord task = new TaskRecord(mService, taskId, info, intent, voiceSession,
+                voiceInteractor);
         // add the task to stack first, mTaskPositioner might need the stack association
         addTask(task, toTop, "createTaskRecord");
         final boolean isLockscreenShown =
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 64cbe2b..01a6b54 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -33,6 +33,9 @@
 import static android.app.ActivityManager.StackId.RECENTS_STACK_ID;
 import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY;
 import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SPLIT_SCREEN;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
 import static android.content.pm.PackageManager.PERMISSION_DENIED;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.PowerManager.PARTIAL_WAKE_LOCK;
@@ -67,8 +70,6 @@
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.am.ActivityManagerService.ANIMATE;
 import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
-import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
-import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
 import static com.android.server.am.ActivityStack.ActivityState.DESTROYED;
 import static com.android.server.am.ActivityStack.ActivityState.DESTROYING;
 import static com.android.server.am.ActivityStack.ActivityState.INITIALIZING;
@@ -689,7 +690,7 @@
         }
 
         if (prev != null) {
-            prev.getTask().setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
+            prev.getTask().setTaskToReturnTo(ACTIVITY_TYPE_STANDARD);
         }
 
         mHomeStack.moveHomeStackTaskToTop();
@@ -1342,7 +1343,7 @@
                                 + " newIntents=" + newIntents + " andResume=" + andResume);
                 EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY, r.userId,
                         System.identityHashCode(r), task.taskId, r.shortComponentName);
-                if (r.isHomeActivity()) {
+                if (r.isActivityTypeHome()) {
                     // Home process is the root process of the task.
                     mService.mHomeProcess = task.mActivities.get(0).app;
                 }
@@ -2077,7 +2078,7 @@
         if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
             // Caller wants the home activity moved with it.  To accomplish this,
             // we'll just indicate that this task returns to the home task.
-            task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
+            task.setTaskToReturnTo(ACTIVITY_TYPE_HOME);
         }
         ActivityStack currentStack = task.getStack();
         if (currentStack == null) {
@@ -2263,11 +2264,11 @@
         final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
         for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
             final TaskRecord task = tasks.get(taskNdx);
-            if (task.isHomeTask()) {
+            if (task.isActivityTypeHome()) {
                 final ArrayList<ActivityRecord> activities = task.mActivities;
                 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
                     final ActivityRecord r = activities.get(activityNdx);
-                    if (r.isHomeActivity()
+                    if (r.isActivityTypeHome()
                             && ((userId == UserHandle.USER_ALL) || (r.userId == userId))) {
                         return r;
                     }
@@ -2400,8 +2401,8 @@
                         // Update the return-to to reflect where the pinned stack task was moved
                         // from so that we retain the stack that was previously visible if the
                         // pinned stack is recreated. See moveActivityToPinnedStackLocked().
-                        task.setTaskToReturnTo(isFullscreenStackVisible && onTop ?
-                                APPLICATION_ACTIVITY_TYPE : HOME_ACTIVITY_TYPE);
+                        task.setTaskToReturnTo(isFullscreenStackVisible ?
+                                ACTIVITY_TYPE_STANDARD : ACTIVITY_TYPE_HOME);
                     }
                     // Defer resume until all the tasks have been moved to the fullscreen stack
                     task.reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
@@ -2921,7 +2922,7 @@
                 // move the home stack forward if we are currently entering picture-in-picture
                 // while pausing because that changes the focused stack and may prevent the new
                 // starting activity from resuming.
-                if (moveHomeStackToFront && task.getTaskToReturnTo() == HOME_ACTIVITY_TYPE
+                if (moveHomeStackToFront && task.returnsToHomeTask()
                         && (r.state == RESUMED || !r.supportsEnterPipOnTaskSwitch)) {
                     // Move the home stack forward if the task we just moved to the pinned stack
                     // was launched from home so home should be visible behind it.
@@ -2940,8 +2941,7 @@
                 // ensures that all the necessary work to migrate states in the old and new stacks
                 // is also done.
                 final TaskRecord newTask = task.getStack().createTaskRecord(
-                        getNextTaskIdForUserLocked(r.userId), r.info, r.intent, null, null, true,
-                        r.mActivityType);
+                        getNextTaskIdForUserLocked(r.userId), r.info, r.intent, null, null, true);
                 r.reparent(newTask, MAX_VALUE, "moveActivityToStack");
 
                 // Defer resume until below, and do not schedule PiP changes until we animate below
@@ -3013,7 +3013,7 @@
             final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                 final ActivityStack stack = stacks.get(stackNdx);
-                if (!checkActivityBelongsInStack(r, stack)) {
+                if (!r.hasCompatibleActivityType(stack)) {
                     if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping stack: (mismatch activity/stack) "
                             + stack);
                     continue;
@@ -3041,21 +3041,6 @@
         return affinityMatch;
     }
 
-    /**
-     * Checks that for the given activity {@param r}, its activity type matches the {@param stack}
-     * type.
-     */
-    private boolean checkActivityBelongsInStack(ActivityRecord r, ActivityStack stack) {
-        if (r.isHomeActivity()) {
-            return stack.isHomeStack();
-        } else if (r.isRecentsActivity()) {
-            return stack.isRecentsStack();
-        } else if (r.isAssistantActivity()) {
-            return stack.isAssistantStack();
-        }
-        return true;
-    }
-
     ActivityRecord findActivityLocked(Intent intent, ActivityInfo info,
                                       boolean compareIntentFilters) {
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
@@ -3438,7 +3423,7 @@
         if (stack == null) {
             stack = mHomeStack;
         }
-        final boolean homeInFront = stack.isHomeStack();
+        final boolean homeInFront = stack.isActivityTypeHome();
         if (stack.isOnHomeDisplay()) {
             stack.moveToFront("switchUserOnHomeDisplay");
         } else {
@@ -4038,7 +4023,7 @@
                 (preferredDisplayId != DEFAULT_DISPLAY && preferredDisplayId != INVALID_DISPLAY)
                 || StackId.isDynamicStack(preferredStackId);
         if (((!isStackDockedInEffect(actualStackId) && preferredStackId != DOCKED_STACK_ID)
-                && !isSecondaryDisplayPreferred) || task.isHomeTask()) {
+                && !isSecondaryDisplayPreferred) || task.isActivityTypeHome()) {
             return;
         }
 
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 235477e..16abcfb 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -36,6 +36,9 @@
 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 import static android.app.ActivityManager.StackId.RECENTS_STACK_ID;
 import static android.app.ActivityManager.StackId.isDynamicStack;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
 import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
@@ -72,9 +75,6 @@
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.am.ActivityManagerService.ANIMATE;
-import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
-import static com.android.server.am.ActivityRecord.ASSISTANT_ACTIVITY_TYPE;
-import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
 import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
 import static com.android.server.am.ActivityStack.STACK_INVISIBLE;
 import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
@@ -1507,7 +1507,7 @@
                 // There can be one and only one instance of single instance activity in the
                 // history, and it is always in its own unique task, so we do a special search.
                intentActivity = mSupervisor.findActivityLocked(mIntent, mStartActivity.info,
-                       mStartActivity.isHomeActivity());
+                       mStartActivity.isActivityTypeHome());
             } else if ((mLaunchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0) {
                 // For the launch adjacent case we only want to put the activity in an existing
                 // task if the activity already exists in the history.
@@ -1669,21 +1669,21 @@
         if ((launchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
                 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
             // Caller wants to appear on home activity.
-            task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
+            task.setTaskToReturnTo(ACTIVITY_TYPE_HOME);
             return;
-        } else if (focusedStack == null || focusedStack.isHomeStack()) {
+        } else if (focusedStack == null || focusedStack.isActivityTypeHome()) {
             // Task will be launched over the home stack, so return home.
-            task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
+            task.setTaskToReturnTo(ACTIVITY_TYPE_HOME);
             return;
         } else if (focusedStack != null && focusedStack != task.getStack() &&
-                focusedStack.isAssistantStack()) {
+                focusedStack.isActivityTypeAssistant()) {
             // Task was launched over the assistant stack, so return there
-            task.setTaskToReturnTo(ASSISTANT_ACTIVITY_TYPE);
+            task.setTaskToReturnTo(ACTIVITY_TYPE_ASSISTANT);
             return;
         }
 
         // Else we are coming from an application stack so return to an application.
-        task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
+        task.setTaskToReturnTo(ACTIVITY_TYPE_STANDARD);
     }
 
     private void setTaskFromIntentActivity(ActivityRecord intentActivity) {
@@ -1791,7 +1791,7 @@
                     mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId),
                     mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
                     mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
-                    mVoiceInteractor, !mLaunchTaskBehind /* toTop */, mStartActivity.mActivityType);
+                    mVoiceInteractor, !mLaunchTaskBehind /* toTop */);
             addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
             if (mLaunchBounds != null) {
                 final int stackId = mTargetStack.mStackId;
@@ -1995,7 +1995,7 @@
         final ActivityRecord prev = mTargetStack.topActivity();
         final TaskRecord task = (prev != null) ? prev.getTask() : mTargetStack.createTaskRecord(
                 mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId), mStartActivity.info,
-                mIntent, null, null, true, mStartActivity.mActivityType);
+                mIntent, null, null, true);
         addOrReparentStartingActivity(task, "setTaskToCurrentTopOrCreateNewTask");
         mTargetStack.positionChildWindowContainerAtTop(task);
         if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
@@ -2124,7 +2124,7 @@
                 canUseFocusedStack = true;
                 break;
             case ASSISTANT_STACK_ID:
-                canUseFocusedStack = r.isAssistantActivity();
+                canUseFocusedStack = r.isActivityTypeAssistant();
                 break;
             case DOCKED_STACK_ID:
                 // Any activity which supports split screen can go in the docked stack.
@@ -2155,13 +2155,13 @@
 
         // If the activity is of a specific type, return the associated stack, creating it if
         // necessary
-        if (r.isHomeActivity()) {
+        if (r.isActivityTypeHome()) {
             return mSupervisor.mHomeStack;
         }
-        if (r.isRecentsActivity()) {
+        if (r.isActivityTypeRecents()) {
             return mSupervisor.getStack(RECENTS_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
         }
-        if (r.isAssistantActivity()) {
+        if (r.isActivityTypeAssistant()) {
             return mSupervisor.getStack(ASSISTANT_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
         }
 
@@ -2254,9 +2254,9 @@
             case PINNED_STACK_ID:
                 return r.supportsPictureInPicture();
             case RECENTS_STACK_ID:
-                return r.isRecentsActivity();
+                return r.isActivityTypeRecents();
             case ASSISTANT_STACK_ID:
-                return r.isAssistantActivity();
+                return r.isActivityTypeAssistant();
             default:
                 if (StackId.isDynamicStack(stackId)) {
                     return r.canBeLaunchedOnDisplay(displayId);
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index fc03db1..d1424c8 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -55,7 +55,6 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Set;
 
 import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
@@ -676,7 +675,7 @@
                 && (mService.mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
             for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
                 final ActivityRecord r = activities.get(activityNdx);
-                if (r.isHomeActivity()) {
+                if (r.isActivityTypeHome()) {
                     Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
                     try {
                         ActivityThread.getPackageManager()
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 1578930..b09591e 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -26,6 +26,11 @@
 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 import static android.app.ActivityManager.StackId.RECENTS_STACK_ID;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
 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_RELINQUISH_TASK_IDENTITY;
@@ -44,6 +49,7 @@
 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
 import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
 import static android.view.Display.DEFAULT_DISPLAY;
+
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ADD_REMOVE;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
@@ -54,15 +60,12 @@
 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
-import static com.android.server.am.ActivityRecord.ASSISTANT_ACTIVITY_TYPE;
-import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
-import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
 import static com.android.server.am.ActivityRecord.STARTING_WINDOW_SHOWN;
 import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING;
 import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING_TO_TOP;
 import static com.android.server.am.ActivityStackSupervisor.PAUSE_IMMEDIATELY;
 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
+
 import static java.lang.Integer.MAX_VALUE;
 
 import android.annotation.IntDef;
@@ -75,6 +78,7 @@
 import android.app.ActivityOptions;
 import android.app.AppGlobals;
 import android.app.IActivityManager;
+import android.app.WindowConfiguration;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
@@ -135,6 +139,7 @@
     private static final String ATTR_USERID = "user_id";
     private static final String ATTR_USER_SETUP_COMPLETE = "user_setup_complete";
     private static final String ATTR_EFFECTIVE_UID = "effective_uid";
+    @Deprecated
     private static final String ATTR_TASKTYPE = "task_type";
     private static final String ATTR_FIRSTACTIVETIME = "first_active_time";
     private static final String ATTR_LASTACTIVETIME = "last_active_time";
@@ -248,9 +253,6 @@
     /** Current stack. Setter must always be used to update the value. */
     private ActivityStack mStack;
 
-    /** Takes on same set of values as ActivityRecord.mActivityType */
-    int taskType;
-
     /** Takes on same value as first root activity */
     boolean isPersistable = false;
     int maxRecents;
@@ -260,10 +262,11 @@
      * (positive) or back (negative). Absolute value indicates time. */
     long mLastTimeMoved = System.currentTimeMillis();
 
-    /** Indication of what to run next when task exits. Use ActivityRecord types.
-     * ActivityRecord.APPLICATION_ACTIVITY_TYPE indicates to resume the task below this one in the
-     * task stack. */
-    private int mTaskToReturnTo = APPLICATION_ACTIVITY_TYPE;
+    /** Indication of what to run next when task exits. */
+    // TODO: Shouldn't be needed if we have things in visual order. I.e. we stop using stacks or
+    // have a stack per standard application type...
+    @WindowConfiguration.ActivityType
+    private int mTaskToReturnTo = ACTIVITY_TYPE_STANDARD;
 
     /** If original intent did not allow relinquishing task identity, save that information */
     private boolean mNeverRelinquishIdentity = true;
@@ -316,7 +319,7 @@
     private TaskWindowContainerController mWindowContainerController;
 
     TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
-            IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor, int type) {
+            IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor) {
         mService = service;
         mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
                 TaskPersister.IMAGE_EXTENSION;
@@ -329,7 +332,6 @@
         mActivities = new ArrayList<>();
         mCallingUid = info.applicationInfo.uid;
         mCallingPackage = info.packageName;
-        taskType = type;
         setIntent(_intent, info);
         setMinDimensions(info);
         touchActiveTime();
@@ -358,8 +360,7 @@
         maxRecents = Math.min(Math.max(info.maxRecents, 1),
                 ActivityManager.getMaxAppRecentsLimitStatic());
 
-        taskType = APPLICATION_ACTIVITY_TYPE;
-        mTaskToReturnTo = HOME_ACTIVITY_TYPE;
+        mTaskToReturnTo = ACTIVITY_TYPE_HOME;
         lastTaskDescription = _taskDescription;
         touchActiveTime();
         mService.mTaskChangeNotificationController.notifyTaskCreated(_taskId, realActivity);
@@ -368,7 +369,7 @@
     private TaskRecord(ActivityManagerService service, int _taskId, Intent _intent,
             Intent _affinityIntent, String _affinity, String _rootAffinity,
             ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset,
-            boolean _autoRemoveRecents, boolean _askedCompatMode, int _taskType, int _userId,
+            boolean _autoRemoveRecents, boolean _askedCompatMode, int _userId,
             int _effectiveUid, String _lastDescription, ArrayList<ActivityRecord> activities,
             long _firstActiveTime, long _lastActiveTime, long lastTimeMoved,
             boolean neverRelinquishIdentity, TaskDescription _lastTaskDescription,
@@ -393,8 +394,7 @@
         isAvailable = true;
         autoRemoveRecents = _autoRemoveRecents;
         askedCompatMode = _askedCompatMode;
-        taskType = _taskType;
-        mTaskToReturnTo = HOME_ACTIVITY_TYPE;
+        mTaskToReturnTo = ACTIVITY_TYPE_HOME;
         userId = _userId;
         mUserSetupComplete = userSetupComplete;
         effectiveUid = _effectiveUid;
@@ -433,8 +433,8 @@
         final Configuration overrideConfig = getOverrideConfiguration();
         setWindowContainerController(new TaskWindowContainerController(taskId, this,
                 getStack().getWindowContainerController(), userId, bounds, overrideConfig,
-                mResizeMode, mSupportsPictureInPicture, isHomeTask(), onTop, showForAllUsers,
-                lastTaskDescription));
+                mResizeMode, mSupportsPictureInPicture, onTop,
+                showForAllUsers, lastTaskDescription));
     }
 
     /**
@@ -887,16 +887,16 @@
         return this.intent.filterEquals(intent);
     }
 
-    void setTaskToReturnTo(int taskToReturnTo) {
-        mTaskToReturnTo = (taskToReturnTo == RECENTS_ACTIVITY_TYPE)
-                ? HOME_ACTIVITY_TYPE : taskToReturnTo;
+    void setTaskToReturnTo(@WindowConfiguration.ActivityType int taskToReturnTo) {
+        mTaskToReturnTo = taskToReturnTo == ACTIVITY_TYPE_RECENTS
+                ? ACTIVITY_TYPE_HOME : taskToReturnTo;
     }
 
     void setTaskToReturnTo(ActivityRecord source) {
-        if (source.isRecentsActivity()) {
-            setTaskToReturnTo(RECENTS_ACTIVITY_TYPE);
-        } else if (source.isAssistantActivity()) {
-            setTaskToReturnTo(ASSISTANT_ACTIVITY_TYPE);
+        if (source.isActivityTypeRecents()) {
+            setTaskToReturnTo(ACTIVITY_TYPE_RECENTS);
+        } else if (source.isActivityTypeAssistant()) {
+            setTaskToReturnTo(ACTIVITY_TYPE_ASSISTANT);
         }
     }
 
@@ -904,6 +904,14 @@
         return mTaskToReturnTo;
     }
 
+    boolean returnsToHomeTask() {
+        return mTaskToReturnTo == ACTIVITY_TYPE_HOME;
+    }
+
+    boolean returnsToStandardTask() {
+        return mTaskToReturnTo == ACTIVITY_TYPE_STANDARD;
+    }
+
     void setPrevAffiliate(TaskRecord prevAffiliate) {
         mPrevAffiliate = prevAffiliate;
         mPrevAffiliateTaskId = prevAffiliate == null ? INVALID_TASK_ID : prevAffiliate.taskId;
@@ -1133,6 +1141,16 @@
         addActivityAtIndex(mActivities.size(), r);
     }
 
+    @Override
+    @WindowConfiguration.ActivityType
+    public int getActivityType() {
+        final int applicationType = super.getActivityType();
+        if (applicationType != ACTIVITY_TYPE_UNDEFINED || mActivities.isEmpty()) {
+            return applicationType;
+        }
+        return mActivities.get(0).getActivityType();
+    }
+
     /**
      * Adds an activity {@param r} at the given {@param index}. The activity {@param r} must either
      * be in the current task or unparented to any task.
@@ -1153,7 +1171,17 @@
         }
         // Only set this based on the first activity
         if (mActivities.isEmpty()) {
-            taskType = r.mActivityType;
+            // TODO: propagating this change to the WM side...Should probably be done by having
+            // ConfigurationContainer change listener that the WindowContainerController registers
+            // for.
+            if (r.getActivityType() == ACTIVITY_TYPE_UNDEFINED) {
+                // Normally non-standard activity type for the activity record will be set when the
+                // object is created, however we delay setting the standard application type until
+                // this point so that the task can set the type for additional activities added in
+                // the else condition below.
+                r.setActivityType(ACTIVITY_TYPE_STANDARD);
+            }
+            setActivityType(r.getActivityType());
             isPersistable = r.isPersistable();
             mCallingUid = r.launchedFromUid;
             mCallingPackage = r.launchedFromPackage;
@@ -1162,7 +1190,7 @@
                     ActivityManager.getMaxAppRecentsLimitStatic());
         } else {
             // Otherwise make all added activities match this one.
-            r.mActivityType = taskType;
+            r.setActivityType(getActivityType());
         }
 
         final int size = mActivities.size();
@@ -1427,28 +1455,12 @@
         return false;
     }
 
-    boolean isHomeTask() {
-        return taskType == HOME_ACTIVITY_TYPE;
-    }
-
-    boolean isRecentsTask() {
-        return taskType == RECENTS_ACTIVITY_TYPE;
-    }
-
-    boolean isAssistantTask() {
-        return taskType == ASSISTANT_ACTIVITY_TYPE;
-    }
-
-    boolean isApplicationTask() {
-        return taskType == APPLICATION_ACTIVITY_TYPE;
-    }
-
     boolean isOverHomeStack() {
-        return mTaskToReturnTo == HOME_ACTIVITY_TYPE;
+        return mTaskToReturnTo == ACTIVITY_TYPE_HOME;
     }
 
     boolean isOverAssistantStack() {
-        return mTaskToReturnTo == ASSISTANT_ACTIVITY_TYPE;
+        return mTaskToReturnTo == ACTIVITY_TYPE_ASSISTANT;
     }
 
     private boolean isResizeable(boolean checkSupportsPip) {
@@ -1642,7 +1654,6 @@
         out.attribute(null, ATTR_USERID, String.valueOf(userId));
         out.attribute(null, ATTR_USER_SETUP_COMPLETE, String.valueOf(mUserSetupComplete));
         out.attribute(null, ATTR_EFFECTIVE_UID, String.valueOf(effectiveUid));
-        out.attribute(null, ATTR_TASKTYPE, String.valueOf(taskType));
         out.attribute(null, ATTR_FIRSTACTIVETIME, String.valueOf(firstActiveTime));
         out.attribute(null, ATTR_LASTACTIVETIME, String.valueOf(lastActiveTime));
         out.attribute(null, ATTR_LASTTIMEMOVED, String.valueOf(mLastTimeMoved));
@@ -1712,7 +1723,7 @@
         boolean rootHasReset = false;
         boolean autoRemoveRecents = false;
         boolean askedCompatMode = false;
-        int taskType = ActivityRecord.APPLICATION_ACTIVITY_TYPE;
+        int taskType = 0;
         int userId = 0;
         boolean userSetupComplete = true;
         int effectiveUid = -1;
@@ -1867,7 +1878,7 @@
             // they are marked as RESIZE_MODE_RESIZEABLE to RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION
             // since we didn't have that differentiation before version 1 and the system didn't
             // resize home activities before then.
-            if (taskType == HOME_ACTIVITY_TYPE && resizeMode == RESIZE_MODE_RESIZEABLE) {
+            if (taskType == 1 /* old home type */ && resizeMode == RESIZE_MODE_RESIZEABLE) {
                 resizeMode = RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
             }
         } else {
@@ -1883,7 +1894,7 @@
 
         final TaskRecord task = new TaskRecord(stackSupervisor.mService, taskId, intent,
                 affinityIntent, affinity, rootAffinity, realActivity, origActivity, rootHasReset,
-                autoRemoveRecents, askedCompatMode, taskType, userId, effectiveUid, lastDescription,
+                autoRemoveRecents, askedCompatMode, userId, effectiveUid, lastDescription,
                 activities, firstActiveTime, lastActiveTime, lastTimeOnTop, neverRelinquishIdentity,
                 taskDescription, taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor,
                 callingUid, callingPackage, resizeMode, supportsPictureInPicture, privileged,
@@ -2105,13 +2116,13 @@
      * The task will be moved (and stack focus changed) later if necessary.
      */
     int getLaunchStackId() {
-        if (isRecentsTask()) {
+        if (isActivityTypeRecents()) {
             return RECENTS_STACK_ID;
         }
-        if (isHomeTask()) {
+        if (isActivityTypeHome()) {
             return HOME_STACK_ID;
         }
-        if (isAssistantTask()) {
+        if (isActivityTypeAssistant()) {
             return ASSISTANT_STACK_ID;
         }
         if (mBounds != null) {
@@ -2190,12 +2201,12 @@
             pw.print(prefix); pw.print("realActivity=");
             pw.println(realActivity.flattenToShortString());
         }
-        if (autoRemoveRecents || isPersistable || taskType != 0 || mTaskToReturnTo != 0
-                || numFullscreen != 0) {
+        if (autoRemoveRecents || isPersistable || !isActivityTypeStandard()
+                || mTaskToReturnTo != ACTIVITY_TYPE_STANDARD || numFullscreen != 0) {
             pw.print(prefix); pw.print("autoRemoveRecents="); pw.print(autoRemoveRecents);
                     pw.print(" isPersistable="); pw.print(isPersistable);
                     pw.print(" numFullscreen="); pw.print(numFullscreen);
-                    pw.print(" taskType="); pw.print(taskType);
+                    pw.print(" activityType="); pw.print(getActivityType());
                     pw.print(" mTaskToReturnTo="); pw.println(mTaskToReturnTo);
         }
         if (rootWasReset || mNeverRelinquishIdentity || mReuseTask
diff --git a/services/core/java/com/android/server/wm/ConfigurationContainer.java b/services/core/java/com/android/server/wm/ConfigurationContainer.java
index ace40c1..3b9d816 100644
--- a/services/core/java/com/android/server/wm/ConfigurationContainer.java
+++ b/services/core/java/com/android/server/wm/ConfigurationContainer.java
@@ -16,6 +16,13 @@
 
 package com.android.server.wm;
 
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.app.WindowConfiguration.activityTypeToString;
+
 import android.app.WindowConfiguration;
 import android.content.res.Configuration;
 
@@ -41,6 +48,9 @@
      */
     private Configuration mMergedOverrideConfiguration = new Configuration();
 
+    // TODO: Can't have ag/2592611 soon enough!
+    private final Configuration mTmpConfig = new Configuration();
+
     /**
      * Returns full configuration applied to this configuration container.
      * This method should be used for getting settings applied in each particular level of the
@@ -120,10 +130,56 @@
     }
 
     /** Sets the windowing mode for the configuration container. */
-    public void setWindowingMode(/* @WindowConfiguration.WindowingMode...triggers Jack compiler bug...*/
-            int windowingMode) {
-        mOverrideConfiguration.windowConfiguration.setWindowingMode(windowingMode);
-        onOverrideConfigurationChanged(mOverrideConfiguration);
+    public void setWindowingMode(@WindowConfiguration.WindowingMode int windowingMode) {
+        mTmpConfig.setTo(getOverrideConfiguration());
+        mTmpConfig.windowConfiguration.setWindowingMode(windowingMode);
+        onOverrideConfigurationChanged(mTmpConfig);
+    }
+
+    /** Returns the activity type associated with the the configuration container. */
+    @WindowConfiguration.ActivityType
+    public int getActivityType() {
+        return mFullConfiguration.windowConfiguration.getActivityType();
+    }
+
+    /** Sets the activity type to associate with the configuration container. */
+    public void setActivityType(@WindowConfiguration.ActivityType int activityType) {
+        int currentActivityType = getActivityType();
+        if (currentActivityType == activityType) {
+            return;
+        }
+        if (currentActivityType != ACTIVITY_TYPE_UNDEFINED) {
+            throw new IllegalStateException("Can't change activity type once set: " + this
+                    + " activityType=" + activityTypeToString(activityType));
+        }
+        mTmpConfig.setTo(getOverrideConfiguration());
+        mTmpConfig.windowConfiguration.setActivityType(activityType);
+        onOverrideConfigurationChanged(mTmpConfig);
+    }
+
+    public boolean isActivityTypeHome() {
+        return getActivityType() == ACTIVITY_TYPE_HOME;
+    }
+
+    public boolean isActivityTypeRecents() {
+        return getActivityType() == ACTIVITY_TYPE_RECENTS;
+    }
+
+    public boolean isActivityTypeAssistant() {
+        return getActivityType() == ACTIVITY_TYPE_ASSISTANT;
+    }
+
+    public boolean isActivityTypeStandard() {
+        return getActivityType() == ACTIVITY_TYPE_STANDARD;
+    }
+
+    public boolean hasCompatibleActivityType(ConfigurationContainer other) {
+        @WindowConfiguration.ActivityType int thisType = getActivityType();
+        @WindowConfiguration.ActivityType int otherType = other.getActivityType();
+
+        return thisType == otherType
+                || thisType == ACTIVITY_TYPE_UNDEFINED
+                || otherType == ACTIVITY_TYPE_UNDEFINED;
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index ce21991..030b986 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -608,8 +608,7 @@
         final TaskStack fullscreenStack =
                 mDisplayContent.getStackById(FULLSCREEN_WORKSPACE_STACK_ID);
         final boolean homeVisible = homeTask.getTopVisibleAppToken() != null;
-        final boolean homeBehind = (fullscreenStack != null && fullscreenStack.isVisible())
-                || (homeStack.hasMultipleTaskWithHomeTaskNotTop());
+        final boolean homeBehind = fullscreenStack != null && fullscreenStack.isVisible();
         setMinimizedDockedStack(homeVisible && !homeBehind, animate);
     }
 
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 60384f27..f57238e 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -97,27 +97,23 @@
     private boolean mDragResizing;
     private int mDragResizeMode;
 
-    private boolean mHomeTask;
-
     private TaskDescription mTaskDescription;
 
     // If set to true, the task will report that it is not in the floating
-    // state regardless of it's stack affilation. As the floating state drives
+    // state regardless of it's stack affiliation. As the floating state drives
     // production of content insets this can be used to preserve them across
     // stack moves and we in fact do so when moving from full screen to pinned.
     private boolean mPreserveNonFloatingState = false;
 
     Task(int taskId, TaskStack stack, int userId, WindowManagerService service, Rect bounds,
             Configuration overrideConfig, int resizeMode, boolean supportsPictureInPicture,
-            boolean homeTask, TaskDescription taskDescription,
-            TaskWindowContainerController controller) {
+            TaskDescription taskDescription, TaskWindowContainerController controller) {
         mTaskId = taskId;
         mStack = stack;
         mUserId = userId;
         mService = service;
         mResizeMode = resizeMode;
         mSupportsPictureInPicture = supportsPictureInPicture;
-        mHomeTask = homeTask;
         setController(controller);
         setBounds(bounds, overrideConfig);
         mTaskDescription = taskDescription;
@@ -370,10 +366,6 @@
         return isResizeable();
     }
 
-    boolean isHomeTask() {
-        return mHomeTask;
-    }
-
     boolean resizeLocked(Rect bounds, Configuration overrideConfig, boolean forced) {
         int boundsChanged = setBounds(bounds, overrideConfig);
         if (forced) {
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 1a6e2c8..33eb0a9 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -18,18 +18,9 @@
 
 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT;
-import static android.app.ActivityManager.StackId.ASSISTANT_STACK_ID;
 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
-import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
-import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
-import static android.app.ActivityManager.StackId.RECENTS_STACK_ID;
-import static android.app.WindowConfiguration.WINDOWING_MODE_DOCKED;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
 import static android.content.res.Configuration.DENSITY_DPI_UNDEFINED;
 import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
@@ -52,7 +43,6 @@
 import static com.android.server.wm.proto.StackProto.TASKS;
 
 import android.app.ActivityManager.StackId;
-import android.app.WindowConfiguration;
 import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.graphics.Region;
@@ -170,20 +160,10 @@
     }
 
     Task findHomeTask() {
-        if (mStackId != HOME_STACK_ID) {
+        if (!isActivityTypeHome() || mChildren.isEmpty()) {
             return null;
         }
-
-        for (int i = mChildren.size() - 1; i >= 0; i--) {
-            if (mChildren.get(i).isHomeTask()) {
-                return mChildren.get(i);
-            }
-        }
-        return null;
-    }
-
-    boolean hasMultipleTaskWithHomeTaskNotTop() {
-        return mChildren.size() > 1 && !mChildren.get(mChildren.size() - 1).isHomeTask();
+        return mChildren.get(mChildren.size() - 1);
     }
 
     /**
@@ -1470,7 +1450,7 @@
              * small portion which the home stack currently is resized to.
              */
 
-            if (task.isHomeTask() && isMinimizedDockAndHomeStackResizable()) {
+            if (task.isActivityTypeHome() && isMinimizedDockAndHomeStackResizable()) {
                 mDisplayContent.getLogicalDisplayRect(mTmpRect);
             } else {
                 task.getDimBounds(mTmpRect);
diff --git a/services/core/java/com/android/server/wm/TaskWindowContainerController.java b/services/core/java/com/android/server/wm/TaskWindowContainerController.java
index 54a6cc0..d8929c9 100644
--- a/services/core/java/com/android/server/wm/TaskWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/TaskWindowContainerController.java
@@ -51,18 +51,17 @@
     public TaskWindowContainerController(int taskId, TaskWindowContainerListener listener,
             StackWindowController stackController, int userId, Rect bounds,
             Configuration overrideConfig, int resizeMode, boolean supportsPictureInPicture,
-            boolean homeTask, boolean toTop, boolean showForAllUsers,
-            TaskDescription taskDescription) {
+            boolean toTop, boolean showForAllUsers, TaskDescription taskDescription) {
         this(taskId, listener, stackController, userId, bounds, overrideConfig, resizeMode,
-                supportsPictureInPicture, homeTask, toTop, showForAllUsers, taskDescription,
+                supportsPictureInPicture, toTop, showForAllUsers, taskDescription,
                 WindowManagerService.getInstance());
     }
 
     public TaskWindowContainerController(int taskId, TaskWindowContainerListener listener,
             StackWindowController stackController, int userId, Rect bounds,
             Configuration overrideConfig, int resizeMode, boolean supportsPictureInPicture,
-            boolean homeTask, boolean toTop, boolean showForAllUsers,
-            TaskDescription taskDescription, WindowManagerService service) {
+            boolean toTop, boolean showForAllUsers, TaskDescription taskDescription,
+            WindowManagerService service) {
         super(listener, service);
         mTaskId = taskId;
         mHandler = new H(new WeakReference<>(this), service.mH.getLooper());
@@ -78,7 +77,7 @@
             }
             EventLog.writeEvent(WM_TASK_CREATED, taskId, stack.mStackId);
             final Task task = createTask(taskId, stack, userId, bounds, overrideConfig, resizeMode,
-                    supportsPictureInPicture, homeTask, taskDescription);
+                    supportsPictureInPicture, taskDescription);
             final int position = toTop ? POSITION_TOP : POSITION_BOTTOM;
             // We only want to move the parents to the parents if we are creating this task at the
             // top of its stack.
@@ -89,9 +88,9 @@
     @VisibleForTesting
     Task createTask(int taskId, TaskStack stack, int userId, Rect bounds,
             Configuration overrideConfig, int resizeMode, boolean supportsPictureInPicture,
-            boolean homeTask, TaskDescription taskDescription) {
+            TaskDescription taskDescription) {
         return new Task(taskId, stack, userId, mService, bounds, overrideConfig, resizeMode,
-                supportsPictureInPicture, homeTask, taskDescription, this);
+                supportsPictureInPicture, taskDescription, this);
     }
 
     @Override
diff --git a/services/tests/servicestests/src/com/android/server/wm/ConfigurationContainerTests.java b/services/tests/servicestests/src/com/android/server/wm/ConfigurationContainerTests.java
index 0f9b721..d441df0 100644
--- a/services/tests/servicestests/src/com/android/server/wm/ConfigurationContainerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/ConfigurationContainerTests.java
@@ -16,23 +16,29 @@
 
 package com.android.server.wm;
 
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import android.content.res.Configuration;
-import android.platform.test.annotations.Presubmit;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-
-import java.util.ArrayList;
-import java.util.List;
-
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.content.res.Configuration;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Test class for {@link ConfigurationContainer}.
@@ -201,6 +207,62 @@
         assertEquals(mergedConfig2, child2.getConfiguration());
     }
 
+    @Test
+    public void testSetWindowingMode() throws Exception {
+        final TestConfigurationContainer root = new TestConfigurationContainer();
+        root.setWindowingMode(WINDOWING_MODE_UNDEFINED);
+        final TestConfigurationContainer child = root.addChild();
+        child.setWindowingMode(WINDOWING_MODE_FREEFORM);
+        assertEquals(WINDOWING_MODE_UNDEFINED, root.getWindowingMode());
+        assertEquals(WINDOWING_MODE_FREEFORM, child.getWindowingMode());
+
+        root.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+        assertEquals(WINDOWING_MODE_FULLSCREEN, root.getWindowingMode());
+        assertEquals(WINDOWING_MODE_FREEFORM, child.getWindowingMode());
+    }
+
+    @Test
+    public void testSetActivityType() throws Exception {
+        final TestConfigurationContainer root = new TestConfigurationContainer();
+        root.setActivityType(ACTIVITY_TYPE_UNDEFINED);
+        final TestConfigurationContainer child = root.addChild();
+        child.setActivityType(ACTIVITY_TYPE_STANDARD);
+        assertEquals(ACTIVITY_TYPE_UNDEFINED, root.getActivityType());
+        assertEquals(ACTIVITY_TYPE_STANDARD, child.getActivityType());
+
+        boolean gotException = false;
+        try {
+            // Can't change activity type once set.
+            child.setActivityType(ACTIVITY_TYPE_HOME);
+        } catch (IllegalStateException e) {
+            gotException = true;
+        }
+        assertTrue("Can't change activity type once set.", gotException);
+
+        gotException = false;
+        try {
+            // Parent can't change child's activity type once set.
+            root.setActivityType(ACTIVITY_TYPE_HOME);
+        } catch (IllegalStateException e) {
+            gotException = true;
+        }
+        assertTrue("Parent can't change activity type once set.", gotException);
+        assertEquals(ACTIVITY_TYPE_HOME, root.getActivityType());
+
+        final TestConfigurationContainer child2 = new TestConfigurationContainer();
+        child2.setActivityType(ACTIVITY_TYPE_RECENTS);
+
+        gotException = false;
+        try {
+            // Can't re-parent to a different activity type.
+            root.addChild(child2);
+        } catch (IllegalStateException e) {
+            gotException = true;
+        }
+        assertTrue("Can't re-parent to a different activity type.", gotException);
+
+    }
+
     /**
      * Contains minimal implementation of {@link ConfigurationContainer}'s abstract behavior needed
      * for testing.
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowConfigurationTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowConfigurationTests.java
index a1ff2d7..3f75b41 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowConfigurationTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowConfigurationTests.java
@@ -27,8 +27,9 @@
 import android.view.DisplayInfo;
 
 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOW_CONFIG_APP_BOUNDS;
 import static android.app.WindowConfiguration.WINDOW_CONFIG_WINDOWING_MODE;
 import static android.content.pm.ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
@@ -118,6 +119,22 @@
         assertEquals(blankWinConfig.compareTo(winConfig1), 1);
     }
 
+    @Test
+    public void testSetActivityType() throws Exception {
+        final WindowConfiguration config = new WindowConfiguration();
+        config.setActivityType(ACTIVITY_TYPE_HOME);
+        assertEquals(ACTIVITY_TYPE_HOME, config.getActivityType());
+
+        boolean gotException = false;
+        try {
+            // Can't change activity type once set.
+            config.setActivityType(ACTIVITY_TYPE_STANDARD);
+        } catch (IllegalStateException e) {
+            gotException = true;
+        }
+        assertTrue("Can't change activity type once set.", gotException);
+    }
+
     /** Ensures the configuration app bounds at the root level match the app dimensions. */
     @Test
     public void testAppBounds_RootConfigurationBounds() throws Exception {
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
index 6e253e7..df3f755 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
@@ -75,7 +75,7 @@
         final Rect mInsetBounds = new Rect();
         boolean mFullscreenForTest = true;
         TaskWithBounds(Rect bounds) {
-            super(0, mStubStack, 0, sWm, null, null, 0, false, false, new TaskDescription(), null);
+            super(0, mStubStack, 0, sWm, null, null, 0, false, new TaskDescription(), null);
             mBounds = bounds;
         }
         @Override
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
index 40c79bb..ebe00ce 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
@@ -67,7 +67,7 @@
     public static Task createTaskInStack(WindowManagerService service, TaskStack stack,
             int userId) {
         final Task newTask = new Task(sNextTaskId++, stack, userId, service, null, EMPTY, 0, false,
-                false, new ActivityManager.TaskDescription(), null);
+                new ActivityManager.TaskDescription(), null);
         stack.addTask(newTask, POSITION_TOP);
         return newTask;
     }
@@ -175,10 +175,9 @@
 
         TestTask(int taskId, TaskStack stack, int userId, WindowManagerService service, Rect bounds,
                 Configuration overrideConfig, int resizeMode, boolean supportsPictureInPicture,
-                boolean homeTask, TaskWindowContainerController controller) {
+                TaskWindowContainerController controller) {
             super(taskId, stack, userId, service, bounds, overrideConfig, resizeMode,
-                    supportsPictureInPicture, homeTask, new ActivityManager.TaskDescription(),
-                    controller);
+                    supportsPictureInPicture, new ActivityManager.TaskDescription(), controller);
         }
 
         boolean shouldDeferRemoval() {
@@ -229,7 +228,7 @@
                         }
                     }, stackController, 0 /* userId */, null /* bounds */,
                     EMPTY /* overrideConfig*/, RESIZE_MODE_UNRESIZEABLE,
-                    false /* supportsPictureInPicture */, false /* homeTask*/, true /* toTop*/,
+                    false /* supportsPictureInPicture */, true /* toTop*/,
                     true /* showForAllUsers */, new ActivityManager.TaskDescription(),
                     stackController.mService);
         }
@@ -237,9 +236,9 @@
         @Override
         TestTask createTask(int taskId, TaskStack stack, int userId, Rect bounds,
                 Configuration overrideConfig, int resizeMode, boolean supportsPictureInPicture,
-                boolean homeTask, ActivityManager.TaskDescription taskDescription) {
+                ActivityManager.TaskDescription taskDescription) {
             return new TestTask(taskId, stack, userId, mService, bounds, overrideConfig, resizeMode,
-                    supportsPictureInPicture, homeTask, this);
+                    supportsPictureInPicture, this);
         }
     }