Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e4ef6618 authored by HQ Liu's avatar HQ Liu
Browse files

Use RootTaskDisplayAreaOrganizer to change windowing mode

In core, windowing mode is being set in TDA with ag/19902621. Thus, set
windowing mode with RooTaskDisplayAreaOrganizer instead of
RootDisplayAreaOrganizer.

Bug: b/241168290
Test: services/tests/wmtests
Change-Id: Ib7e6701839f83ab4125a9630d20203f8c5e415ba
parent b25a29ed
Loading
Loading
Loading
Loading
+8 −0
Original line number Original line Diff line number Diff line
@@ -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}.
+2 −3
Original line number Original line Diff line number Diff line
@@ -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;
@@ -598,13 +597,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();
        }
        }
+26 −7
Original line number Original line Diff line number Diff line
@@ -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}
     */
     */
+18 −17
Original line number Original line Diff line number Diff line
@@ -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);
    }
    }