Merge "Fix Wear brightness after tilt-to-wake" into main
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index e28a6ce..5843e51 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -1253,10 +1253,14 @@
     public abstract boolean clearApplicationUserData(String packageName, boolean keepState,
             boolean isRestore, IPackageDataObserver observer, int userId);
 
+
     /**
-     * Returns current state of {@link com.android.systemui.theme.ThemeOverlayController} color
-     * palette readiness.
+     * Method that checks if system is Headless (don't delay launch) case in which it
+     * should also check if ThemeOverlayController is ready (don't delay) or not (delay).
+     *
+     * @param userId
+     * @return Boolean indicating if Home launch should wait for ThemeOverlayController signal
      * @hide
      */
-    public abstract boolean isThemeOverlayReady(int userId);
+    public abstract boolean shouldDelayHomeLaunch(int userId);
 }
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 5b28f50..a075ac5 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -12749,6 +12749,10 @@
      * <li>{@link android.provider.Settings.System#SCREEN_OFF_TIMEOUT}</li>
      * </ul>
      * <p>
+     * Starting from Android {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM}, a
+     * profile owner on an organization-owned device can call this method on the parent
+     * {@link DevicePolicyManager} instance returned by
+     * {@link #getParentProfileInstance(ComponentName)} to set system settings on the parent user.
      *
      * @see android.provider.Settings.System#SCREEN_OFF_TIMEOUT
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
@@ -12758,10 +12762,9 @@
      */
     public void setSystemSetting(@NonNull ComponentName admin,
             @NonNull @SystemSettingsWhitelist String setting, String value) {
-        throwIfParentInstance("setSystemSetting");
         if (mService != null) {
             try {
-                mService.setSystemSetting(admin, setting, value);
+                mService.setSystemSetting(admin, setting, value, mParentInstance);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index aea0246..d4589dc 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -316,7 +316,7 @@
     int getLockTaskFeatures(in ComponentName who, String callerPackageName);
 
     void setGlobalSetting(in ComponentName who, in String setting, in String value);
-    void setSystemSetting(in ComponentName who, in String setting, in String value);
+    void setSystemSetting(in ComponentName who, in String setting, in String value, boolean parent);
     void setSecureSetting(in ComponentName who, in String setting, in String value);
 
     void setConfiguredNetworksLockdownState(in ComponentName who, String callerPackageName, boolean lockdown);
diff --git a/core/java/android/app/admin/flags/flags.aconfig b/core/java/android/app/admin/flags/flags.aconfig
index c29ea6d..441d521 100644
--- a/core/java/android/app/admin/flags/flags.aconfig
+++ b/core/java/android/app/admin/flags/flags.aconfig
@@ -173,3 +173,10 @@
       purpose: PURPOSE_BUGFIX
     }
 }
+
+flag {
+  name: "allow_screen_brightness_control_on_cope"
+  namespace: "enterprise"
+  description: "Allow COPE admin to control screen brightness and timeout."
+  bug: "323894620"
+}
diff --git a/core/java/android/window/DisplayAreaOrganizer.java b/core/java/android/window/DisplayAreaOrganizer.java
index 0110136..84ce247 100644
--- a/core/java/android/window/DisplayAreaOrganizer.java
+++ b/core/java/android/window/DisplayAreaOrganizer.java
@@ -112,6 +112,15 @@
     public static final int FEATURE_IME = FEATURE_SYSTEM_FIRST + 8;
 
     /**
+     * Display area that includes all areas which can have windows. It is used to separate the
+     * window content to provide the ability of display level animation and display recording.
+     * It is usually only a placeholder that organizer should not control it. This only exists
+     * if {@link #FEATURE_WINDOWED_MAGNIFICATION} is not available to be the windowing layer.
+     * @hide
+     */
+    public static final int FEATURE_WINDOWING_LAYER = FEATURE_SYSTEM_FIRST + 9;
+
+    /**
      * The last boundary of display area for system features
      */
     public static final int FEATURE_SYSTEM_LAST = 10_000;
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayApplier.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayApplier.java
index 147e158..de2fb67 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayApplier.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayApplier.java
@@ -15,7 +15,6 @@
  */
 package com.android.systemui.theme;
 
-import static com.android.systemui.shared.Flags.enableHomeDelay;
 
 import android.annotation.AnyThread;
 import android.content.om.FabricatedOverlay;
@@ -251,7 +250,7 @@
 
             try {
                 mOverlayManager.commit(transaction.build());
-                if (enableHomeDelay() && onComplete != null) {
+                if (onComplete != null) {
                     Log.d(TAG, "Executing onComplete runnable");
                     mMainExecutor.execute(onComplete);
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
index aac18e3..5c3bbb7 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
@@ -20,7 +20,6 @@
 
 import static com.android.systemui.Flags.themeOverlayControllerWakefulnessDeprecation;
 import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP;
-import static com.android.systemui.shared.Flags.enableHomeDelay;
 import static com.android.systemui.theme.ThemeOverlayApplier.COLOR_SOURCE_HOME;
 import static com.android.systemui.theme.ThemeOverlayApplier.COLOR_SOURCE_LOCK;
 import static com.android.systemui.theme.ThemeOverlayApplier.COLOR_SOURCE_PRESET;
@@ -775,12 +774,11 @@
             }
         }
 
-        final Runnable onCompleteCallback = !enableHomeDelay()
-                ? () -> {}
-                : () -> {
-                    Log.d(TAG, "ThemeHomeDelay: ThemeOverlayController ready");
-                    mActivityManager.setThemeOverlayReady(currentUser);
-                };
+        final Runnable onCompleteCallback = () -> {
+            Log.d(TAG, "ThemeHomeDelay: ThemeOverlayController ready with user "
+                    + currentUser);
+            mActivityManager.setThemeOverlayReady(currentUser);
+        };
 
         if (colorSchemeIsApplied(managedProfiles)) {
             Log.d(TAG, "Skipping overlay creation. Theme was already: " + mColorScheme);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index f1195f3..03ab5b3 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -5283,18 +5283,24 @@
      * Starts Home if there is no completion signal from ThemeOverlayController
      */
     private void scheduleHomeTimeout() {
-        if (enableHomeDelay() && mHasHomeDelay.compareAndSet(false, true)) {
-            int userId = mUserController.getCurrentUserId();
-            mHandler.postDelayed(() -> {
-                if (!isThemeOverlayReady(userId)) {
-                    Slog.d(TAG,
-                            "ThemeHomeDelay: ThemeOverlayController not responding, launching "
-                                    + "Home after "
-                                    + HOME_LAUNCH_TIMEOUT_MS + "ms");
-                    setThemeOverlayReady(userId);
-                }
-            }, HOME_LAUNCH_TIMEOUT_MS);
+        if (!isHomeLaunchDelayable()) {
+            Slog.d(TAG, "ThemeHomeDelay: Home launch is not delayable, skipping timeout creation");
+            return;
         }
+
+        if (!mHasHomeDelay.compareAndSet(false, true)) return;
+
+        mHandler.postDelayed(() -> {
+            int userId = mUserController.getCurrentUserId();
+            if (!isThemeOverlayReady(userId)) {
+                Slog.d(TAG,
+                        "ThemeHomeDelay: ThemeOverlayController not responding, launching "
+                                + "Home after " + HOME_LAUNCH_TIMEOUT_MS + "ms"
+                                + " with user " + userId);
+                setThemeOverlayReady(userId);
+            }
+        }, HOME_LAUNCH_TIMEOUT_MS);
+
     }
 
     /**
@@ -5302,22 +5308,28 @@
      * palette is ready.
      *
      * @param userId The ID of the user where ThemeOverlayController is ready.
-     *
-     * @throws RemoteException
-     *
      * @hide
      */
     @Override
     public void setThemeOverlayReady(@UserIdInt int userId) {
+        if (!isHomeLaunchDelayable()) {
+            Slog.d(TAG, "ThemeHomeDelay: Home launch is not delayable, "
+                    + "ignoring setThemeOverlayReady() call");
+            return;
+        }
+
         enforceCallingPermission(Manifest.permission.SET_THEME_OVERLAY_CONTROLLER_READY,
                 "setThemeOverlayReady");
-
+        Slog.d(TAG, "ThemeHomeDelay: userId " + userId
+                + " notified ThemeOverlayController completeness");
         boolean updateUser;
         synchronized (mThemeOverlayReadyUsers) {
             updateUser = mThemeOverlayReadyUsers.add(userId);
+            Slog.d(TAG, "ThemeHomeDelay: updateUser " + userId + " isUpdatable: " + updateUser);
         }
 
-        if (updateUser && enableHomeDelay()) {
+        if (updateUser) {
+            Slog.d(TAG, "ThemeHomeDelay: updating user " + userId);
             mAtmInternal.startHomeOnAllDisplays(userId, "setThemeOverlayReady");
         }
     }
@@ -5334,6 +5346,16 @@
         }
     }
 
+    /**
+     * Checks if feature flag is enabled and if system is Headless (HSUM), case in which 
+     * home delay should be skipped.
+     *
+     * @hide
+     */
+    public boolean isHomeLaunchDelayable() {
+        return !UserManager.isHeadlessSystemUserMode() && enableHomeDelay();
+    }
+
     final void ensureBootCompleted() {
         boolean booting;
         boolean enableScreen;
@@ -18142,8 +18164,10 @@
             // Clean up various services by removing the user
             mBatteryStatsService.onUserRemoved(userId);
 
-            synchronized (mThemeOverlayReadyUsers) {
-                mThemeOverlayReadyUsers.remove(userId);
+            if (isHomeLaunchDelayable()) {
+                synchronized (mThemeOverlayReadyUsers) {
+                    mThemeOverlayReadyUsers.remove(userId);
+                }
             }
         }
 
@@ -19496,8 +19520,12 @@
         }
 
         @Override
-        public boolean isThemeOverlayReady(int userId) {
-            return ActivityManagerService.this.isThemeOverlayReady(userId);
+        public boolean shouldDelayHomeLaunch(int userId) {
+            if (!isHomeLaunchDelayable()) return false;
+
+            synchronized (mThemeOverlayReadyUsers) {
+                return !ActivityManagerService.this.mThemeOverlayReadyUsers.contains(userId);
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
index 1919137..73e7485 100644
--- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
+++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
@@ -270,7 +270,7 @@
      * Special user restrictions that profile owner of an organization-owned managed profile can
      * set on the parent profile instance to apply them on the personal profile.
      */
-    private static final Set<String> PROFILE_OWNER_ORGANIZATION_OWNED_LOCAL_RESTRICTIONS =
+    private static final Set<String> PROFILE_OWNER_ORGANIZATION_OWNED_PARENT_LOCAL_RESTRICTIONS =
             Sets.newArraySet(
                     UserManager.DISALLOW_CONFIG_BLUETOOTH,
                     UserManager.DISALLOW_CONFIG_LOCATION,
@@ -293,7 +293,9 @@
                     UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,
                     UserManager.DISALLOW_UNMUTE_MICROPHONE,
                     UserManager.DISALLOW_CONFIG_DEFAULT_APPS,
-                    UserManager.DISALLOW_ADD_PRIVATE_PROFILE
+                    UserManager.DISALLOW_ADD_PRIVATE_PROFILE,
+                    UserManager.DISALLOW_CONFIG_BRIGHTNESS,
+                    UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT
     );
 
     /**
@@ -536,7 +538,7 @@
     public static boolean canParentOfProfileOwnerOfOrganizationOwnedDeviceChange(
             String restriction) {
         return PROFILE_OWNER_ORGANIZATION_OWNED_PARENT_GLOBAL_RESTRICTIONS.contains(restriction)
-                || PROFILE_OWNER_ORGANIZATION_OWNED_LOCAL_RESTRICTIONS.contains(restriction);
+                || PROFILE_OWNER_ORGANIZATION_OWNED_PARENT_LOCAL_RESTRICTIONS.contains(restriction);
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/DisplayAreaPolicy.java b/services/core/java/com/android/server/wm/DisplayAreaPolicy.java
index c18377d..efeb85f 100644
--- a/services/core/java/com/android/server/wm/DisplayAreaPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayAreaPolicy.java
@@ -84,6 +84,11 @@
     public abstract List<DisplayArea<? extends WindowContainer>> getDisplayAreas(int featureId);
 
     /**
+     * Returns the {@link DisplayArea} that is used to put all window content.
+     */
+    public abstract DisplayArea<? extends WindowContainer> getWindowingArea();
+
+    /**
      * @return the default/fallback {@link TaskDisplayArea} on the display.
      */
     public abstract TaskDisplayArea getDefaultTaskDisplayArea();
diff --git a/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java b/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java
index f49e64e..8c52288 100644
--- a/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java
+++ b/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java
@@ -25,6 +25,8 @@
 import static android.view.WindowManagerPolicyConstants.APPLICATION_LAYER;
 import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER;
 import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_LAST;
+import static android.window.DisplayAreaOrganizer.FEATURE_WINDOWED_MAGNIFICATION;
+import static android.window.DisplayAreaOrganizer.FEATURE_WINDOWING_LAYER;
 import static android.window.DisplayAreaOrganizer.KEY_ROOT_DISPLAY_AREA_ID;
 
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER;
@@ -254,6 +256,10 @@
             throw new IllegalStateException("There must be a default TaskDisplayArea with id of "
                     + "FEATURE_DEFAULT_TASK_CONTAINER.");
         }
+
+        if (!mRootHierarchyBuilder.hasValidWindowingLayer()) {
+            throw new IllegalStateException("WindowingLayer must exist at the top level index");
+        }
     }
 
     /** Checks if the given hierarchy contains the default {@link TaskDisplayArea}. */
@@ -267,6 +273,11 @@
         return false;
     }
 
+    /** Returns {@code true} if the feature id can be used to put all window content. */
+    static boolean canBeWindowingLayer(int featureId) {
+        return featureId == FEATURE_WINDOWED_MAGNIFICATION || featureId == FEATURE_WINDOWING_LAYER;
+    }
+
     /**
      * Makes sure that ids meet requirement.
      * {@link RootDisplayArea} and {@link TaskDisplayArea} must have unique ids.
@@ -329,6 +340,12 @@
     }
 
     Result build(WindowManagerService wmService) {
+        if (mRootHierarchyBuilder != null && !mRootHierarchyBuilder.hasValidWindowingLayer()) {
+            // Need an additional top layer for screen level animation.
+            mRootHierarchyBuilder.mFeatures.add(0 /* top level index */, new Feature.Builder(
+                    wmService.mPolicy, "WindowingLayer", FEATURE_WINDOWING_LAYER)
+                    .setExcludeRoundedCornerOverlay(false).all().build());
+        }
         validate();
 
         // Attach DA group roots to screen hierarchy before adding windows to group hierarchies.
@@ -624,6 +641,11 @@
             }
         }
 
+        boolean hasValidWindowingLayer() {
+            // The windowing layer feature can only be the first one as the top hierarchy.
+            return !mFeatures.isEmpty() && canBeWindowingLayer(mFeatures.get(0).mId);
+        }
+
         private static int typeOfLayer(WindowManagerPolicy policy, int layer) {
             if (layer == APPLICATION_LAYER) {
                 return LEAF_TYPE_TASK_CONTAINERS;
@@ -866,6 +888,23 @@
         }
 
         @Override
+        public DisplayArea<? extends WindowContainer> getWindowingArea() {
+            if (mRoot.mFeatures.isEmpty()) {
+                throw new IllegalStateException("There must be at least one feature.");
+            }
+            final Feature feature = mRoot.mFeatures.get(0);
+            if (canBeWindowingLayer(feature.mId)) {
+                final List<DisplayArea<WindowContainer>> areas =
+                        mRoot.mFeatureToDisplayAreas.get(feature);
+                if (areas.size() == 1) {
+                    return areas.get(0);
+                }
+            }
+            throw new IllegalStateException("There must be exactly one DisplayArea at top for the "
+                    + "FEATURE_WINDOWED_MAGNIFICATION or FEATURE_WINDOWING_LAYER");
+        }
+
+        @Override
         public TaskDisplayArea getDefaultTaskDisplayArea() {
             return mDefaultTaskDisplayArea;
         }
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 1dcfde4..eb1f052 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -87,7 +87,6 @@
 import static android.view.inputmethod.ImeTracker.DEBUG_IME_VISIBILITY;
 import static android.window.DisplayAreaOrganizer.FEATURE_IME;
 import static android.window.DisplayAreaOrganizer.FEATURE_ROOT;
-import static android.window.DisplayAreaOrganizer.FEATURE_WINDOWED_MAGNIFICATION;
 
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_BOOT;
@@ -340,12 +339,6 @@
     private SurfaceControl mA11yOverlayLayer;
 
     /**
-     * The direct child layer of the display to put all non-overlay windows. This is also used for
-     * screen rotation animation so that there is a parent layer to put the animation leash.
-     */
-    private SurfaceControl mWindowingLayer;
-
-    /**
      * Delegate for handling all logic around content recording; decides if this DisplayContent is
      * recording, and if so, applies necessary updates to SurfaceFlinger.
      */
@@ -365,7 +358,7 @@
     private final ImeContainer mImeWindowsContainer = new ImeContainer(mWmService);
 
     @VisibleForTesting
-    DisplayAreaPolicy mDisplayAreaPolicy;
+    final DisplayAreaPolicy mDisplayAreaPolicy;
 
     private WindowState mTmpWindow;
     private boolean mUpdateImeTarget;
@@ -1245,6 +1238,10 @@
         mWindowCornerRadius = mDisplayPolicy.getWindowCornerRadius();
         mPinnedTaskController = new PinnedTaskController(mWmService, this);
 
+        // Set up the policy and build the display area hierarchy.
+        // Build the hierarchy only after creating the surface, so it is reparented correctly
+        mDisplayAreaPolicy = mWmService.getDisplayAreaPolicyProvider().instantiate(
+                mWmService, this /* content */, this /* root */, mImeWindowsContainer);
         final Transaction pendingTransaction = getPendingTransaction();
         configureSurfaces(pendingTransaction);
         pendingTransaction.apply();
@@ -1315,14 +1312,6 @@
         mLastDeltaRotation = Surface.ROTATION_0;
 
         configureSurfaces(t);
-
-        for (int i = 0; i < mChildren.size(); i++)  {
-            SurfaceControl sc = mChildren.get(i).getSurfaceControl();
-            if (sc != null) {
-                t.reparent(sc, getParentingSurfaceControl());
-            }
-        }
-
         scheduleAnimation();
     }
 
@@ -1338,31 +1327,11 @@
                 .setContainerLayer()
                 .setCallsite("DisplayContent");
         mSurfaceControl = b.setName(getName()).setContainerLayer().build();
-
-        if (mDisplayAreaPolicy == null) {
-            // Setup the policy and build the display area hierarchy.
-            // Build the hierarchy only after creating the surface so it is reparented correctly
-            mDisplayAreaPolicy = mWmService.getDisplayAreaPolicyProvider().instantiate(
-                    mWmService, this /* content */, this /* root */,
-                    mImeWindowsContainer);
-        }
-
-        final List<DisplayArea<? extends WindowContainer>> areas =
-                mDisplayAreaPolicy.getDisplayAreas(FEATURE_WINDOWED_MAGNIFICATION);
-        final DisplayArea<?> area = areas.size() == 1 ? areas.get(0) : null;
-
-        if (area != null && area.getParent() == this) {
-            // The windowed magnification area should contain all non-overlay windows, so just use
-            // it as the windowing layer.
-            mWindowingLayer = area.mSurfaceControl;
-            transaction.reparent(mWindowingLayer, mSurfaceControl);
-        } else {
-            // Need an additional layer for screen level animation, so move the layer containing
-            // the windows to the new root.
-            mWindowingLayer = mSurfaceControl;
-            mSurfaceControl = b.setName("RootWrapper").build();
-            transaction.reparent(mWindowingLayer, mSurfaceControl)
-                    .show(mWindowingLayer);
+        for (int i = getChildCount() - 1; i >= 0; i--)  {
+            final SurfaceControl sc = getChildAt(i).mSurfaceControl;
+            if (sc != null) {
+                transaction.reparent(sc, mSurfaceControl);
+            }
         }
 
         if (mOverlayLayer == null) {
@@ -1385,7 +1354,6 @@
         }
 
         transaction
-                .setLayer(mSurfaceControl, 0)
                 .setLayerStack(mSurfaceControl, mDisplayId)
                 .show(mSurfaceControl)
                 .setLayer(mOverlayLayer, Integer.MAX_VALUE)
@@ -3461,7 +3429,6 @@
             mOverlayLayer.release();
             mInputOverlayLayer.release();
             mA11yOverlayLayer.release();
-            mWindowingLayer.release();
             mInputMonitor.onDisplayRemoved();
             mWmService.mDisplayNotificationController.dispatchDisplayRemoved(this);
             mDisplayRotation.onDisplayRemoved();
@@ -5490,11 +5457,6 @@
             return b;
         }
 
-        // WARNING: it says `mSurfaceControl` below, but this CHANGES meaning after construction!
-        // DisplayAreas are added in `configureSurface()` *before* `mSurfaceControl` gets replaced
-        // with a wrapper or magnification surface so they end up in the right place; however,
-        // anything added or reparented to "the display" *afterwards* needs to be reparented to
-        // `getWindowinglayer()` (unless it's an overlay DisplayArea).
         return b.setName(child.getName())
                 .setParent(mSurfaceControl);
     }
