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

Commit 83fe86c4 authored by HQ Liu's avatar HQ Liu Committed by Automerger Merge Worker
Browse files

Merge "Use RootTaskDisplayAreaOrganizer to change windowing mode" into tm-qpr-dev am: 51afb38b

parents 6258e32e 51afb38b
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;
@@ -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();
        }
+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);
    }