Loading libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/DesktopModeStatus.java +18 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,16 @@ public class DesktopModeStatus { private static final boolean ENFORCE_DEVICE_RESTRICTIONS = SystemProperties.getBoolean( "persist.wm.debug.desktop_mode_enforce_device_restrictions", true); /** Override density for tasks when they're inside the desktop. */ public static final int DESKTOP_DENSITY_OVERRIDE = SystemProperties.getInt("persist.wm.debug.desktop_mode_density", 284); /** The minimum override density allowed for tasks inside the desktop. */ private static final int DESKTOP_DENSITY_MIN = 100; /** The maximum override density allowed for tasks inside the desktop. */ private static final int DESKTOP_DENSITY_MAX = 1000; /** * Default value for {@code MAX_TASK_LIMIT}. */ Loading Loading @@ -145,4 +155,12 @@ public class DesktopModeStatus { public static boolean canEnterDesktopMode(@NonNull Context context) { return (!enforceDeviceRestrictions() || isDesktopModeSupported(context)) && isEnabled(); } /** * Return {@code true} if the override desktop density is set. */ public static boolean isDesktopDensityOverrideSet() { return DESKTOP_DENSITY_OVERRIDE >= DESKTOP_DENSITY_MIN && DESKTOP_DENSITY_OVERRIDE <= DESKTOP_DENSITY_MAX; } } libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +8 −19 Original line number Diff line number Diff line Loading @@ -73,6 +73,8 @@ import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE import com.android.wm.shell.recents.RecentsTransitionHandler import com.android.wm.shell.recents.RecentsTransitionStateListener import com.android.wm.shell.shared.DesktopModeStatus import com.android.wm.shell.shared.DesktopModeStatus.DESKTOP_DENSITY_OVERRIDE import com.android.wm.shell.shared.DesktopModeStatus.isDesktopDensityOverrideSet import com.android.wm.shell.shared.annotations.ExternalThread import com.android.wm.shell.shared.annotations.ShellMainThread import com.android.wm.shell.splitscreen.SplitScreenController Loading Loading @@ -910,15 +912,18 @@ class DesktopTasksController( wct.reorder(task.token, true) } } val wct = WindowContainerTransaction() if (isDesktopDensityOverrideSet()) { wct.setDensityDpi(task.token, DESKTOP_DENSITY_OVERRIDE) } // Desktop Mode is showing and we're launching a new Task - we might need to minimize // a Task. val wct = WindowContainerTransaction() val taskToMinimize = addAndGetMinimizeChangesIfNeeded(task.displayId, wct, task) if (taskToMinimize != null) { addPendingMinimizeTransition(transition, taskToMinimize) return wct } return null return if (wct.isEmpty) null else wct } private fun handleFullscreenTaskLaunch( Loading Loading @@ -986,7 +991,7 @@ class DesktopTasksController( wct.setWindowingMode(taskInfo.token, targetWindowingMode) wct.reorder(taskInfo.token, true /* onTop */) if (isDesktopDensityOverrideSet()) { wct.setDensityDpi(taskInfo.token, getDesktopDensityDpi()) wct.setDensityDpi(taskInfo.token, DESKTOP_DENSITY_OVERRIDE) } } Loading Loading @@ -1090,10 +1095,6 @@ class DesktopTasksController( return context.resources.displayMetrics.densityDpi } private fun getDesktopDensityDpi(): Int { return DESKTOP_DENSITY_OVERRIDE } /** Creates a new instance of the external interface to pass to another process. */ private fun createExternalInterface(): ExternalInterfaceBinder { return IDesktopModeImpl(this) Loading Loading @@ -1467,21 +1468,9 @@ class DesktopTasksController( } companion object { private val DESKTOP_DENSITY_OVERRIDE = SystemProperties.getInt("persist.wm.debug.desktop_mode_density", 284) private val DESKTOP_DENSITY_ALLOWED_RANGE = (100..1000) @JvmField val DESKTOP_MODE_INITIAL_BOUNDS_SCALE = SystemProperties .getInt("persist.wm.debug.desktop_mode_initial_bounds_scale", 75) / 100f /** * Check if desktop density override is enabled */ @JvmStatic fun isDesktopDensityOverrideSet(): Boolean { return DESKTOP_DENSITY_OVERRIDE in DESKTOP_DENSITY_ALLOWED_RANGE } } /** The positions on a screen that a task can snap to. */ Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java +2 −3 Original line number Diff line number Diff line Loading @@ -67,7 +67,6 @@ import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.desktopmode.DesktopTasksController; import com.android.wm.shell.shared.DesktopModeStatus; import com.android.wm.shell.windowdecor.extension.TaskInfoKt; import com.android.wm.shell.windowdecor.viewholder.DesktopModeAppControlsWindowDecorationViewHolder; Loading Loading @@ -405,7 +404,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin // Should match the density of the task. The task may have had its density overridden // to be different that SysUI's. windowDecorConfig.setTo(taskInfo.configuration); } else if (DesktopTasksController.isDesktopDensityOverrideSet()) { } else if (DesktopModeStatus.isDesktopDensityOverrideSet()) { // The task has had its density overridden, but keep using the system's density to // layout the header. windowDecorConfig.setTo(context.getResources().getConfiguration()); Loading Loading @@ -966,7 +965,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer, ResizeHandleSizeRepository resizeHandleSizeRepository) { final Configuration windowDecorConfig = DesktopTasksController.isDesktopDensityOverrideSet() DesktopModeStatus.isDesktopDensityOverrideSet() ? context.getResources().getConfiguration() // Use system context : taskInfo.configuration; // Use task configuration return new DesktopModeWindowDecoration( Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +39 −11 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW import android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED import android.content.Intent import android.content.pm.ActivityInfo import android.content.pm.ActivityInfo.CONFIG_DENSITY import android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE import android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT import android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED Loading Loading @@ -115,6 +116,8 @@ import org.mockito.kotlin.atLeastOnce import org.mockito.kotlin.capture import org.mockito.quality.Strictness import java.util.Optional import junit.framework.Assert.assertFalse import junit.framework.Assert.assertTrue import org.mockito.Mockito.`when` as whenever /** Loading Loading @@ -1044,17 +1047,6 @@ class DesktopTasksControllerTest : ShellTestCase() { assertThat(result).isNull() } @Test fun handleRequest_freeformTask_freeformVisible_returnNull() { assumeTrue(ENABLE_SHELL_TRANSITIONS) val freeformTask1 = setUpFreeformTask() markTaskVisible(freeformTask1) val freeformTask2 = createFreeformTask() assertThat(controller.handleRequest(Binder(), createTransition(freeformTask2))).isNull() } @Test fun handleRequest_freeformTask_freeformVisible_aboveTaskLimit_minimize() { assumeTrue(ENABLE_SHELL_TRANSITIONS) Loading Loading @@ -1112,6 +1104,34 @@ class DesktopTasksControllerTest : ShellTestCase() { result!!.assertReorderAt(0, taskDefaultDisplay, toTop = true) } @Test fun handleRequest_freeformTask_alreadyInDesktop_noOverrideDensity_noConfigDensityChange() { assumeTrue(ENABLE_SHELL_TRANSITIONS) whenever(DesktopModeStatus.isDesktopDensityOverrideSet()).thenReturn(false) val freeformTask1 = setUpFreeformTask() markTaskVisible(freeformTask1) val freeformTask2 = createFreeformTask() val result = controller.handleRequest(freeformTask2.token.asBinder(), createTransition(freeformTask2)) assertFalse(result.anyDensityConfigChange(freeformTask2.token)) } @Test fun handleRequest_freeformTask_alreadyInDesktop_overrideDensity_hasConfigDensityChange() { assumeTrue(ENABLE_SHELL_TRANSITIONS) whenever(DesktopModeStatus.isDesktopDensityOverrideSet()).thenReturn(true) val freeformTask1 = setUpFreeformTask() markTaskVisible(freeformTask1) val freeformTask2 = createFreeformTask() val result = controller.handleRequest(freeformTask2.token.asBinder(), createTransition(freeformTask2)) assertTrue(result.anyDensityConfigChange(freeformTask2.token)) } @Test fun handleRequest_notOpenOrToFrontTransition_returnNull() { assumeTrue(ENABLE_SHELL_TRANSITIONS) Loading Loading @@ -1813,3 +1833,11 @@ private fun WindowContainerTransaction.assertPendingIntentAt(index: Int, intent: assertThat(op.type).isEqualTo(HIERARCHY_OP_TYPE_PENDING_INTENT) assertThat(op.pendingIntent?.intent?.component).isEqualTo(intent.component) } private fun WindowContainerTransaction?.anyDensityConfigChange( token: WindowContainerToken ): Boolean { return this?.changes?.any { change -> change.key == token.asBinder() && ((change.value.configSetMask and CONFIG_DENSITY) != 0) } ?: false } Loading
libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/DesktopModeStatus.java +18 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,16 @@ public class DesktopModeStatus { private static final boolean ENFORCE_DEVICE_RESTRICTIONS = SystemProperties.getBoolean( "persist.wm.debug.desktop_mode_enforce_device_restrictions", true); /** Override density for tasks when they're inside the desktop. */ public static final int DESKTOP_DENSITY_OVERRIDE = SystemProperties.getInt("persist.wm.debug.desktop_mode_density", 284); /** The minimum override density allowed for tasks inside the desktop. */ private static final int DESKTOP_DENSITY_MIN = 100; /** The maximum override density allowed for tasks inside the desktop. */ private static final int DESKTOP_DENSITY_MAX = 1000; /** * Default value for {@code MAX_TASK_LIMIT}. */ Loading Loading @@ -145,4 +155,12 @@ public class DesktopModeStatus { public static boolean canEnterDesktopMode(@NonNull Context context) { return (!enforceDeviceRestrictions() || isDesktopModeSupported(context)) && isEnabled(); } /** * Return {@code true} if the override desktop density is set. */ public static boolean isDesktopDensityOverrideSet() { return DESKTOP_DENSITY_OVERRIDE >= DESKTOP_DENSITY_MIN && DESKTOP_DENSITY_OVERRIDE <= DESKTOP_DENSITY_MAX; } }
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt +8 −19 Original line number Diff line number Diff line Loading @@ -73,6 +73,8 @@ import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE import com.android.wm.shell.recents.RecentsTransitionHandler import com.android.wm.shell.recents.RecentsTransitionStateListener import com.android.wm.shell.shared.DesktopModeStatus import com.android.wm.shell.shared.DesktopModeStatus.DESKTOP_DENSITY_OVERRIDE import com.android.wm.shell.shared.DesktopModeStatus.isDesktopDensityOverrideSet import com.android.wm.shell.shared.annotations.ExternalThread import com.android.wm.shell.shared.annotations.ShellMainThread import com.android.wm.shell.splitscreen.SplitScreenController Loading Loading @@ -910,15 +912,18 @@ class DesktopTasksController( wct.reorder(task.token, true) } } val wct = WindowContainerTransaction() if (isDesktopDensityOverrideSet()) { wct.setDensityDpi(task.token, DESKTOP_DENSITY_OVERRIDE) } // Desktop Mode is showing and we're launching a new Task - we might need to minimize // a Task. val wct = WindowContainerTransaction() val taskToMinimize = addAndGetMinimizeChangesIfNeeded(task.displayId, wct, task) if (taskToMinimize != null) { addPendingMinimizeTransition(transition, taskToMinimize) return wct } return null return if (wct.isEmpty) null else wct } private fun handleFullscreenTaskLaunch( Loading Loading @@ -986,7 +991,7 @@ class DesktopTasksController( wct.setWindowingMode(taskInfo.token, targetWindowingMode) wct.reorder(taskInfo.token, true /* onTop */) if (isDesktopDensityOverrideSet()) { wct.setDensityDpi(taskInfo.token, getDesktopDensityDpi()) wct.setDensityDpi(taskInfo.token, DESKTOP_DENSITY_OVERRIDE) } } Loading Loading @@ -1090,10 +1095,6 @@ class DesktopTasksController( return context.resources.displayMetrics.densityDpi } private fun getDesktopDensityDpi(): Int { return DESKTOP_DENSITY_OVERRIDE } /** Creates a new instance of the external interface to pass to another process. */ private fun createExternalInterface(): ExternalInterfaceBinder { return IDesktopModeImpl(this) Loading Loading @@ -1467,21 +1468,9 @@ class DesktopTasksController( } companion object { private val DESKTOP_DENSITY_OVERRIDE = SystemProperties.getInt("persist.wm.debug.desktop_mode_density", 284) private val DESKTOP_DENSITY_ALLOWED_RANGE = (100..1000) @JvmField val DESKTOP_MODE_INITIAL_BOUNDS_SCALE = SystemProperties .getInt("persist.wm.debug.desktop_mode_initial_bounds_scale", 75) / 100f /** * Check if desktop density override is enabled */ @JvmStatic fun isDesktopDensityOverrideSet(): Boolean { return DESKTOP_DENSITY_OVERRIDE in DESKTOP_DENSITY_ALLOWED_RANGE } } /** The positions on a screen that a task can snap to. */ Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java +2 −3 Original line number Diff line number Diff line Loading @@ -67,7 +67,6 @@ import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.desktopmode.DesktopTasksController; import com.android.wm.shell.shared.DesktopModeStatus; import com.android.wm.shell.windowdecor.extension.TaskInfoKt; import com.android.wm.shell.windowdecor.viewholder.DesktopModeAppControlsWindowDecorationViewHolder; Loading Loading @@ -405,7 +404,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin // Should match the density of the task. The task may have had its density overridden // to be different that SysUI's. windowDecorConfig.setTo(taskInfo.configuration); } else if (DesktopTasksController.isDesktopDensityOverrideSet()) { } else if (DesktopModeStatus.isDesktopDensityOverrideSet()) { // The task has had its density overridden, but keep using the system's density to // layout the header. windowDecorConfig.setTo(context.getResources().getConfiguration()); Loading Loading @@ -966,7 +965,7 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer, ResizeHandleSizeRepository resizeHandleSizeRepository) { final Configuration windowDecorConfig = DesktopTasksController.isDesktopDensityOverrideSet() DesktopModeStatus.isDesktopDensityOverrideSet() ? context.getResources().getConfiguration() // Use system context : taskInfo.configuration; // Use task configuration return new DesktopModeWindowDecoration( Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +39 −11 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW import android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED import android.content.Intent import android.content.pm.ActivityInfo import android.content.pm.ActivityInfo.CONFIG_DENSITY import android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE import android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT import android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED Loading Loading @@ -115,6 +116,8 @@ import org.mockito.kotlin.atLeastOnce import org.mockito.kotlin.capture import org.mockito.quality.Strictness import java.util.Optional import junit.framework.Assert.assertFalse import junit.framework.Assert.assertTrue import org.mockito.Mockito.`when` as whenever /** Loading Loading @@ -1044,17 +1047,6 @@ class DesktopTasksControllerTest : ShellTestCase() { assertThat(result).isNull() } @Test fun handleRequest_freeformTask_freeformVisible_returnNull() { assumeTrue(ENABLE_SHELL_TRANSITIONS) val freeformTask1 = setUpFreeformTask() markTaskVisible(freeformTask1) val freeformTask2 = createFreeformTask() assertThat(controller.handleRequest(Binder(), createTransition(freeformTask2))).isNull() } @Test fun handleRequest_freeformTask_freeformVisible_aboveTaskLimit_minimize() { assumeTrue(ENABLE_SHELL_TRANSITIONS) Loading Loading @@ -1112,6 +1104,34 @@ class DesktopTasksControllerTest : ShellTestCase() { result!!.assertReorderAt(0, taskDefaultDisplay, toTop = true) } @Test fun handleRequest_freeformTask_alreadyInDesktop_noOverrideDensity_noConfigDensityChange() { assumeTrue(ENABLE_SHELL_TRANSITIONS) whenever(DesktopModeStatus.isDesktopDensityOverrideSet()).thenReturn(false) val freeformTask1 = setUpFreeformTask() markTaskVisible(freeformTask1) val freeformTask2 = createFreeformTask() val result = controller.handleRequest(freeformTask2.token.asBinder(), createTransition(freeformTask2)) assertFalse(result.anyDensityConfigChange(freeformTask2.token)) } @Test fun handleRequest_freeformTask_alreadyInDesktop_overrideDensity_hasConfigDensityChange() { assumeTrue(ENABLE_SHELL_TRANSITIONS) whenever(DesktopModeStatus.isDesktopDensityOverrideSet()).thenReturn(true) val freeformTask1 = setUpFreeformTask() markTaskVisible(freeformTask1) val freeformTask2 = createFreeformTask() val result = controller.handleRequest(freeformTask2.token.asBinder(), createTransition(freeformTask2)) assertTrue(result.anyDensityConfigChange(freeformTask2.token)) } @Test fun handleRequest_notOpenOrToFrontTransition_returnNull() { assumeTrue(ENABLE_SHELL_TRANSITIONS) Loading Loading @@ -1813,3 +1833,11 @@ private fun WindowContainerTransaction.assertPendingIntentAt(index: Int, intent: assertThat(op.type).isEqualTo(HIERARCHY_OP_TYPE_PENDING_INTENT) assertThat(op.pendingIntent?.intent?.component).isEqualTo(intent.component) } private fun WindowContainerTransaction?.anyDensityConfigChange( token: WindowContainerToken ): Boolean { return this?.changes?.any { change -> change.key == token.asBinder() && ((change.value.configSetMask and CONFIG_DENSITY) != 0) } ?: false }