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

Commit 37400aec authored by Kenneth Ford's avatar Kenneth Ford Committed by Android (Google) Code Review
Browse files

Merge "Allow multiple displays to register for rotation coordination" into main

parents 31af15fb b0f6b1a6
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1484,7 +1484,7 @@ public class DisplayRotation {
    void removeDefaultDisplayRotationChangedCallback() {
        if (DisplayRotationCoordinator.isSecondaryInternalDisplay(mDisplayContent)) {
            mDisplayRotationCoordinator.removeDefaultDisplayRotationChangedCallback(
                    mDefaultDisplayRotationChangedCallback);
                    mDisplayContent.getDisplayId(), mDefaultDisplayRotationChangedCallback);
        }
    }

+13 −23
Original line number Diff line number Diff line
@@ -17,8 +17,8 @@
package com.android.server.wm;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.Slog;
import android.util.SparseArray;
import android.view.Display;
import android.view.Surface;

@@ -38,22 +38,21 @@ class DisplayRotationCoordinator {
    @Surface.Rotation
    private int mDefaultDisplayDefaultRotation;

    @Nullable
    @VisibleForTesting
    Runnable mDefaultDisplayRotationChangedCallback;
    private int mCallbackDisplayId = Display.INVALID_DISPLAY;

    @Surface.Rotation
    private int mDefaultDisplayCurrentRotation;

    @VisibleForTesting
    @NonNull
    final SparseArray<Runnable> mDefaultDisplayRotationChangedCallbacks = new SparseArray<>();

    /**
     * Notifies clients when the default display rotation changes.
     */
    void onDefaultDisplayRotationChanged(@Surface.Rotation int rotation) {
        mDefaultDisplayCurrentRotation = rotation;

        if (mDefaultDisplayRotationChangedCallback != null) {
            mDefaultDisplayRotationChangedCallback.run();
        for (int i = 0; i < mDefaultDisplayRotationChangedCallbacks.size(); i++) {
            mDefaultDisplayRotationChangedCallbacks.valueAt(i).run();
        }
    }

@@ -71,14 +70,7 @@ class DisplayRotationCoordinator {
     * query the default display's current rotation via {@link #getDefaultDisplayCurrentRotation()}.
     */
    void setDefaultDisplayRotationChangedCallback(int displayId, @NonNull Runnable callback) {
        if (mDefaultDisplayRotationChangedCallback != null && displayId != mCallbackDisplayId) {
            throw new UnsupportedOperationException("Multiple clients unsupported"
                    + ". Incoming displayId: " + displayId
                    + ", existing displayId: " + mCallbackDisplayId);
        }

        mDefaultDisplayRotationChangedCallback = callback;
        mCallbackDisplayId = displayId;
        mDefaultDisplayRotationChangedCallbacks.put(displayId, callback);

        if (mDefaultDisplayCurrentRotation != mDefaultDisplayDefaultRotation) {
            callback.run();
@@ -89,15 +81,13 @@ class DisplayRotationCoordinator {
     * Removes the callback that was added via
     * {@link #setDefaultDisplayRotationChangedCallback(int, Runnable)}.
     */
    void removeDefaultDisplayRotationChangedCallback(@NonNull Runnable callback) {
        if (callback != mDefaultDisplayRotationChangedCallback) {
            Slog.w(TAG, "Attempted to remove non-matching callback."
                    + " DisplayId: " + mCallbackDisplayId);
    void removeDefaultDisplayRotationChangedCallback(int displayId, @NonNull Runnable callback) {
        Runnable currentCallback = mDefaultDisplayRotationChangedCallbacks.get(displayId);
        if (!callback.equals(currentCallback)) {
            Slog.w(TAG, "Attempted to remove non-matching callback. DisplayId: " + displayId);
            return;
        }

        mDefaultDisplayRotationChangedCallback = null;
        mCallbackDisplayId = Display.INVALID_DISPLAY;
        mDefaultDisplayRotationChangedCallbacks.remove(displayId);
    }

    static boolean isSecondaryInternalDisplay(@NonNull DisplayContent displayContent) {
+4 −3
Original line number Diff line number Diff line
@@ -1824,7 +1824,8 @@ public class DisplayContentTests extends WindowTestsBase {

            // Check that secondary display registered callback
            assertEquals(secondaryDisplayRotation.mDefaultDisplayRotationChangedCallback,
                    coordinator.mDefaultDisplayRotationChangedCallback);
                    coordinator.mDefaultDisplayRotationChangedCallbacks.get(
                            secondaryDisplayContent.getDisplayId()));

            // Set the default display to a known orientation. This may be a zero or non-zero
            // rotation since mDisplayInfo.logicalWidth/Height depends on the DUT's default display
@@ -1863,9 +1864,9 @@ public class DisplayContentTests extends WindowTestsBase {

        // Create secondary non-internal displays
        createSecondaryDisplayContent(Display.TYPE_EXTERNAL, deviceStateController);
        assertNull(coordinator.mDefaultDisplayRotationChangedCallback);
        assertEquals(0, coordinator.mDefaultDisplayRotationChangedCallbacks.size());
        createSecondaryDisplayContent(Display.TYPE_VIRTUAL, deviceStateController);
        assertNull(coordinator.mDefaultDisplayRotationChangedCallback);
        assertEquals(0, coordinator.mDefaultDisplayRotationChangedCallbacks.size());
    }

    private DisplayContent createSecondaryDisplayContent(int displayType,
+11 −7
Original line number Diff line number Diff line
@@ -52,13 +52,14 @@ public class DisplayRotationCoordinatorTests {
        mCoordinator.onDefaultDisplayRotationChanged(Surface.ROTATION_90);
    }

    @Test (expected = UnsupportedOperationException.class)
    @Test
    public void testSecondRegistrationWithoutRemovingFirstWhenDifferentDisplay() {
        Runnable callback1 = mock(Runnable.class);
        Runnable callback2 = mock(Runnable.class);
        mCoordinator.setDefaultDisplayRotationChangedCallback(FIRST_DISPLAY_ID, callback1);
        mCoordinator.setDefaultDisplayRotationChangedCallback(SECOND_DISPLAY_ID, callback2);
        assertEquals(callback1, mCoordinator.mDefaultDisplayRotationChangedCallback);
        assertEquals(callback1,
                mCoordinator.mDefaultDisplayRotationChangedCallbacks.get(FIRST_DISPLAY_ID));
    }

    @Test
@@ -67,7 +68,8 @@ public class DisplayRotationCoordinatorTests {
        Runnable callback2 = mock(Runnable.class);
        mCoordinator.setDefaultDisplayRotationChangedCallback(FIRST_DISPLAY_ID, callback1);
        mCoordinator.setDefaultDisplayRotationChangedCallback(FIRST_DISPLAY_ID, callback2);
        assertEquals(callback2, mCoordinator.mDefaultDisplayRotationChangedCallback);
        assertEquals(callback2,
                mCoordinator.mDefaultDisplayRotationChangedCallbacks.get(FIRST_DISPLAY_ID));
    }

    @Test
@@ -75,20 +77,22 @@ public class DisplayRotationCoordinatorTests {
        Runnable callback1 = mock(Runnable.class);
        Runnable callback2 = mock(Runnable.class);
        mCoordinator.setDefaultDisplayRotationChangedCallback(FIRST_DISPLAY_ID, callback1);
        mCoordinator.removeDefaultDisplayRotationChangedCallback(callback2);
        assertEquals(callback1, mCoordinator.mDefaultDisplayRotationChangedCallback);
        mCoordinator.removeDefaultDisplayRotationChangedCallback(FIRST_DISPLAY_ID, callback2);
        assertEquals(callback1,
                mCoordinator.mDefaultDisplayRotationChangedCallbacks.get(FIRST_DISPLAY_ID));

        // FIRST_DISPLAY_ID is still able to register another callback because the previous
        // removal should not have succeeded.
        mCoordinator.setDefaultDisplayRotationChangedCallback(FIRST_DISPLAY_ID, callback2);
        assertEquals(callback2, mCoordinator.mDefaultDisplayRotationChangedCallback);
        assertEquals(callback2,
                mCoordinator.mDefaultDisplayRotationChangedCallbacks.get(FIRST_DISPLAY_ID));
    }

    @Test
    public void testSecondRegistrationAfterRemovingFirst() {
        Runnable callback1 = mock(Runnable.class);
        mCoordinator.setDefaultDisplayRotationChangedCallback(FIRST_DISPLAY_ID, callback1);
        mCoordinator.removeDefaultDisplayRotationChangedCallback(callback1);
        mCoordinator.removeDefaultDisplayRotationChangedCallback(FIRST_DISPLAY_ID, callback1);

        Runnable callback2 = mock(Runnable.class);
        mCoordinator.setDefaultDisplayRotationChangedCallback(SECOND_DISPLAY_ID, callback2);