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

Commit 6d633a06 authored by Graciela Wissen Putri's avatar Graciela Wissen Putri Committed by Massimo Carli
Browse files

[2/n] Add opaque background if task in freeform

Force set an opaque background colour for all freeform tasks to prevent
risk of other floating tasks below from being visible if the window
above is translucent.

Flag: com.android.window.flags.enable_opaque_background_for_transparent_windows
Bug: 397219542
Test: atest WindowDecorationTests
Test: atest DesktopModeStatusTest

Change-Id: Iea4c173681ac6f2a2b4105a91b839328d4a4be72
parent c2b07151
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper.enabl

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.TaskInfo;
import android.content.Context;
import android.hardware.display.DisplayManager;
import android.os.SystemProperties;
@@ -286,6 +287,16 @@ public class DesktopModeStatus {
                && deviceHasLargeScreen(context);
    }

    /**
     * @return If {@code true} we set opaque background for all freeform tasks to prevent freeform
     * tasks below from being visible if freeform task window above is translucent.
     * Otherwise if fluid resize is enabled, add a background to freeform tasks.
     */
    public static boolean shouldSetBackground(@NonNull TaskInfo taskInfo) {
        return taskInfo.isFreeform() && (!DesktopModeStatus.isVeiledResizeEnabled()
                || DesktopModeFlags.ENABLE_OPAQUE_BACKGROUND_FOR_TRANSPARENT_WINDOWS.isTrue());
    }

    /**
     * @return {@code true} if the app handle should be shown because desktop mode is enabled or
     * the device has a large screen
+5 −0
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.shared.annotations.ShellBackgroundThread;
import com.android.wm.shell.shared.annotations.ShellMainThread;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import com.android.wm.shell.windowdecor.common.viewhost.WindowDecorViewHost;
import com.android.wm.shell.windowdecor.common.viewhost.WindowDecorViewHostSupplier;
import com.android.wm.shell.windowdecor.extension.TaskInfoKt;
@@ -247,6 +248,10 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
        relayoutParams.mOccludingCaptionElements.add(controlsElement);
        relayoutParams.mCaptionTopPadding = getTopPadding(relayoutParams,
                taskInfo.getConfiguration().windowConfiguration.getBounds(), displayInsetsState);
        // Set opaque background for all freeform tasks to prevent freeform tasks below
        // from being visible if freeform task window above is translucent.
        // Otherwise if fluid resize is enabled, add a background to freeform tasks.
        relayoutParams.mShouldSetBackground = DesktopModeStatus.shouldSetBackground(taskInfo);
    }

    @SuppressLint("MissingPermission")
+4 −0
Original line number Diff line number Diff line
@@ -1064,6 +1064,10 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
            relayoutParams.mCornerRadius = shouldIgnoreCornerRadius ? INVALID_CORNER_RADIUS :
                    getCornerRadius(context, relayoutParams.mLayoutResId);
        }
        // Set opaque background for all freeform tasks to prevent freeform tasks below
        // from being visible if freeform task window above is translucent.
        // Otherwise if fluid resize is enabled, add a background to freeform tasks.
        relayoutParams.mShouldSetBackground = DesktopModeStatus.shouldSetBackground(taskInfo);
    }

    private static int getCornerRadius(@NonNull Context context, int layoutResId) {
+6 −7
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package com.android.wm.shell.windowdecor;

import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.content.res.Configuration.DENSITY_DPI_UNDEFINED;
import static android.view.WindowInsets.Type.captionBar;
import static android.view.WindowInsets.Type.mandatorySystemGestures;
@@ -57,7 +56,6 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.desktopmode.DesktopModeEventLogger;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
import com.android.wm.shell.windowdecor.WindowDecoration.RelayoutParams.OccludingCaptionElement;
import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalViewHostViewContainer;
import com.android.wm.shell.windowdecor.common.viewhost.WindowDecorViewHost;
@@ -504,15 +502,14 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
            startT.show(mTaskSurface);
        }

        if (mTaskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM
                && !DesktopModeStatus.isVeiledResizeEnabled()) {
            // When fluid resize is enabled, add a background to freeform tasks
            int backgroundColorInt = mTaskInfo.taskDescription.getBackgroundColor();
        if (params.mShouldSetBackground) {
            final int backgroundColorInt = mTaskInfo.taskDescription != null
                    ? mTaskInfo.taskDescription.getBackgroundColor() : Color.BLACK;
            mTmpColor[0] = (float) Color.red(backgroundColorInt) / 255.f;
            mTmpColor[1] = (float) Color.green(backgroundColorInt) / 255.f;
            mTmpColor[2] = (float) Color.blue(backgroundColorInt) / 255.f;
            startT.setColor(mTaskSurface, mTmpColor);
        } else if (!DesktopModeStatus.isVeiledResizeEnabled()) {
        } else {
            startT.unsetColor(mTaskSurface);
        }

@@ -833,6 +830,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer>
        boolean mSetTaskVisibilityPositionAndCrop;
        boolean mHasGlobalFocus;
        boolean mShouldSetAppBounds;
        boolean mShouldSetBackground;

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

        boolean hasInputFeatureSpy() {
+73 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.wm.shell.shared.desktopmode

import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
import android.content.Context
import android.content.res.Resources
import android.platform.test.annotations.DisableFlags
@@ -27,6 +28,7 @@ import androidx.test.filters.SmallTest
import com.android.internal.R
import com.android.window.flags.Flags
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.util.createTaskInfo
import com.google.common.truth.Truth.assertThat
import org.junit.After
import org.junit.Before
@@ -152,6 +154,70 @@ class DesktopModeStatusTest : ShellTestCase() {
        assertThat(DesktopModeStatus.canEnterDesktopMode(mockContext)).isTrue()
    }

    @EnableFlags(
        Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE,
        Flags.FLAG_ENABLE_OPAQUE_BACKGROUND_FOR_TRANSPARENT_WINDOWS,
    )
    @Test
    fun shouldSetBackground_BTWFlagEnabled_freeformTask_returnsTrue() {
        val freeFormTaskInfo = createTaskInfo(deviceWindowingMode = WINDOWING_MODE_FREEFORM)
        assertThat(DesktopModeStatus.shouldSetBackground(freeFormTaskInfo)).isTrue()
    }

    @EnableFlags(
        Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE,
        Flags.FLAG_ENABLE_OPAQUE_BACKGROUND_FOR_TRANSPARENT_WINDOWS,
    )
    @Test
    fun shouldSetBackground_BTWFlagEnabled_notFreeformTask_returnsFalse() {
        val notFreeFormTaskInfo = createTaskInfo()
        assertThat(DesktopModeStatus.shouldSetBackground(notFreeFormTaskInfo)).isFalse()
    }

    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
    @DisableFlags(Flags.FLAG_ENABLE_OPAQUE_BACKGROUND_FOR_TRANSPARENT_WINDOWS)
    @Test
    fun shouldSetBackground_BTWFlagDisabled_freeformTaskAndFluid_returnsTrue() {
        val freeFormTaskInfo = createTaskInfo(deviceWindowingMode = WINDOWING_MODE_FREEFORM)

        setIsVeiledResizeEnabled(false)
        assertThat(DesktopModeStatus.shouldSetBackground(freeFormTaskInfo)).isTrue()
    }

    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
    @DisableFlags(Flags.FLAG_ENABLE_OPAQUE_BACKGROUND_FOR_TRANSPARENT_WINDOWS)
    @Test
    fun shouldSetBackground_BTWFlagDisabled_freeformTaskAndVeiled_returnsFalse() {
        val freeFormTaskInfo = createTaskInfo(deviceWindowingMode = WINDOWING_MODE_FREEFORM)

        setIsVeiledResizeEnabled(true)
        assertThat(DesktopModeStatus.shouldSetBackground(freeFormTaskInfo)).isFalse()
    }

    @EnableFlags(
        Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE,
        Flags.FLAG_ENABLE_OPAQUE_BACKGROUND_FOR_TRANSPARENT_WINDOWS,
    )
    @Test
    fun shouldSetBackground_BTWFlagEnabled_freeformTaskAndFluid_returnsTrue() {
        val freeFormTaskInfo = createTaskInfo(deviceWindowingMode = WINDOWING_MODE_FREEFORM)

        setIsVeiledResizeEnabled(false)
        assertThat(DesktopModeStatus.shouldSetBackground(freeFormTaskInfo)).isTrue()
    }

    @EnableFlags(
        Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE,
        Flags.FLAG_ENABLE_OPAQUE_BACKGROUND_FOR_TRANSPARENT_WINDOWS,
    )
    @Test
    fun shouldSetBackground_BTWFlagEnabled_windowModesTask_freeformTaskAndVeiled_returnsTrue() {
        val freeFormTaskInfo = createTaskInfo(deviceWindowingMode = WINDOWING_MODE_FREEFORM)

        setIsVeiledResizeEnabled(true)
        assertThat(DesktopModeStatus.shouldSetBackground(freeFormTaskInfo)).isTrue()
    }

    @Test
    fun isDeviceEligibleForDesktopMode_configDEModeOnAndIntDispHostsDesktop_returnsTrue() {
        doReturn(true).whenever(mockResources).getBoolean(eq(R.bool.config_isDesktopModeSupported))
@@ -254,4 +320,11 @@ class DesktopModeStatusTest : ShellTestCase() {
        deviceRestrictions.isAccessible = true
        deviceRestrictions.setBoolean(/* obj= */ null, /* z= */ !eligible)
    }

    private fun setIsVeiledResizeEnabled(enabled: Boolean) {
        val deviceRestrictions =
            DesktopModeStatus::class.java.getDeclaredField("IS_VEILED_RESIZE_ENABLED")
        deviceRestrictions.isAccessible = true
        deviceRestrictions.setBoolean(/* obj= */ null, /* z= */ enabled)
    }
}
Loading