diff options
6 files changed, 103 insertions, 26 deletions
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java index 00c446c3da60..3992183200c8 100644 --- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java +++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java @@ -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; @@ -287,6 +288,16 @@ public class DesktopModeStatus { } /** + * @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 */ diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java index 49510c8060fc..5e8c1fe2aa8d 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java @@ -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") diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java index 6165dbf686fd..30e5c2ae0914 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java @@ -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) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java index 4002dc572897..7baef2b2dc97 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java @@ -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() { diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatusTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatusTest.kt index 4082ffd4ac0a..fb62ba75e056 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatusTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatusTest.kt @@ -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) + } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java index af0162334440..a2927fa3527b 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java @@ -24,7 +24,6 @@ import static android.view.WindowInsets.Type.captionBar; import static android.view.WindowInsets.Type.mandatorySystemGestures; import static android.view.WindowInsets.Type.statusBars; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; import static com.android.wm.shell.MockSurfaceControlHelper.createMockSurfaceControlBuilder; import static com.android.wm.shell.MockSurfaceControlHelper.createMockSurfaceControlTransaction; @@ -51,7 +50,6 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import static org.mockito.quality.Strictness.LENIENT; import android.annotation.NonNull; import android.app.ActivityManager; @@ -79,13 +77,11 @@ import android.window.WindowContainerTransaction; import androidx.test.filters.SmallTest; -import com.android.dx.mockito.inline.extended.StaticMockitoSession; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.ShellTestCase; import com.android.wm.shell.TestRunningTaskInfoBuilder; 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.tests.R; import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalViewContainer; import com.android.wm.shell.windowdecor.common.viewhost.WindowDecorViewHost; @@ -564,12 +560,7 @@ public class WindowDecorationTests extends ShellTestCase { } @Test - public void testRelayout_fluidResizeEnabled_freeformTask_setTaskSurfaceColor() { - StaticMockitoSession mockitoSession = mockitoSession().mockStatic( - DesktopModeStatus.class).strictness( - LENIENT).startMocking(); - when(DesktopModeStatus.isVeiledResizeEnabled()).thenReturn(false); - + public void testRelayout_shouldSetBackground_freeformTask_setTaskSurfaceColor() { final Display defaultDisplay = mock(Display.class); doReturn(defaultDisplay).when(mMockDisplayController) .getDisplay(Display.DEFAULT_DISPLAY); @@ -595,11 +586,10 @@ public class WindowDecorationTests extends ShellTestCase { .build(); final TestWindowDecoration windowDecor = createWindowDecoration(taskInfo); + mRelayoutParams.mShouldSetBackground = true; windowDecor.relayout(taskInfo, true /* hasGlobalFocus */); verify(mMockSurfaceControlStartT).setColor(mMockTaskSurface, new float[]{1.f, 1.f, 0.f}); - - mockitoSession.finishMocking(); } @Test @@ -627,11 +617,7 @@ public class WindowDecorationTests extends ShellTestCase { } @Test - public void testRelayout_fluidResizeEnabled_fullscreenTask_clearTaskSurfaceColor() { - StaticMockitoSession mockitoSession = mockitoSession().mockStatic( - DesktopModeStatus.class).strictness(LENIENT).startMocking(); - when(DesktopModeStatus.isVeiledResizeEnabled()).thenReturn(false); - + public void testRelayout_shouldNotSetBackground_fullscreenTask_clearTaskSurfaceColor() { final Display defaultDisplay = mock(Display.class); doReturn(defaultDisplay).when(mMockDisplayController) .getDisplay(Display.DEFAULT_DISPLAY); @@ -655,12 +641,11 @@ public class WindowDecorationTests extends ShellTestCase { .setWindowingMode(WINDOWING_MODE_FULLSCREEN) .build(); final TestWindowDecoration windowDecor = createWindowDecoration(taskInfo); + mRelayoutParams.mIsCaptionVisible = false; windowDecor.relayout(taskInfo, true /* hasGlobalFocus */); verify(mMockSurfaceControlStartT).unsetColor(mMockTaskSurface); - - mockitoSession.finishMocking(); } @Test |