@@ -5838,22 +5800,11 @@
     }
 
     /**
-     * Returns the {@link SurfaceControl} where all the children should be parented on.
-     *
-     * <p> {@link DisplayContent} inserts a RootWrapper leash in the hierarchy above its original
-     * {@link #mSurfaceControl} and then overrides the {@link #mSurfaceControl} to point to the
-     * RootWrapper.
-     * <p> To prevent inconsistent state later where the DAs might get re-parented to the
-     * RootWrapper, this method should be used which returns the correct surface where the
-     * re-parenting should happen.
+     * The direct child layer of the display to put all non-overlay windows. This is also used for
+     * screen rotation animation so that there is a parent layer to put the animation leash.
      */
-    @Override
-    SurfaceControl getParentingSurfaceControl() {
-        return mWindowingLayer;
-    }
-
     SurfaceControl getWindowingLayer() {
-        return mWindowingLayer;
+        return mDisplayAreaPolicy.getWindowingArea().mSurfaceControl;
     }
 
     DisplayArea.Tokens getImeContainer() {
@@ -7257,7 +7208,6 @@
 
     public void replaceContent(SurfaceControl sc) {
         new Transaction().reparent(sc, getSurfaceControl())
-                .reparent(mWindowingLayer, null)
                 .reparent(mOverlayLayer, null)
                 .reparent(mInputOverlayLayer, null)
                 .reparent(mA11yOverlayLayer, null)
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 445a5c8..d66005f 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -83,7 +83,6 @@
 import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_NONE;
 import static com.android.server.wm.WindowSurfacePlacer.SET_UPDATE_ROTATION;
 import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_ACTION_PENDING;
-import static com.android.systemui.shared.Flags.enableHomeDelay;
 
 import static java.lang.Integer.MAX_VALUE;
 
@@ -1452,8 +1451,8 @@
             return false;
         }
 
-        if (enableHomeDelay() && !mService.mAmInternal.isThemeOverlayReady(userId)) {
-            Slog.d(TAG, "ThemeHomeDelay: Home launch was deferred.");
+        if (mService.mAmInternal.shouldDelayHomeLaunch(userId)) {
+            Slog.d(TAG, "ThemeHomeDelay: Home launch was deferred with user " + userId);
             return false;
         }
 
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 6d8b030..66c2e53 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -2542,12 +2542,6 @@
             // DisplayContent is the "root", so we reinterpret it's wc as the window layer
             // making the parent surface the displaycontent's surface.
             return wc.getSurfaceControl();
-        } else if (wc.getParent().asDisplayContent() != null) {
-            // DisplayContent is kinda split into 2 pieces, the "real root" and the
-            // "windowing layer". So if the parent of the window is DC, then it really belongs on
-            // the windowing layer (unless it's an overlay display area, but those can't be in
-            // transitions anyways).
-            return wc.getParent().asDisplayContent().getWindowingLayer();
         }
         return wc.getParent().getSurfaceControl();
     }
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index f2af852..e01842c 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -716,7 +716,7 @@
 
         // If parent is null, the layer should be placed offscreen so reparent to null. Otherwise,
         // set to the available parent.
