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

Commit 5f6167b7 authored by Kevin Chyn's avatar Kevin Chyn
Browse files

Coordinate rotation for concurrent mode

1) Adds DisplayRotationCoordinator which is used to coordinate
   default display rotation changes with non-default displays.

2) We now create DeviceStateController in RootWindowContainer and pass
   a single instance to DisplayContent/DisplayRotation. This allows
   for (3) below

3) Adds TestDisplayContent.Builder#setDeviceStateController, which
   allows tests to mock deviceStateController behavior

Bug: 251747141
Bug: 267343444

Test: atest DisplayRotationCoordinatorTests
Test: atest DisplayRotationTests
Test: atest DisplayContentTests
Test: atest DualDisplayAreaGroupPolicyTest
Test: presubmit for other unit tests
Test: manual

Change-Id: Ifae3806079ece87d6d14d09b3025ee19f9c9d226
parent e37ef8a3
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.view.Surface;
import android.view.Surface.Rotation;
import android.view.SurfaceControl;

@@ -245,4 +246,23 @@ public class RotationUtils {
                throw new IllegalArgumentException("Unknown rotation: " + rotation);
        }
    }

    /**
     * Reverses the rotation direction around the Z axis. Note that this method assumes all
     * rotations are relative to {@link Surface.ROTATION_0}.
     *
     * @param rotation the original rotation.
     * @return the new rotation that should be applied.
     */
    @Surface.Rotation
    public static int reverseRotationDirectionAroundZAxis(@Surface.Rotation int rotation) {
        // Flipping 270 and 90 has the same effect as changing the direction which rotation is
        // applied.
        if (rotation == Surface.ROTATION_90) {
            rotation = Surface.ROTATION_270;
        } else if (rotation == Surface.ROTATION_270) {
            rotation = Surface.ROTATION_90;
        }
        return rotation;
    }
}
+7 −0
Original line number Diff line number Diff line
@@ -980,6 +980,13 @@
    <integer-array name="config_deviceStatesToReverseDefaultDisplayRotationAroundZAxis">
    </integer-array>

    <!-- Boolean indicating whether secondary built-in displays should have their orientation
         match the active default display. This config assumes that the secondary display only
         requires swapping ROTATION_90 and ROTATION_270.
         TODO(b/265991392): This should eventually be configured and parsed in
          display_settings.xml -->
    <bool name="config_matchSecondaryInternalDisplaysOrientationToReverseDefaultDisplay">true</bool>

    <!-- Indicate available ColorDisplayManager.COLOR_MODE_xxx. -->
    <integer-array name="config_availableColorModes">
        <!-- Example:
+7 −0
Original line number Diff line number Diff line
@@ -3390,6 +3390,13 @@
       TODO(b/265312193): Remove this workaround when this bug is fixed.-->
  <java-symbol type="array" name="config_deviceStatesToReverseDefaultDisplayRotationAroundZAxis" />

  <!-- Boolean indicating whether secondary built-in displays should have their orientation
       match the active default display. This config assumes that the secondary display only
       requires swapping ROTATION_90 and ROTATION_270.
       TODO(b/265991392): This should eventually be configured and parsed in
        display_settings.xml -->
  <java-symbol type="bool" name="config_matchSecondaryInternalDisplaysOrientationToReverseDefaultDisplay" />

  <!-- Default user restrictions for the SYSTEM user -->
  <java-symbol type="array" name="config_defaultFirstUserRestrictions" />

+23 −9
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.os.Handler;
import android.os.HandlerExecutor;

import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.ArrayUtils;

import java.util.ArrayList;
@@ -48,9 +49,12 @@ final class DeviceStateController implements DeviceStateManager.DeviceStateCallb
    private final int[] mRearDisplayDeviceStates;
    @NonNull
    private final int[] mReverseRotationAroundZAxisStates;
    @GuardedBy("this")
    @NonNull
    private final List<Consumer<DeviceState>> mDeviceStateCallbacks = new ArrayList<>();

    private final boolean mMatchBuiltInDisplayOrientationToDefaultDisplay;

    @Nullable
    private DeviceState mLastDeviceState;
    private int mCurrentState;
