Loading libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java +8 −0 Original line number Diff line number Diff line Loading @@ -178,6 +178,14 @@ public class RootTaskDisplayAreaOrganizer extends DisplayAreaOrganizer { applyConfigChangesToContext(displayAreaInfo); } /** * Returns the {@link DisplayAreaInfo} of the {@link DisplayAreaInfo#displayId}. */ @Nullable public DisplayAreaInfo getDisplayAreaInfo(int displayId) { return mDisplayAreasInfo.get(displayId); } /** * Applies the {@link DisplayAreaInfo} to the {@link DisplayAreaContext} specified by * {@link DisplayAreaInfo#displayId}. Loading libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +2 −3 Original line number Diff line number Diff line Loading @@ -27,7 +27,6 @@ import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.logging.UiEventLogger; import com.android.internal.statusbar.IStatusBarService; import com.android.launcher3.icons.IconProvider; import com.android.wm.shell.RootDisplayAreaOrganizer; import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.TaskViewTransitions; Loading Loading @@ -599,13 +598,13 @@ public abstract class WMShellModule { static Optional<DesktopModeController> provideDesktopModeController( Context context, ShellInit shellInit, ShellTaskOrganizer shellTaskOrganizer, RootDisplayAreaOrganizer rootDisplayAreaOrganizer, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer, @ShellMainThread Handler mainHandler, Transitions transitions ) { if (DesktopMode.IS_SUPPORTED) { return Optional.of(new DesktopModeController(context, shellInit, shellTaskOrganizer, rootDisplayAreaOrganizer, mainHandler, transitions)); rootTaskDisplayAreaOrganizer, mainHandler, transitions)); } else { return Optional.empty(); } Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java +26 −7 Original line number Diff line number Diff line Loading @@ -22,19 +22,21 @@ import static android.view.WindowManager.TRANSIT_CHANGE; import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE; import android.app.WindowConfiguration; import android.content.Context; import android.database.ContentObserver; import android.net.Uri; import android.os.Handler; import android.os.UserHandle; import android.provider.Settings; import android.window.DisplayAreaInfo; import android.window.WindowContainerTransaction; import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.protolog.common.ProtoLog; import com.android.wm.shell.RootDisplayAreaOrganizer; import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.annotations.ShellMainThread; import com.android.wm.shell.sysui.ShellInit; Loading @@ -47,18 +49,18 @@ public class DesktopModeController { private final Context mContext; private final ShellTaskOrganizer mShellTaskOrganizer; private final RootDisplayAreaOrganizer mRootDisplayAreaOrganizer; private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer; private final SettingsObserver mSettingsObserver; private final Transitions mTransitions; public DesktopModeController(Context context, ShellInit shellInit, ShellTaskOrganizer shellTaskOrganizer, RootDisplayAreaOrganizer rootDisplayAreaOrganizer, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer, @ShellMainThread Handler mainHandler, Transitions transitions) { mContext = context; mShellTaskOrganizer = shellTaskOrganizer; mRootDisplayAreaOrganizer = rootDisplayAreaOrganizer; mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer; mSettingsObserver = new SettingsObserver(mContext, mainHandler); mTransitions = transitions; shellInit.addInitCallback(this::onInit, this); Loading Loading @@ -92,15 +94,32 @@ public class DesktopModeController { wct.merge(mShellTaskOrganizer.prepareClearBoundsForStandardTasks(displayId), true /* transfer */); } wct.merge(mRootDisplayAreaOrganizer.prepareWindowingModeChange(displayId, targetWindowingMode), true /* transfer */); prepareWindowingModeChange(wct, displayId, targetWindowingMode); if (Transitions.ENABLE_SHELL_TRANSITIONS) { mTransitions.startTransition(TRANSIT_CHANGE, wct, null); } else { mRootDisplayAreaOrganizer.applyTransaction(wct); mRootTaskDisplayAreaOrganizer.applyTransaction(wct); } } private void prepareWindowingModeChange(WindowContainerTransaction wct, int displayId, @WindowConfiguration.WindowingMode int windowingMode) { DisplayAreaInfo displayAreaInfo = mRootTaskDisplayAreaOrganizer .getDisplayAreaInfo(displayId); if (displayAreaInfo == null) { ProtoLog.e(WM_SHELL_DESKTOP_MODE, "unable to update windowing mode for display %d display not found", displayId); return; } ProtoLog.d(WM_SHELL_DESKTOP_MODE, "setWindowingMode: displayId=%d current wmMode=%d new wmMode=%d", displayId, displayAreaInfo.configuration.windowConfiguration.getWindowingMode(), windowingMode); wct.setWindowingMode(displayAreaInfo.token, windowingMode); } /** * A {@link ContentObserver} for listening to changes to {@link Settings.System#DESKTOP_MODE} */ Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java +18 −17 Original line number Diff line number Diff line Loading @@ -32,13 +32,14 @@ import android.app.WindowConfiguration; import android.os.Handler; import android.os.IBinder; import android.testing.AndroidTestingRunner; import android.window.DisplayAreaInfo; import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; import android.window.WindowContainerTransaction.Change; import androidx.test.filters.SmallTest; import com.android.wm.shell.RootDisplayAreaOrganizer; import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.ShellTestCase; import com.android.wm.shell.common.ShellExecutor; Loading @@ -59,7 +60,7 @@ public class DesktopModeControllerTest extends ShellTestCase { @Mock private ShellTaskOrganizer mShellTaskOrganizer; @Mock private RootDisplayAreaOrganizer mRootDisplayAreaOrganizer; private RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer; @Mock private ShellExecutor mTestExecutor; @Mock Loading @@ -75,7 +76,7 @@ public class DesktopModeControllerTest extends ShellTestCase { mShellInit = Mockito.spy(new ShellInit(mTestExecutor)); mController = new DesktopModeController(mContext, mShellInit, mShellTaskOrganizer, mRootDisplayAreaOrganizer, mMockHandler, mMockTransitions); mRootTaskDisplayAreaOrganizer, mMockHandler, mMockTransitions); mShellInit.init(); } Loading @@ -94,19 +95,19 @@ public class DesktopModeControllerTest extends ShellTestCase { when(mShellTaskOrganizer.prepareClearFreeformForStandardTasks( mContext.getDisplayId())).thenReturn(taskWct); // Create a fake WCT to simulate setting display windowing mode to freeform WindowContainerTransaction displayWct = new WindowContainerTransaction(); // Create a fake DisplayAreaInfo to check if windowing mode change is set correctly MockToken displayMockToken = new MockToken(); displayWct.setWindowingMode(displayMockToken.token(), WINDOWING_MODE_FREEFORM); when(mRootDisplayAreaOrganizer.prepareWindowingModeChange(mContext.getDisplayId(), WINDOWING_MODE_FREEFORM)).thenReturn(displayWct); DisplayAreaInfo displayAreaInfo = new DisplayAreaInfo(displayMockToken.mToken, mContext.getDisplayId(), 0); when(mRootTaskDisplayAreaOrganizer.getDisplayAreaInfo(mContext.getDisplayId())) .thenReturn(displayAreaInfo); // The test mController.updateDesktopModeActive(true); ArgumentCaptor<WindowContainerTransaction> arg = ArgumentCaptor.forClass( WindowContainerTransaction.class); verify(mRootDisplayAreaOrganizer).applyTransaction(arg.capture()); verify(mRootTaskDisplayAreaOrganizer).applyTransaction(arg.capture()); // WCT should have 2 changes - clear task wm mode and set display wm mode WindowContainerTransaction wct = arg.getValue(); Loading @@ -118,7 +119,7 @@ public class DesktopModeControllerTest extends ShellTestCase { assertThat(taskWmModeChange.getWindowingMode()).isEqualTo(WINDOWING_MODE_UNDEFINED); // Verify executed WCT has a change for setting display windowing mode to freeform Change displayWmModeChange = wct.getChanges().get(displayMockToken.binder()); Change displayWmModeChange = wct.getChanges().get(displayAreaInfo.token.asBinder()); assertThat(displayWmModeChange).isNotNull(); assertThat(displayWmModeChange.getWindowingMode()).isEqualTo(WINDOWING_MODE_FREEFORM); } Loading @@ -139,19 +140,19 @@ public class DesktopModeControllerTest extends ShellTestCase { when(mShellTaskOrganizer.prepareClearBoundsForStandardTasks( mContext.getDisplayId())).thenReturn(taskBoundsWct); // Create a fake WCT to simulate setting display windowing mode to fullscreen WindowContainerTransaction displayWct = new WindowContainerTransaction(); // Create a fake DisplayAreaInfo to check if windowing mode change is set correctly MockToken displayMockToken = new MockToken(); displayWct.setWindowingMode(displayMockToken.token(), WINDOWING_MODE_FULLSCREEN); when(mRootDisplayAreaOrganizer.prepareWindowingModeChange(mContext.getDisplayId(), WINDOWING_MODE_FULLSCREEN)).thenReturn(displayWct); DisplayAreaInfo displayAreaInfo = new DisplayAreaInfo(displayMockToken.mToken, mContext.getDisplayId(), 0); when(mRootTaskDisplayAreaOrganizer.getDisplayAreaInfo(mContext.getDisplayId())) .thenReturn(displayAreaInfo); // The test mController.updateDesktopModeActive(false); ArgumentCaptor<WindowContainerTransaction> arg = ArgumentCaptor.forClass( WindowContainerTransaction.class); verify(mRootDisplayAreaOrganizer).applyTransaction(arg.capture()); verify(mRootTaskDisplayAreaOrganizer).applyTransaction(arg.capture()); // WCT should have 3 changes - clear task wm mode and bounds and set display wm mode WindowContainerTransaction wct = arg.getValue(); Loading @@ -171,7 +172,7 @@ public class DesktopModeControllerTest extends ShellTestCase { .isTrue(); // Verify executed WCT has a change for setting display windowing mode to fullscreen Change displayWmModeChange = wct.getChanges().get(displayMockToken.binder()); Change displayWmModeChange = wct.getChanges().get(displayAreaInfo.token.asBinder()); assertThat(displayWmModeChange).isNotNull(); assertThat(displayWmModeChange.getWindowingMode()).isEqualTo(WINDOWING_MODE_FULLSCREEN); } Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java +8 −0 Original line number Diff line number Diff line Loading @@ -178,6 +178,14 @@ public class RootTaskDisplayAreaOrganizer extends DisplayAreaOrganizer { applyConfigChangesToContext(displayAreaInfo); } /** * Returns the {@link DisplayAreaInfo} of the {@link DisplayAreaInfo#displayId}. */ @Nullable public DisplayAreaInfo getDisplayAreaInfo(int displayId) { return mDisplayAreasInfo.get(displayId); } /** * Applies the {@link DisplayAreaInfo} to the {@link DisplayAreaContext} specified by * {@link DisplayAreaInfo#displayId}. Loading
libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +2 −3 Original line number Diff line number Diff line Loading @@ -27,7 +27,6 @@ import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.logging.UiEventLogger; import com.android.internal.statusbar.IStatusBarService; import com.android.launcher3.icons.IconProvider; import com.android.wm.shell.RootDisplayAreaOrganizer; import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.TaskViewTransitions; Loading Loading @@ -599,13 +598,13 @@ public abstract class WMShellModule { static Optional<DesktopModeController> provideDesktopModeController( Context context, ShellInit shellInit, ShellTaskOrganizer shellTaskOrganizer, RootDisplayAreaOrganizer rootDisplayAreaOrganizer, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer, @ShellMainThread Handler mainHandler, Transitions transitions ) { if (DesktopMode.IS_SUPPORTED) { return Optional.of(new DesktopModeController(context, shellInit, shellTaskOrganizer, rootDisplayAreaOrganizer, mainHandler, transitions)); rootTaskDisplayAreaOrganizer, mainHandler, transitions)); } else { return Optional.empty(); } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeController.java +26 −7 Original line number Diff line number Diff line Loading @@ -22,19 +22,21 @@ import static android.view.WindowManager.TRANSIT_CHANGE; import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE; import android.app.WindowConfiguration; import android.content.Context; import android.database.ContentObserver; import android.net.Uri; import android.os.Handler; import android.os.UserHandle; import android.provider.Settings; import android.window.DisplayAreaInfo; import android.window.WindowContainerTransaction; import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.protolog.common.ProtoLog; import com.android.wm.shell.RootDisplayAreaOrganizer; import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.annotations.ShellMainThread; import com.android.wm.shell.sysui.ShellInit; Loading @@ -47,18 +49,18 @@ public class DesktopModeController { private final Context mContext; private final ShellTaskOrganizer mShellTaskOrganizer; private final RootDisplayAreaOrganizer mRootDisplayAreaOrganizer; private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer; private final SettingsObserver mSettingsObserver; private final Transitions mTransitions; public DesktopModeController(Context context, ShellInit shellInit, ShellTaskOrganizer shellTaskOrganizer, RootDisplayAreaOrganizer rootDisplayAreaOrganizer, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer, @ShellMainThread Handler mainHandler, Transitions transitions) { mContext = context; mShellTaskOrganizer = shellTaskOrganizer; mRootDisplayAreaOrganizer = rootDisplayAreaOrganizer; mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer; mSettingsObserver = new SettingsObserver(mContext, mainHandler); mTransitions = transitions; shellInit.addInitCallback(this::onInit, this); Loading Loading @@ -92,15 +94,32 @@ public class DesktopModeController { wct.merge(mShellTaskOrganizer.prepareClearBoundsForStandardTasks(displayId), true /* transfer */); } wct.merge(mRootDisplayAreaOrganizer.prepareWindowingModeChange(displayId, targetWindowingMode), true /* transfer */); prepareWindowingModeChange(wct, displayId, targetWindowingMode); if (Transitions.ENABLE_SHELL_TRANSITIONS) { mTransitions.startTransition(TRANSIT_CHANGE, wct, null); } else { mRootDisplayAreaOrganizer.applyTransaction(wct); mRootTaskDisplayAreaOrganizer.applyTransaction(wct); } } private void prepareWindowingModeChange(WindowContainerTransaction wct, int displayId, @WindowConfiguration.WindowingMode int windowingMode) { DisplayAreaInfo displayAreaInfo = mRootTaskDisplayAreaOrganizer .getDisplayAreaInfo(displayId); if (displayAreaInfo == null) { ProtoLog.e(WM_SHELL_DESKTOP_MODE, "unable to update windowing mode for display %d display not found", displayId); return; } ProtoLog.d(WM_SHELL_DESKTOP_MODE, "setWindowingMode: displayId=%d current wmMode=%d new wmMode=%d", displayId, displayAreaInfo.configuration.windowConfiguration.getWindowingMode(), windowingMode); wct.setWindowingMode(displayAreaInfo.token, windowingMode); } /** * A {@link ContentObserver} for listening to changes to {@link Settings.System#DESKTOP_MODE} */ Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeControllerTest.java +18 −17 Original line number Diff line number Diff line Loading @@ -32,13 +32,14 @@ import android.app.WindowConfiguration; import android.os.Handler; import android.os.IBinder; import android.testing.AndroidTestingRunner; import android.window.DisplayAreaInfo; import android.window.WindowContainerToken; import android.window.WindowContainerTransaction; import android.window.WindowContainerTransaction.Change; import androidx.test.filters.SmallTest; import com.android.wm.shell.RootDisplayAreaOrganizer; import com.android.wm.shell.RootTaskDisplayAreaOrganizer; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.ShellTestCase; import com.android.wm.shell.common.ShellExecutor; Loading @@ -59,7 +60,7 @@ public class DesktopModeControllerTest extends ShellTestCase { @Mock private ShellTaskOrganizer mShellTaskOrganizer; @Mock private RootDisplayAreaOrganizer mRootDisplayAreaOrganizer; private RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer; @Mock private ShellExecutor mTestExecutor; @Mock Loading @@ -75,7 +76,7 @@ public class DesktopModeControllerTest extends ShellTestCase { mShellInit = Mockito.spy(new ShellInit(mTestExecutor)); mController = new DesktopModeController(mContext, mShellInit, mShellTaskOrganizer, mRootDisplayAreaOrganizer, mMockHandler, mMockTransitions); mRootTaskDisplayAreaOrganizer, mMockHandler, mMockTransitions); mShellInit.init(); } Loading @@ -94,19 +95,19 @@ public class DesktopModeControllerTest extends ShellTestCase { when(mShellTaskOrganizer.prepareClearFreeformForStandardTasks( mContext.getDisplayId())).thenReturn(taskWct); // Create a fake WCT to simulate setting display windowing mode to freeform WindowContainerTransaction displayWct = new WindowContainerTransaction(); // Create a fake DisplayAreaInfo to check if windowing mode change is set correctly MockToken displayMockToken = new MockToken(); displayWct.setWindowingMode(displayMockToken.token(), WINDOWING_MODE_FREEFORM); when(mRootDisplayAreaOrganizer.prepareWindowingModeChange(mContext.getDisplayId(), WINDOWING_MODE_FREEFORM)).thenReturn(displayWct); DisplayAreaInfo displayAreaInfo = new DisplayAreaInfo(displayMockToken.mToken, mContext.getDisplayId(), 0); when(mRootTaskDisplayAreaOrganizer.getDisplayAreaInfo(mContext.getDisplayId())) .thenReturn(displayAreaInfo); // The test mController.updateDesktopModeActive(true); ArgumentCaptor<WindowContainerTransaction> arg = ArgumentCaptor.forClass( WindowContainerTransaction.class); verify(mRootDisplayAreaOrganizer).applyTransaction(arg.capture()); verify(mRootTaskDisplayAreaOrganizer).applyTransaction(arg.capture()); // WCT should have 2 changes - clear task wm mode and set display wm mode WindowContainerTransaction wct = arg.getValue(); Loading @@ -118,7 +119,7 @@ public class DesktopModeControllerTest extends ShellTestCase { assertThat(taskWmModeChange.getWindowingMode()).isEqualTo(WINDOWING_MODE_UNDEFINED); // Verify executed WCT has a change for setting display windowing mode to freeform Change displayWmModeChange = wct.getChanges().get(displayMockToken.binder()); Change displayWmModeChange = wct.getChanges().get(displayAreaInfo.token.asBinder()); assertThat(displayWmModeChange).isNotNull(); assertThat(displayWmModeChange.getWindowingMode()).isEqualTo(WINDOWING_MODE_FREEFORM); } Loading @@ -139,19 +140,19 @@ public class DesktopModeControllerTest extends ShellTestCase { when(mShellTaskOrganizer.prepareClearBoundsForStandardTasks( mContext.getDisplayId())).thenReturn(taskBoundsWct); // Create a fake WCT to simulate setting display windowing mode to fullscreen WindowContainerTransaction displayWct = new WindowContainerTransaction(); // Create a fake DisplayAreaInfo to check if windowing mode change is set correctly MockToken displayMockToken = new MockToken(); displayWct.setWindowingMode(displayMockToken.token(), WINDOWING_MODE_FULLSCREEN); when(mRootDisplayAreaOrganizer.prepareWindowingModeChange(mContext.getDisplayId(), WINDOWING_MODE_FULLSCREEN)).thenReturn(displayWct); DisplayAreaInfo displayAreaInfo = new DisplayAreaInfo(displayMockToken.mToken, mContext.getDisplayId(), 0); when(mRootTaskDisplayAreaOrganizer.getDisplayAreaInfo(mContext.getDisplayId())) .thenReturn(displayAreaInfo); // The test mController.updateDesktopModeActive(false); ArgumentCaptor<WindowContainerTransaction> arg = ArgumentCaptor.forClass( WindowContainerTransaction.class); verify(mRootDisplayAreaOrganizer).applyTransaction(arg.capture()); verify(mRootTaskDisplayAreaOrganizer).applyTransaction(arg.capture()); // WCT should have 3 changes - clear task wm mode and bounds and set display wm mode WindowContainerTransaction wct = arg.getValue(); Loading @@ -171,7 +172,7 @@ public class DesktopModeControllerTest extends ShellTestCase { .isTrue(); // Verify executed WCT has a change for setting display windowing mode to fullscreen Change displayWmModeChange = wct.getChanges().get(displayMockToken.binder()); Change displayWmModeChange = wct.getChanges().get(displayAreaInfo.token.asBinder()); assertThat(displayWmModeChange).isNotNull(); assertThat(displayWmModeChange.getWindowingMode()).isEqualTo(WINDOWING_MODE_FULLSCREEN); } Loading