Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 05eec2f9 authored by Merissa Mitchell's avatar Merissa Mitchell
Browse files

[WindowDecor] Trigger relayout when system theme changes.

This CL implements onThemeChanged for DesktopModeWindowDecorViewModel so
that we can trigger a relayout when the system color changes to update
the header color for tasks that are already open. A boolean is also
added to WindowDecoration so that the AppHeaderViewHolder will be
recreated with the new context -- this will update the cached color
scheme accordingly.

Recall: http://recall/clips/4d457d63-3c90-41d9-9118-55faf0eac95c

Bug: 412489198
Flag: EXEMPT bugfix
Test: atest WMShellUnitTests:com.android.wm.shell.windowdecor
Test: Manual - navigate to Wallpaper & Style in Settings > change the
Home screen color > observe that the header changes color along with the
app content

Change-Id: I1ebabd7e16d0fa4a71f889564781d28b1b303596
parent 15a444a9
Loading
Loading
Loading
Loading
+24 −4
Original line number Diff line number Diff line
@@ -211,10 +211,26 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
        // at the same, whereas applying them independently causes flickering. See b/270202228.
        relayout(taskInfo, t, t, true /* applyStartTransactionOnDraw */,
                shouldSetTaskVisibilityPositionAndCrop, hasGlobalFocus, displayExclusionRegion,
                /* inSyncWithTransition= */ false);
                /* inSyncWithTransition= */ false, /* forceReinflation= */ false);
    }

    /** TODO(b/437224867): Remove this workaround for "Wallpaper & Style" bug in Settings */
    void onThemeChanged() {
        final SurfaceControl.Transaction t = mSurfaceControlTransactionSupplier.get();
        final boolean shouldSetTaskVisibilityPositionAndCrop =
                !mDesktopConfig.isVeiledResizeEnabled()
                        && mTaskDragResizer.isResizingOrAnimating();
        final boolean applyTransactionOnDraw = mTaskInfo.isFreeform();
        relayout(mTaskInfo, t, t, applyTransactionOnDraw, shouldSetTaskVisibilityPositionAndCrop,
                mHasGlobalFocus, mExclusionRegion, /* inSyncWithTransition= */ false,
                /* forceReinflation= */ true);
        if (!applyTransactionOnDraw) {
            t.apply();
        }
    }

    @VisibleForTesting
    /** TODO(b/437224867): Remove forceReinflation param */
    static void updateRelayoutParams(
            RelayoutParams relayoutParams,
            @NonNull Context context,
@@ -227,7 +243,8 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
            boolean hasGlobalFocus,
            @NonNull Region globalExclusionRegion,
            boolean shouldSetBackground,
            boolean inSyncWithTransition) {
            boolean inSyncWithTransition,
            boolean forceReinflation) {
        relayoutParams.reset();
        relayoutParams.mRunningTaskInfo = taskInfo;
        relayoutParams.mLayoutResId = R.layout.caption_window_decor;
@@ -249,6 +266,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
                || (isStatusBarVisible && !isKeyguardVisibleAndOccluded);
        relayoutParams.mDisplayExclusionRegion.set(globalExclusionRegion);
        relayoutParams.mInSyncWithTransition = inSyncWithTransition;
        relayoutParams.mForceReinflation = forceReinflation;

        if (TaskInfoKt.isTransparentCaptionBarAppearance(taskInfo)) {
            // If the app is requesting to customize the caption bar, allow input to fall
@@ -276,11 +294,13 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
    }

    @SuppressLint("MissingPermission")
    /** TODO(b/437224867): Remove forceReinflation param */
    void relayout(RunningTaskInfo taskInfo,
            SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT,
            boolean applyStartTransactionOnDraw, boolean shouldSetTaskVisibilityPositionAndCrop,
            boolean hasGlobalFocus,
            @NonNull Region globalExclusionRegion, boolean inSyncWithTransition) {
            @NonNull Region globalExclusionRegion, boolean inSyncWithTransition,
            boolean forceReinflation) {
        final boolean isFreeform =
                taskInfo.getWindowingMode() == WindowConfiguration.WINDOWING_MODE_FREEFORM;
        final boolean isDragResizeable = ENABLE_WINDOWING_SCALED_RESIZING.isTrue()
@@ -295,7 +315,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
                mIsKeyguardVisibleAndOccluded,
                mDisplayController.getInsetsState(taskInfo.displayId), hasGlobalFocus,
                globalExclusionRegion, mDesktopConfig.shouldSetBackground(taskInfo),
                inSyncWithTransition);
                inSyncWithTransition, forceReinflation);

        relayout(mRelayoutParams, startT, finishT, wct, oldRootView, mResult);
        // After this line, mTaskInfo is up-to-date and should be used instead of taskInfo
