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

Commit 56af8626 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Reset WindowContainerTransaction when rotation changed callback"

parents 26e228da 038ca7f4
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -77,7 +77,7 @@ public class OneHandedController implements OneHanded {
    private final DisplayChangeController.OnDisplayChangingListener mRotationController =
            (display, fromRotation, toRotation, wct) -> {
                if (mDisplayAreaOrganizer != null) {
                    mDisplayAreaOrganizer.onRotateDisplay(fromRotation, toRotation);
                    mDisplayAreaOrganizer.onRotateDisplay(fromRotation, toRotation, wct);
                }
            };

+40 −36
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.graphics.Rect;
import android.os.Handler;
import android.os.Looper;
import android.os.SystemProperties;
import android.util.ArrayMap;
import android.util.Log;
import android.view.SurfaceControl;
import android.window.DisplayAreaInfo;
@@ -42,7 +43,6 @@ import com.android.wm.shell.common.DisplayController;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;

@@ -76,7 +76,7 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
    private int mEnterExitAnimationDurationMs;

    @VisibleForTesting
    HashMap<DisplayAreaInfo, SurfaceControl> mDisplayAreaMap = new HashMap();
    ArrayMap<DisplayAreaInfo, SurfaceControl> mDisplayAreaMap = new ArrayMap();
    private DisplayController mDisplayController;
    private OneHandedAnimationController mAnimationController;
    private OneHandedSurfaceTransactionHelper.SurfaceControlTransactionFactory
@@ -117,12 +117,13 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
    private Handler.Callback mUpdateCallback = (msg) -> {
        SomeArgs args = (SomeArgs) msg.obj;
        final Rect currentBounds = args.arg1 != null ? (Rect) args.arg1 : mDefaultDisplayBounds;
        final WindowContainerTransaction wctFromRotate = (WindowContainerTransaction) args.arg2;
        final int yOffset = args.argi2;
        final int direction = args.argi3;

        switch (msg.what) {
            case MSG_RESET_IMMEDIATE:
                resetWindowsOffset();
                resetWindowsOffset(wctFromRotate);
                mDefaultDisplayBounds.set(currentBounds);
                mLastVisualDisplayBounds.set(currentBounds);
                finishOffset(0, TRANSITION_DIRECTION_EXIT);
@@ -165,47 +166,44 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
            @NonNull SurfaceControl leash) {
        Objects.requireNonNull(displayAreaInfo, "displayAreaInfo must not be null");
        Objects.requireNonNull(leash, "leash must not be null");

        if (displayAreaInfo.featureId != FEATURE_ONE_HANDED) {
            Log.w(TAG, "Bypass onDisplayAreaAppeared()! displayAreaInfo=" + displayAreaInfo);
            return;
        }
        synchronized (this) {
            if (mDisplayAreaMap.get(displayAreaInfo) == null) {
                // mDefaultDisplayBounds may out of date after removeDisplayChangingController()
                mDefaultDisplayBounds.set(getDisplayBounds());
                mDisplayAreaMap.put(displayAreaInfo, leash);
            }
        }
    }

    @Override
    public void onDisplayAreaVanished(@NonNull DisplayAreaInfo displayAreaInfo) {
        Objects.requireNonNull(displayAreaInfo,
                "Requires valid displayArea, and displayArea must not be null");

        synchronized (this) {
            if (!mDisplayAreaMap.containsKey(displayAreaInfo)) {
                Log.w(TAG, "Unrecognized token: " + displayAreaInfo.token);
                return;
            }
            mDisplayAreaMap.remove(displayAreaInfo);
        }
    }

    @Override
    public void unregisterOrganizer() {
        super.unregisterOrganizer();
        resetWindowsOffset();

        // Ensure all cached instance are cleared after resetWindowsOffset
        mUpdateHandler.post(() -> {
            if (mDisplayAreaMap != null && !mDisplayAreaMap.isEmpty()) {
                mDisplayAreaMap.clear();
            }
        });
        mUpdateHandler.post(() -> resetWindowsOffset(null));
    }

    /**
     * Handler for display rotation changes by below policy which
     * handles 90 degree display rotation changes {@link Surface.Rotation}
     * handles 90 degree display rotation changes {@link Surface.Rotation}.
     *
     * @param fromRotation starting rotation of the display.
     * @param toRotation target rotation of the display (after rotating).
     * @param wct A task transaction {@link WindowContainerTransaction} from
     *        {@link DisplayChangeController} to populate.
     */
    public void onRotateDisplay(int fromRotation, int toRotation) {
    public void onRotateDisplay(int fromRotation, int toRotation, WindowContainerTransaction wct) {
        // Stop one handed without animation and reset cropped size immediately
        final Rect newBounds = new Rect(mDefaultDisplayBounds);
        final boolean isOrientationDiff = Math.abs(fromRotation - toRotation) % 2 == 1;
@@ -214,6 +212,7 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
            newBounds.set(newBounds.left, newBounds.top, newBounds.bottom, newBounds.right);
            SomeArgs args = SomeArgs.obtain();
            args.arg1 = newBounds;
            args.arg2 = wct;
            args.argi1 = 0 /* xOffset */;
            args.argi2 = 0 /* yOffset */;
            args.argi3 = TRANSITION_DIRECTION_EXIT;
@@ -239,18 +238,19 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
            throw new RuntimeException("Callers should call scheduleOffset() instead of this "
                    + "directly");
        }
        synchronized (this) {
            final WindowContainerTransaction wct = new WindowContainerTransaction();
            mDisplayAreaMap.forEach(
                    (key, leash) -> {
                    animateWindows(leash, fromBounds, toBounds, direction,
                            durationMs);
                        animateWindows(leash, fromBounds, toBounds, direction, durationMs);
                        wct.setBounds(key.token, toBounds);
                    });
            applyTransaction(wct);
        }
    }

    private void resetWindowsOffset() {
        mUpdateHandler.post(() -> {
    private void resetWindowsOffset(WindowContainerTransaction wct) {
        synchronized (this) {
            final SurfaceControl.Transaction tx =
                    mSurfaceControlTransactionFactory.getTransaction();
            mDisplayAreaMap.forEach(
@@ -262,9 +262,13 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
                        }
                        tx.setPosition(leash, 0, 0)
                                .setWindowCrop(leash, -1/* reset */, -1/* reset */);
                        // DisplayRotationController will applyTransaction() after finish rotating
                        if (wct != null) {
                            wct.setBounds(key.token, null/* reset */);
                        }
                    });
            tx.apply();
        });
        }
    }

    private void animateWindows(SurfaceControl leash, Rect fromBounds, Rect toBounds,
+112 −61
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import android.view.SurfaceControl;
import android.window.DisplayAreaInfo;
import android.window.IWindowContainerToken;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;

import androidx.test.filters.SmallTest;

@@ -49,7 +50,6 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;

@SmallTest
@RunWith(AndroidTestingRunner.class)
@@ -60,11 +60,13 @@ public class OneHandedDisplayAreaOrganizerTest extends OneHandedTestCase {

    DisplayAreaInfo mDisplayAreaInfo;
    Display mDisplay;
    Handler mUpdateHandler;
    OneHandedDisplayAreaOrganizer mDisplayAreaOrganizer;
    OneHandedTutorialHandler mTutorialHandler;
    OneHandedAnimationController.OneHandedTransitionAnimator mFakeAnimator;
    WindowContainerToken mToken;
    SurfaceControl mLeash;
    TestableLooper mTestableLooper;
    @Mock
    IWindowContainerToken mMockRealToken;
    @Mock
@@ -77,12 +79,13 @@ public class OneHandedDisplayAreaOrganizerTest extends OneHandedTestCase {
    DisplayController mMockDisplayController;
    @Mock
    SurfaceControl mMockLeash;
    @Spy
    Handler mUpdateHandler;
    @Mock
    WindowContainerTransaction mMockWindowContainerTransaction;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        mTestableLooper = TestableLooper.get(this);
        mToken = new WindowContainerToken(mMockRealToken);
        mLeash = new SurfaceControl();
        mDisplay = mContext.getDisplay();
@@ -110,14 +113,10 @@ public class OneHandedDisplayAreaOrganizerTest extends OneHandedTestCase {
        mUpdateHandler = mDisplayAreaOrganizer.getUpdateHandler();
    }

    @Test
    public void testGetDisplayAreaUpdateHandler_isNotNull() {
        assertThat(mUpdateHandler).isNotNull();
    }

    @Test
    public void testOnDisplayAreaAppeared() {
        mDisplayAreaOrganizer.onDisplayAreaAppeared(mDisplayAreaInfo, mLeash);
        mTestableLooper.processAllMessages();

        verify(mMockAnimationController, never()).getAnimator(any(), any(), any());
    }
@@ -125,17 +124,10 @@ public class OneHandedDisplayAreaOrganizerTest extends OneHandedTestCase {
    @Test
    public void testOnDisplayAreaVanished() {
        mDisplayAreaOrganizer.onDisplayAreaAppeared(mDisplayAreaInfo, mLeash);
        mTestableLooper.processAllMessages();
        mDisplayAreaOrganizer.onDisplayAreaVanished(mDisplayAreaInfo);
    }

    @Test
    public void testOnDisplayAreaInfoChanged_updateDisplayAreaInfo() {
        final DisplayAreaInfo newDisplayAreaInfo = new DisplayAreaInfo(mToken, DEFAULT_DISPLAY,
                FEATURE_ONE_HANDED);
        mDisplayAreaOrganizer.onDisplayAreaAppeared(mDisplayAreaInfo, mLeash);
        mDisplayAreaOrganizer.onDisplayAreaInfoChanged(newDisplayAreaInfo);

        assertThat(mDisplayAreaOrganizer.mDisplayAreaMap.containsKey(mDisplayAreaInfo)).isTrue();
        assertThat(mDisplayAreaOrganizer.mDisplayAreaMap).isEmpty();
    }

    @Ignore("b/160848002")
@@ -143,142 +135,201 @@ public class OneHandedDisplayAreaOrganizerTest extends OneHandedTestCase {
    public void testScheduleOffset() {
        final int xOffSet = 0;
        final int yOffSet = 100;

        TestableLooper.get(this).processAllMessages();
        mDisplayAreaOrganizer.onDisplayAreaAppeared(mDisplayAreaInfo, mLeash);
        mDisplayAreaOrganizer.scheduleOffset(xOffSet, yOffSet);
        mTestableLooper.processAllMessages();

        assertThat(mUpdateHandler.hasMessages(
                OneHandedDisplayAreaOrganizer.MSG_OFFSET_ANIMATE)).isEqualTo(true);
    }

    @Ignore("b/160848002")
    @Test
    public void testRotation_portraitToLandscape() {
    public void testRotation_portrait_0_to_landscape_90() {
        when(mMockLeash.isValid()).thenReturn(false);
        // Rotate 0 -> 90
        TestableLooper.get(this).processAllMessages();
        mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_0, Surface.ROTATION_90);
        mTestableLooper.processAllMessages();
        mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_0, Surface.ROTATION_90,
                mMockWindowContainerTransaction);

        assertThat(mUpdateHandler.hasMessages(
                OneHandedDisplayAreaOrganizer.MSG_RESET_IMMEDIATE)).isEqualTo(true);
    }

    @Test
    public void testRotation_portrait_0_to_seascape_270() {
        when(mMockLeash.isValid()).thenReturn(false);
        // Rotate 0 -> 270
        TestableLooper.get(this).processAllMessages();
        mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_0, Surface.ROTATION_270);
        mTestableLooper.processAllMessages();
        mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_0, Surface.ROTATION_270,
                mMockWindowContainerTransaction);

        assertThat(mUpdateHandler.hasMessages(
                OneHandedDisplayAreaOrganizer.MSG_RESET_IMMEDIATE)).isEqualTo(true);

    }

    @Test
    public void testRotation_portrait_180_to_landscape_90() {
        when(mMockLeash.isValid()).thenReturn(false);
        // Rotate 180 -> 90
        TestableLooper.get(this).processAllMessages();
        mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_180, Surface.ROTATION_90);
        mTestableLooper.processAllMessages();
        mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_180, Surface.ROTATION_90,
                mMockWindowContainerTransaction);

        assertThat(mUpdateHandler.hasMessages(
                OneHandedDisplayAreaOrganizer.MSG_RESET_IMMEDIATE)).isEqualTo(true);
    }

    @Test
    public void testRotation_portrait_180_to_seascape_270() {
        when(mMockLeash.isValid()).thenReturn(false);
        // Rotate 180 -> 270
        TestableLooper.get(this).processAllMessages();
        mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_180, Surface.ROTATION_270);
        mTestableLooper.processAllMessages();
        mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_180, Surface.ROTATION_270,
                mMockWindowContainerTransaction);

        assertThat(mUpdateHandler.hasMessages(
                OneHandedDisplayAreaOrganizer.MSG_RESET_IMMEDIATE)).isEqualTo(true);
    }

    @Ignore("b/160848002")
    @Test
    public void testRotation_landscapeToPortrait() {
    public void testRotation_landscape_90_to_portrait_0() {
        when(mMockLeash.isValid()).thenReturn(false);
        // Rotate 90 -> 0
        TestableLooper.get(this).processAllMessages();
        mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_90, Surface.ROTATION_0);
        mTestableLooper.processAllMessages();
        mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_90, Surface.ROTATION_0,
                mMockWindowContainerTransaction);

        assertThat(mUpdateHandler.hasMessages(
                OneHandedDisplayAreaOrganizer.MSG_RESET_IMMEDIATE)).isEqualTo(true);
    }

    @Test
    public void testRotation_landscape_90_to_portrait_180() {
        when(mMockLeash.isValid()).thenReturn(false);
        // Rotate 90 -> 180
        TestableLooper.get(this).processAllMessages();
        mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_90, Surface.ROTATION_180);
        mTestableLooper.processAllMessages();
        mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_90, Surface.ROTATION_180,
                mMockWindowContainerTransaction);

        assertThat(mUpdateHandler.hasMessages(
                OneHandedDisplayAreaOrganizer.MSG_RESET_IMMEDIATE)).isEqualTo(true);
    }

    @Test
    public void testRotation_Seascape_270_to_portrait_0() {
        when(mMockLeash.isValid()).thenReturn(false);
        // Rotate 270 -> 0
        TestableLooper.get(this).processAllMessages();
        mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_270, Surface.ROTATION_0);
        mTestableLooper.processAllMessages();
        mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_270, Surface.ROTATION_0,
                mMockWindowContainerTransaction);

        assertThat(mUpdateHandler.hasMessages(
                OneHandedDisplayAreaOrganizer.MSG_RESET_IMMEDIATE)).isEqualTo(true);
    }

    @Test
    public void testRotation_seascape_90_to_portrait_180() {
        when(mMockLeash.isValid()).thenReturn(false);
        // Rotate 270 -> 180
        TestableLooper.get(this).processAllMessages();
        mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_270, Surface.ROTATION_180);
        mTestableLooper.processAllMessages();
        mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_270, Surface.ROTATION_180,
                mMockWindowContainerTransaction);

        assertThat(mUpdateHandler.hasMessages(
                OneHandedDisplayAreaOrganizer.MSG_RESET_IMMEDIATE)).isEqualTo(true);
    }

    @Ignore("b/160848002")
    @Test
    public void testRotation_portraitToPortrait() {
    public void testRotation_portrait_0_to_portrait_0() {
        when(mMockLeash.isValid()).thenReturn(false);
        // Rotate 0 -> 0
        TestableLooper.get(this).processAllMessages();
        mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_0, Surface.ROTATION_0);
        mTestableLooper.processAllMessages();
        mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_0, Surface.ROTATION_0,
                mMockWindowContainerTransaction);

        assertThat(mUpdateHandler.hasMessages(
                OneHandedDisplayAreaOrganizer.MSG_RESET_IMMEDIATE)).isEqualTo(false);
    }

    @Test
    public void testRotation_portrait_0_to_portrait_180() {
        when(mMockLeash.isValid()).thenReturn(false);
        // Rotate 0 -> 180
        TestableLooper.get(this).processAllMessages();
        mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_0, Surface.ROTATION_180);
        mTestableLooper.processAllMessages();
        mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_0, Surface.ROTATION_180,
                mMockWindowContainerTransaction);

        assertThat(mUpdateHandler.hasMessages(
                OneHandedDisplayAreaOrganizer.MSG_RESET_IMMEDIATE)).isEqualTo(false);
    }

    @Test
    public void testRotation_portrait_180_to_portrait_180() {
        when(mMockLeash.isValid()).thenReturn(false);
        // Rotate 180 -> 180
        TestableLooper.get(this).processAllMessages();
        mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_180, Surface.ROTATION_180);
        mTestableLooper.processAllMessages();
        mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_180, Surface.ROTATION_180,
                mMockWindowContainerTransaction);

        assertThat(mUpdateHandler.hasMessages(
                OneHandedDisplayAreaOrganizer.MSG_RESET_IMMEDIATE)).isEqualTo(false);
    }

        // Rotate 180 -> 180
        TestableLooper.get(this).processAllMessages();
        mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_180, Surface.ROTATION_0);
    @Test
    public void testRotation_portrait_180_to_portrait_0() {
        when(mMockLeash.isValid()).thenReturn(false);
        // Rotate 180 -> 0
        mTestableLooper.processAllMessages();
        mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_180, Surface.ROTATION_0,
                mMockWindowContainerTransaction);

        assertThat(mUpdateHandler.hasMessages(
                OneHandedDisplayAreaOrganizer.MSG_RESET_IMMEDIATE)).isEqualTo(false);
    }

    @Ignore("b/160848002")
    @Test
    public void testRotation_landscapeToLandscape() {
    public void testRotation_landscape_90_to_landscape_90() {
        when(mMockLeash.isValid()).thenReturn(false);
        // Rotate 90 -> 90
        TestableLooper.get(this).processAllMessages();
        mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_90, Surface.ROTATION_90);
        mTestableLooper.processAllMessages();
        mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_90, Surface.ROTATION_90,
                mMockWindowContainerTransaction);

        assertThat(mUpdateHandler.hasMessages(
                OneHandedDisplayAreaOrganizer.MSG_RESET_IMMEDIATE)).isEqualTo(false);
    }

    @Test
    public void testRotation_landscape_90_to_seascape_270() {
        when(mMockLeash.isValid()).thenReturn(false);
        // Rotate 90 -> 270
        TestableLooper.get(this).processAllMessages();
        mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_90, Surface.ROTATION_270);
        mTestableLooper.processAllMessages();
        mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_90, Surface.ROTATION_270,
                mMockWindowContainerTransaction);

        assertThat(mUpdateHandler.hasMessages(
                OneHandedDisplayAreaOrganizer.MSG_RESET_IMMEDIATE)).isEqualTo(false);
    }

    @Test
    public void testRotation_seascape_270_to_seascape_270() {
        when(mMockLeash.isValid()).thenReturn(false);
        // Rotate 270 -> 270
        TestableLooper.get(this).processAllMessages();
        mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_270, Surface.ROTATION_270);
        mTestableLooper.processAllMessages();
        mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_270, Surface.ROTATION_270,
                mMockWindowContainerTransaction);

        assertThat(mUpdateHandler.hasMessages(
                OneHandedDisplayAreaOrganizer.MSG_RESET_IMMEDIATE)).isEqualTo(false);
    }

    @Test
    public void testRotation_seascape_90_to_landscape_90() {
        when(mMockLeash.isValid()).thenReturn(false);
        // Rotate 270 -> 90
        TestableLooper.get(this).processAllMessages();
        mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_270, Surface.ROTATION_90);
        mTestableLooper.processAllMessages();
        mDisplayAreaOrganizer.onRotateDisplay(Surface.ROTATION_270, Surface.ROTATION_90,
                mMockWindowContainerTransaction);

        assertThat(mUpdateHandler.hasMessages(
                OneHandedDisplayAreaOrganizer.MSG_RESET_IMMEDIATE)).isEqualTo(false);
+1 −1
Original line number Diff line number Diff line
@@ -419,8 +419,8 @@ public final class WMShell extends SystemUI
        if (handleLoggingCommand(args, pw)) {
            return;
        }

        // Dump WMShell stuff here if no commands were handled
        mOneHandedOptional.ifPresent(oneHanded -> oneHanded.dump(pw));
    }

    @Override