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 Diff line number Diff line
@@ -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}.
+2 −3
Original line number 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.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;
@@ -598,13 +597,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();
        }
+26 −7
Original line number 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 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;
@@ -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);
@@ -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}
     */
+18 −17
Original line number Diff line number Diff line
@@ -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;
@@ -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
@@ -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();
    }
@@ -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();
@@ -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);
    }
@@ -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();
@@ -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);
    }