+17 −2
Original line number Diff line number Diff line
@@ -273,11 +273,16 @@ constructor(
        decorationContainerSurface?.let { updateDragResizeListenerIfNeeded(it) }
    }

    /** Updates all window decorations, including any existing caption. */
    /**
     * Updates all window decorations, including any existing caption.
     *
     * TODO(b/437224867): Remove forceReinflation param
     */
    override fun relayout(
        taskInfo: RunningTaskInfo,
        hasGlobalFocus: Boolean,
        displayExclusionRegion: Region,
        forceReinflation: Boolean,
    ) {
        val t = surfaceControlTransactionSupplier.invoke()
        // The visibility, crop and position of the task should only be set when a task is
@@ -308,13 +313,18 @@ constructor(
            displayExclusionRegion,
            inSyncWithTransition = false,
            taskSurface,
            forceReinflation = forceReinflation,
        )
        if (!applyTransactionOnDraw) {
            t.apply()
        }
    }

    /** Updates all window decorations, including any existing caption. */
    /**
     * Updates all window decorations, including any existing caption.
     *
     * TODO(b/437224867): Remove forceReinflation param
     */
    fun relayout(
        taskInfo: RunningTaskInfo,
        startT: SurfaceControl.Transaction,
@@ -325,6 +335,7 @@ constructor(
        displayExclusionRegion: Region,
        inSyncWithTransition: Boolean,
        taskSurface: SurfaceControl?,
        forceReinflation: Boolean = false,
    ) =
        traceSection("DefaultWindowDecoration#relayout") {
            if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_APP_TO_WEB.isTrue) {
@@ -355,6 +366,7 @@ constructor(
                    desktopModeCompatPolicy.shouldExcludeCaptionFromAppBounds(taskInfo),
                    desktopConfig,
                    inSyncWithTransition,
                    forceReinflation,
                )

            val wct = windowContainerTransactionSupplier.invoke()
@@ -390,6 +402,7 @@ constructor(
            decorationContainerSurface?.let { updateDragResizeListenerIfNeeded(it) }
        }

    /** TODO(b/437224867): Remove forceReinflation param */
    private fun getRelayoutParams(
        context: Context,
        taskInfo: RunningTaskInfo,
@@ -402,6 +415,7 @@ constructor(
        shouldExcludeCaptionFromAppBounds: Boolean,
        desktopConfig: DesktopConfig,
        inSyncWithTransition: Boolean,
        forceReinflation: Boolean,
    ): RelayoutParams {
        val captionType =
            if (taskInfo.isFreeform) {
@@ -500,6 +514,7 @@ constructor(
            shouldSetAppBounds = shouldSetAppBounds,
            shouldSetBackground = shouldSetBackground,
            inSyncWithTransition = inSyncWithTransition,
            forceReinflation = forceReinflation,
        )
    }

+9 −1
Original line number Diff line number Diff line
@@ -148,6 +148,7 @@ import com.android.wm.shell.shared.desktopmode.DesktopModeTransitionSource;
import com.android.wm.shell.shared.desktopmode.DesktopState;
import com.android.wm.shell.shared.split.SplitScreenConstants.SplitPosition;
import com.android.wm.shell.splitscreen.SplitScreenController;
import com.android.wm.shell.sysui.ConfigurationChangeListener;
import com.android.wm.shell.sysui.KeyguardChangeListener;
import com.android.wm.shell.sysui.ShellCommandHandler;
import com.android.wm.shell.sysui.ShellController;
@@ -193,7 +194,7 @@ import java.util.function.Supplier;

public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
        FocusTransitionListener, SnapEventHandler,
        LockTaskChangeListener.LockTaskModeChangedListener {
        LockTaskChangeListener.LockTaskModeChangedListener, ConfigurationChangeListener {
    private static final String TAG = "DesktopModeWindowDecorViewModel";

    private final WindowDecorationWrapper.Factory mWindowDecoratioWrapperFactory;
@@ -533,6 +534,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
    @OptIn(markerClass = ExperimentalCoroutinesApi.class)
    private void onInit() {
        mShellController.addKeyguardChangeListener(mDesktopModeKeyguardChangeListener);
        mShellController.addConfigurationChangeListener(this);
        mShellCommandHandler.addDumpCallback(this::dump, this);
        mDisplayInsetsController.addGlobalInsetsChangedListener(
                new DesktopModeOnInsetsChangedListener());
@@ -671,6 +673,12 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel,
        });
    }

    @Override
    /** TODO(b/437224867): Remove this workaround for "Wallpaper & Style" bug in Settings */
    public void onThemeChanged() {
        forAllWindowDecorations(WindowDecorationWrapper::onThemeChanged);
    }

    private void forAllWindowDecorations(Consumer<WindowDecorationWrapper> callback) {
        forAllWindowDecorations(callback, /* reverseOrder= */ false);
    }
+24 −3
Original line number Diff line number Diff line
@@ -428,7 +428,23 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
        // causes flickering. See b/270202228.
        final boolean applyTransactionOnDraw = taskInfo.isFreeform();
        relayout(taskInfo, t, t, applyTransactionOnDraw, shouldSetTaskVisibilityPositionAndCrop,
                hasGlobalFocus, displayExclusionRegion, /* inSyncWithTransition= */ false);
                hasGlobalFocus, displayExclusionRegion, /* inSyncWithTransition= */ false,
                /* forceReinflation= */ false);
        if (!applyTransactionOnDraw) {
            t.apply();
        }
    }

    /** TODO(b/437224867): Remove this workaround for "Wallpaper & Style" bug in Settings */
    void onThemeChanged() {
        final SurfaceControl.Transaction t = mSurfaceControlTransactionSupplier.get();
        final boolean shouldSetTaskVisibilityPositionAndCrop =
                !mDesktopConfig.isVeiledResizeEnabled()
                        && mTaskDragResizer.isResizingOrAnimating();
        final boolean applyTransactionOnDraw = mTaskInfo.isFreeform();
        relayout(mTaskInfo, t, t, applyTransactionOnDraw, shouldSetTaskVisibilityPositionAndCrop,
                mHasGlobalFocus, mExclusionRegion, /* inSyncWithTransition= */ false,
                /* forceReinflation= */ true);
        if (!applyTransactionOnDraw) {
            t.apply();
        }
@@ -451,11 +467,12 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
        updateDragResizeListenerIfNeeded(mDecorationContainerSurface, inFullImmersive);
    }

    /** TODO(b/437224867): Remove forceReinflation param */
    void relayout(ActivityManager.RunningTaskInfo taskInfo,
            SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT,
            boolean applyStartTransactionOnDraw, boolean shouldSetTaskVisibilityPositionAndCrop,
            boolean hasGlobalFocus, @NonNull Region displayExclusionRegion,
            boolean inSyncWithTransition) {
            boolean inSyncWithTransition, boolean forceReinflation) {
        Trace.beginSection("DesktopModeWindowDecoration#relayout");

        if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_APP_TO_WEB.isTrue()) {
@@ -502,7 +519,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
                        && DesktopModeFlags
                        .ENABLE_DESKTOP_RECENTS_TRANSITIONS_CORNERS_BUGFIX.isTrue(),
                mDesktopModeCompatPolicy.shouldExcludeCaptionFromAppBounds(taskInfo),
                mDesktopConfig, inSyncWithTransition, mLockTaskChangeListener.isTaskLocked(),
                mDesktopConfig, inSyncWithTransition,
                mLockTaskChangeListener.isTaskLocked(), forceReinflation,
                /* occludingElementsCalculator = */ () -> getOccludingElements());

        final WindowDecorLinearLayout oldRootView = mResult.mRootView;
@@ -995,6 +1013,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
    }

    @VisibleForTesting
    /** TODO(b/437224867): Remove forceReinflation param */
    static void updateRelayoutParams(
            RelayoutParams relayoutParams,
            Context context,
@@ -1014,6 +1033,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
            DesktopConfig desktopConfig,
            boolean inSyncWithTransition,
            boolean isTaskLocked,
            boolean forceReinflation,
            Supplier<List<OccludingElement>> occludingElementsCalculator) {
        final int captionLayoutId = getDesktopModeWindowDecorLayoutId(taskInfo.getWindowingMode());
        final boolean isAppHeader =
@@ -1026,6 +1046,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
                taskInfo.getWindowingMode());
        relayoutParams.mCaptionWidthId = getCaptionWidthId(relayoutParams.mLayoutResId);
        relayoutParams.mHasGlobalFocus = hasGlobalFocus;
        relayoutParams.mForceReinflation = forceReinflation;
        relayoutParams.mDisplayExclusionRegion.set(displayExclusionRegion);
        // Allow the handle view to be delayed since the handle is just a small addition to the
        // window, whereas the header cannot be delayed because it is expected to be visible from
+16 −1
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.wm.shell.windowdecor;

import static android.content.pm.ActivityInfo.CONFIG_ASSETS_PATHS;
import static android.content.pm.ActivityInfo.CONFIG_UI_MODE;
import static android.content.res.Configuration.DENSITY_DPI_UNDEFINED;
import static android.view.WindowInsets.Type.statusBars;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
@@ -402,6 +404,14 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
        final int oldNightMode =  mWindowDecorConfig != null
                ? (mWindowDecorConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK)
                : Configuration.UI_MODE_NIGHT_UNDEFINED;
        // TODO(b/437224867): Remove themeChanged workaround for "Wallpaper & Style" bug in Settings
        final Configuration oldConfig = mWindowDecorConfig != null
                ? mWindowDecorConfig : mTaskInfo.configuration;
        final Configuration newConfig = params.mWindowDecorConfig != null
                ? params.mWindowDecorConfig : mTaskInfo.configuration;
        final int diff = newConfig.diff(oldConfig);
        final boolean themeChanged = (diff & CONFIG_ASSETS_PATHS) != 0
                || (diff & CONFIG_UI_MODE) != 0;
        mWindowDecorConfig = params.mWindowDecorConfig != null ? params.mWindowDecorConfig
                : mTaskInfo.getConfiguration();
        final int newDensityDpi = mWindowDecorConfig.densityDpi;
@@ -413,7 +423,9 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
                || oldNightMode != newNightMode
                || mDecorWindowContext == null
                || fontScaleChanged
                || localeListChanged) {
                || localeListChanged
                || themeChanged
                || params.mForceReinflation) {
            releaseViews(wct);

            if (!obtainDisplayOrRegisterListener()) {
@@ -916,6 +928,8 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
        boolean mShouldSetBackground;

        boolean mInSyncWithTransition;
        /** TODO(b/437224867): Remove mForceReinflation */
        boolean mForceReinflation;

        void reset() {
            mLayoutResId = Resources.ID_NULL;
@@ -949,6 +963,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
            mShouldSetAppBounds = false;
            mShouldSetBackground = false;
            mInSyncWithTransition = false;
            mForceReinflation = false;
        }

        boolean hasInputFeatureSpy() {
Loading