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