@@ -72,21 +76,20 @@ final class DeviceStateController implements DeviceStateManager.DeviceStateCallb
                .getIntArray(R.array.config_rearDisplayDeviceStates);
        mReverseRotationAroundZAxisStates = context.getResources()
                .getIntArray(R.array.config_deviceStatesToReverseDefaultDisplayRotationAroundZAxis);
        mMatchBuiltInDisplayOrientationToDefaultDisplay = context.getResources()
                .getBoolean(R.bool
                        .config_matchSecondaryInternalDisplaysOrientationToReverseDefaultDisplay);

        if (mDeviceStateManager != null) {
            mDeviceStateManager.registerCallback(new HandlerExecutor(handler), this);
        }
    }

    void unregisterFromDeviceStateManager() {
        if (mDeviceStateManager != null) {
            mDeviceStateManager.unregisterCallback(this);
        }
    }

    void registerDeviceStateCallback(@NonNull Consumer<DeviceState> callback) {
        synchronized (this) {
            mDeviceStateCallbacks.add(callback);
        }
    }

    /**
     * @return true if the rotation direction on the Z axis should be reversed.
@@ -95,6 +98,15 @@ final class DeviceStateController implements DeviceStateManager.DeviceStateCallb
        return ArrayUtils.contains(mReverseRotationAroundZAxisStates, mCurrentState);
    }

    /**
     * @return true if non-default built-in displays should match the default display's rotation.
     */
    boolean shouldMatchBuiltInDisplayOrientationToReverseDefaultDisplay() {
        // TODO(b/265991392): This should come from display_settings.xml once it's easier to
        //  extend with complex configurations.
        return mMatchBuiltInDisplayOrientationToDefaultDisplay;
    }

    @Override
    public void onStateChanged(int state) {
        mCurrentState = state;
@@ -115,9 +127,11 @@ final class DeviceStateController implements DeviceStateManager.DeviceStateCallb
        if (mLastDeviceState == null || !mLastDeviceState.equals(deviceState)) {
            mLastDeviceState = deviceState;

            synchronized (this) {
                for (Consumer<DeviceState> callback : mDeviceStateCallbacks) {
                    callback.accept(mLastDeviceState);
                }
            }
        }
    }
}
+7 −5
Original line number Diff line number Diff line
@@ -590,7 +590,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
    final FixedRotationTransitionListener mFixedRotationTransitionListener =
            new FixedRotationTransitionListener();

    private final DeviceStateController mDeviceStateController;
    @VisibleForTesting
    final DeviceStateController mDeviceStateController;
    private final PhysicalDisplaySwitchTransitionLauncher mDisplaySwitchTransitionLauncher;
    final RemoteDisplayChangeController mRemoteDisplayChangeController;

@@ -1086,7 +1087,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
     * @param display May not be null.
     * @param root {@link RootWindowContainer}
     */
    DisplayContent(Display display, RootWindowContainer root) {
    DisplayContent(Display display, RootWindowContainer root,
            @NonNull DeviceStateController deviceStateController) {
        super(root.mWindowManager, "DisplayContent", FEATURE_ROOT);
        if (mWmService.mRoot.getDisplayContent(display.getDisplayId()) != null) {
            throw new IllegalArgumentException("Display with ID=" + display.getDisplayId()
@@ -1146,11 +1148,11 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
                    mWmService.mAtmService.getRecentTasks().getInputListener());
        }

        mDeviceStateController = new DeviceStateController(mWmService.mContext, mWmService.mH);
        mDeviceStateController = deviceStateController;

        mDisplayPolicy = new DisplayPolicy(mWmService, this);
        mDisplayRotation = new DisplayRotation(mWmService, this, mDisplayInfo.address,
                mDeviceStateController);
                mDeviceStateController, root.getDisplayRotationCoordinator());

        final Consumer<DeviceStateController.DeviceState> deviceStateConsumer =
                (@NonNull DeviceStateController.DeviceState newFoldState) -> {
@@ -3325,7 +3327,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
            mTransitionController.unregisterLegacyListener(mFixedRotationTransitionListener);
            handleAnimatingStoppedAndTransition();
            mWmService.stopFreezingDisplayLocked();
            mDeviceStateController.unregisterFromDeviceStateManager();
            mDisplayRotation.removeDefaultDisplayRotationChangedCallback();
            super.removeImmediately();
            if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Removing display=" + this);
            mPointerEventDispatcher.dispose();
Loading