Loading libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java +11 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java +5 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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") Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java +4 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java +6 −7 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); } Loading Loading @@ -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; Loading @@ -857,6 +855,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> mAsyncViewHost = false; mHasGlobalFocus = false; mShouldSetAppBounds = false; mShouldSetBackground = false; } boolean hasInputFeatureSpy() { Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatusTest.kt +73 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading Loading @@ -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)) Loading Loading @@ -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
libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java +11 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java +5 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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") Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java +4 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java +6 −7 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); } Loading Loading @@ -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; Loading @@ -857,6 +855,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> mAsyncViewHost = false; mHasGlobalFocus = false; mShouldSetAppBounds = false; mShouldSetBackground = false; } boolean hasInputFeatureSpy() { Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatusTest.kt +73 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading Loading @@ -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)) Loading Loading @@ -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) } }