-        t.reparent(mSurfaceControl, mParent == null ? null : mParent.getParentingSurfaceControl());
+        t.reparent(mSurfaceControl, mParent == null ? null : mParent.mSurfaceControl);
 
         if (mLastRelativeToLayer != null) {
             t.setRelativeLayer(mSurfaceControl, mLastRelativeToLayer, mLastLayer);
@@ -2907,17 +2907,6 @@
     }
 
     /**
-     * Returns the {@link SurfaceControl} where all the children should be parented on.
-     *
-     * A {@link WindowContainer} might insert intermediate leashes in the hierarchy and hence
-     * {@link #getSurfaceControl} won't return the correct surface where the children should be
-     * re-parented on.
-     */
-    SurfaceControl getParentingSurfaceControl() {
-        return getSurfaceControl();
-    }
-
-    /**
      * Use this method instead of {@link #getPendingTransaction()} if the Transaction should be
      * synchronized with the client.
      *
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index cb87f7e..cebd6d0 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -14703,12 +14703,15 @@
     }
 
     @Override
-    public void setSystemSetting(ComponentName who, String setting, String value) {
+    public void setSystemSetting(ComponentName who, String setting, String value, boolean parent) {
         Objects.requireNonNull(who, "ComponentName is null");
         Preconditions.checkStringNotEmpty(setting, "String setting is null or empty");
         final CallerIdentity caller = getCallerIdentity(who);
         Preconditions.checkCallAuthorization(
                 isProfileOwner(caller) || isDefaultDeviceOwner(caller));
+        if (Flags.allowScreenBrightnessControlOnCope() && parent) {
+            Preconditions.checkCallAuthorization(isProfileOwnerOfOrganizationOwnedDevice(caller));
+        }
         checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_SET_SYSTEM_SETTING);
 
         synchronized (getLockObject()) {
@@ -14716,9 +14719,14 @@
                 throw new SecurityException(String.format(
                         "Permission denial: device owners cannot update %1$s", setting));
             }
-
+            int affectedUser;
+            if (Flags.allowScreenBrightnessControlOnCope() && parent) {
+                affectedUser = getProfileParentId(caller.getUserId());
+            } else {
+                affectedUser = caller.getUserId();
+            }
             mInjector.binderWithCleanCallingIdentity(() ->
-                    mInjector.settingsSystemPutStringForUser(setting, value, caller.getUserId()));
+                    mInjector.settingsSystemPutStringForUser(setting, value, affectedUser));
         }
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyTests.java
index fafc035..dd374d9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyTests.java
@@ -34,8 +34,6 @@
 
 import android.platform.test.annotations.Presubmit;
 import android.util.Pair;
-import android.view.Display;
-import android.view.DisplayInfo;
 
 import androidx.test.filters.SmallTest;
 
@@ -49,7 +47,6 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-import java.util.Optional;
 
 /**
  * Tests for the {@link DisplayAreaPolicy}.
@@ -108,16 +105,6 @@
     }
 
     @Test
-    public void testEmptyFeaturesOnUntrustedDisplay() {
-        final DisplayInfo info = new DisplayInfo(mDisplayInfo);
-        info.flags &= ~Display.FLAG_TRUSTED;
-        final DisplayContent untrustedDisplay = new TestDisplayContent.Builder(mAtm, info).build();
-
-        assertTrue(untrustedDisplay.mFeatures.isEmpty());
-        assertNotNull(untrustedDisplay.getWindowingLayer());
-    }
-
-    @Test
     public void testDisplayAreaGroup_taskPositionChanged_updatesDisplayAreaGroupPosition() {
         final WindowManagerService wms = mWm;
         final DisplayContent displayContent = mock(DisplayContent.class);
@@ -215,11 +202,15 @@
     private void assertTaskDisplayAreaPresentAndCanHaveHome(DisplayAreaPolicy policy,
                                                             int featureId,
                                                             boolean canHaveHome) {
-        Optional<DisplayArea> optionalDisplayArea = policy.mRoot.mChildren
-                .stream().filter(displayArea -> displayArea.mFeatureId == featureId)
-                .findAny();
-        assertTrue(optionalDisplayArea.isPresent());
-        assertEquals(canHaveHome, optionalDisplayArea.get().asTaskDisplayArea().canHostHomeTask());
+        final ArrayList<TaskDisplayArea> matchedAreas = new ArrayList<>();
+        policy.mRoot.forAllWindowContainers(w -> {
+            final TaskDisplayArea tda = w.asTaskDisplayArea();
+            if (tda != null && tda.mFeatureId == featureId) {
+                matchedAreas.add(tda);
+            }
+        });
+        assertTrue(matchedAreas.size() > 0);
+        assertEquals(canHaveHome, matchedAreas.get(0).canHostHomeTask());
     }
 
     private void assertTaskDisplayAreasOrder(DisplayAreaPolicy policy,
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index f63ff6e..4e360d0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -2170,9 +2170,50 @@
             assertEquals("There should be only one DisplayArea for FEATURE_WINDOWED_MAGNIFICATION",
                     1, windowedMagnificationAreas.size());
             assertEquals(windowedMagnificationAreas.get(0).mSurfaceControl, windowingLayer);
+            assertEquals(windowingLayer,
+                    mDisplayContent.mDisplayAreaPolicy.getWindowingArea().mSurfaceControl);
         } else {
             assertNotEquals(mDisplayContent.mSurfaceControl, windowingLayer);
         }
+
+        // When migrating the surface of default trusted display, the children should belong to the
+        // surface of DisplayContent directly.
+        clearInvocations(mTransaction);
+        mDisplayContent.migrateToNewSurfaceControl(mTransaction);
+        for (int i = mDisplayContent.getChildCount() - 1; i >= 0; i--) {
+            final SurfaceControl childSc = mDisplayContent.getChildAt(i).mSurfaceControl;
+            verify(mTransaction).reparent(eq(childSc), eq(mDisplayContent.mSurfaceControl));
+            verify(mTransaction, never()).reparent(eq(childSc), eq(windowingLayer));
+        }
+
+        // If a display doesn't have WINDOWED_MAGNIFICATION (e.g. untrusted), it will have an
+        // additional windowing layer to put the window content.
+        clearInvocations(mTransaction);
+        final DisplayInfo info = new DisplayInfo(mDisplayInfo);
+        info.flags &= ~Display.FLAG_TRUSTED;
+        final DisplayContent dc2 = createNewDisplay(info);
+        final SurfaceControl dc2WinLayer = dc2.getWindowingLayer();
+        final DisplayArea<?> dc2WinArea = dc2.mDisplayAreaPolicy.getWindowingArea();
+        assertEquals(dc2WinLayer, dc2WinArea.mSurfaceControl);
+
+        // When migrating the surface of a display with additional windowing layer, the children
+        // layer of display should still belong to the display.
+        clearInvocations(mTransaction);
+        dc2.migrateToNewSurfaceControl(mTransaction);
+        verify(mTransaction).reparent(eq(dc2WinLayer), eq(dc2.mSurfaceControl));
+        for (int i = dc2.getChildCount() - 1; i >= 0; i--) {
+            verify(mTransaction).reparent(eq(dc2.getChildAt(i).mSurfaceControl),
+                    eq(dc2.mSurfaceControl));
+        }
+
+        // When migrating the surface of child area under windowing area, the new child surfaces
+        // should reparent to the windowing layer.
+        clearInvocations(mTransaction);
+        for (int i = dc2WinArea.getChildCount() - 1; i >= 0; i--) {
+            final WindowContainer<?> child = dc2WinArea.getChildAt(i);
+            child.migrateToNewSurfaceControl(mTransaction);
+            verify(mTransaction).reparent(eq(child.mSurfaceControl), eq(dc2WinLayer));
+        }
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
index a8f6fe8..413d003 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -346,7 +346,7 @@
         doReturn(true).when(amInternal).hasStartedUserState(anyInt());
         doReturn(false).when(amInternal).shouldConfirmCredentials(anyInt());
         doReturn(false).when(amInternal).isActivityStartsLoggingEnabled();
-        doReturn(true).when(amInternal).isThemeOverlayReady(anyInt());
+        doReturn(false).when(amInternal).shouldDelayHomeLaunch(anyInt());
         LocalServices.addService(ActivityManagerInternal.class, amInternal);
 
         final ActivityManagerService amService =