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

Commit e312fad8 authored by mincheli's avatar mincheli
Browse files

Updates the rotation and dimensions even mirror view is not inflated yet

Root cause: When the mirror view is not inflated yet, window
magnification will not update its cached dimension values and
rotation even there is a configuration settings changed.
Solution: Not to early return if the mirror view is not inflated
when onConfigurationChanged

Bug: 167973318
Test: atest WindowMagnificationControllerTest
Change-Id: I87290d16f3a10e7b88e8960391b89188443dacc8
parent e9897deb
Loading
Loading
Loading
Loading
+16 −10
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ import android.view.View;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
import com.android.systemui.R;
import com.android.systemui.shared.system.WindowManagerWrapper;
@@ -65,7 +66,8 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
    private final Point mDisplaySize = new Point();
    private final int mDisplayId;
    @Surface.Rotation
    private int mRotation;
    @VisibleForTesting
    int mRotation;
    private final Rect mMagnificationFrame = new Rect();
    private final SurfaceControl.Transaction mTransaction;

@@ -203,13 +205,12 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold
     * @param configDiff a bit mask of the differences between the configurations
     */
    void onConfigurationChanged(int configDiff) {
        if (!isWindowVisible()) {
            return;
        }
        if ((configDiff & ActivityInfo.CONFIG_DENSITY) != 0) {
            updateDimensions();
            if (isWindowVisible()) {
                mWm.removeView(mMirrorView);
                createMirrorWindow();
            }
        } else if ((configDiff & ActivityInfo.CONFIG_ORIENTATION) != 0) {
            onRotate();
        }
@@ -217,16 +218,20 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold

    /** Handles MirrorWindow position when the device rotation changed. */
    private void onRotate() {
        Display display = mContext.getDisplay();
        final Display display = mContext.getDisplay();
        final int oldRotation = mRotation;
        display.getRealSize(mDisplaySize);
        setMagnificationFrameBoundary();
        mRotation = display.getRotation();

        if (!isWindowVisible()) {
            return;
        }
        // Keep MirrorWindow position on the screen unchanged when device rotates 90°
        // clockwise or anti-clockwise.
        final int rotationDegree = getDegreeFromRotation(display.getRotation(), mRotation);
        final int rotationDegree = getDegreeFromRotation(mRotation, oldRotation);
        final Matrix matrix = new Matrix();
        matrix.setRotate(rotationDegree);
        mRotation = display.getRotation();
        if (rotationDegree == 90) {
            matrix.postTranslate(mDisplaySize.x, 0);
        } else if (rotationDegree == 270) {
@@ -555,6 +560,7 @@ class WindowMagnificationController implements View.OnTouchListener, SurfaceHold

    /**
     * Gets the scale.
     *
     * @return {@link Float#NaN} if the window is invisible.
     */
    float getScale() {
+79 −2
Original line number Diff line number Diff line
@@ -29,11 +29,14 @@ import static org.mockito.Mockito.when;
import android.app.Instrumentation;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Resources;
import android.os.Handler;
import android.testing.AndroidTestingRunner;
import android.view.Display;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.View;
import android.view.WindowManager;

import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
@@ -63,7 +66,9 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
    WindowMagnifierCallback mWindowMagnifierCallback;
    @Mock
    SurfaceControl.Transaction mTransaction;
    private Context mContext;
    @Mock
    private WindowManager mWindowManager;
    private Resources mResources;
    private WindowMagnificationController mWindowMagnificationController;
    private Instrumentation mInstrumentation;

@@ -72,6 +77,17 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
        MockitoAnnotations.initMocks(this);
        mContext = Mockito.spy(getContext());
        mInstrumentation = InstrumentationRegistry.getInstrumentation();
        WindowManager wm = mContext.getSystemService(WindowManager.class);
        doAnswer(invocation ->
                wm.getMaximumWindowMetrics()
        ).when(mWindowManager).getMaximumWindowMetrics();
        mContext.addMockSystemService(Context.WINDOW_SERVICE, mWindowManager);
        doAnswer(invocation -> {
            View view = invocation.getArgument(0);
            WindowManager.LayoutParams lp = invocation.getArgument(1);
            view.setLayoutParams(lp);
            return null;
        }).when(mWindowManager).addView(any(View.class), any(WindowManager.LayoutParams.class));
        doAnswer(invocation -> {
            FrameCallback callback = invocation.getArgument(0);
            callback.doFrame(0);
@@ -81,6 +97,8 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
        when(mTransaction.remove(any())).thenReturn(mTransaction);
        when(mTransaction.setGeometry(any(), any(), any(),
                anyInt())).thenReturn(mTransaction);
        mResources = Mockito.spy(mContext.getResources());
        when(mContext.getResources()).thenReturn(mResources);
        mWindowMagnificationController = new WindowMagnificationController(mContext,
                mHandler, mSfVsyncFrameProvider,
                mMirrorWindowControl, mTransaction, mWindowMagnifierCallback);
@@ -150,4 +168,63 @@ public class WindowMagnificationControllerTest extends SysuiTestCase {
            mWindowMagnificationController.onConfigurationChanged(ActivityInfo.CONFIG_ORIENTATION);
        });
    }

    @Test
    public void onOrientationChanged_enabled_updateDisplayRotationAndLayout() {
        final Display display = Mockito.spy(mContext.getDisplay());
        when(display.getRotation()).thenReturn(Surface.ROTATION_90);
        when(mContext.getDisplay()).thenReturn(display);
        mInstrumentation.runOnMainSync(() -> {
            mWindowMagnificationController.enableWindowMagnification(Float.NaN, Float.NaN,
                    Float.NaN);
            Mockito.reset(mWindowManager);
        });

        mInstrumentation.runOnMainSync(() -> {
            mWindowMagnificationController.onConfigurationChanged(ActivityInfo.CONFIG_ORIENTATION);
        });

        assertEquals(Surface.ROTATION_90, mWindowMagnificationController.mRotation);
        verify(mWindowManager).updateViewLayout(any(), any());
    }

    @Test
    public void onOrientationChanged_disabled_updateDisplayRotation() {
        final Display display = Mockito.spy(mContext.getDisplay());
        when(display.getRotation()).thenReturn(Surface.ROTATION_90);
        when(mContext.getDisplay()).thenReturn(display);

        mInstrumentation.runOnMainSync(() -> {
            mWindowMagnificationController.onConfigurationChanged(ActivityInfo.CONFIG_ORIENTATION);
        });

        assertEquals(Surface.ROTATION_90, mWindowMagnificationController.mRotation);
    }


    @Test
    public void onDensityChanged_enabled_updateDimensionsAndLayout() {
        mInstrumentation.runOnMainSync(() -> {
            mWindowMagnificationController.enableWindowMagnification(Float.NaN, Float.NaN,
                    Float.NaN);
            Mockito.reset(mWindowManager);
        });

        mInstrumentation.runOnMainSync(() -> {
            mWindowMagnificationController.onConfigurationChanged(ActivityInfo.CONFIG_DENSITY);
        });

        verify(mResources, atLeastOnce()).getDimensionPixelSize(anyInt());
        verify(mWindowManager).removeView(any());
        verify(mWindowManager).addView(any(), any());
    }

    @Test
    public void onDensityChanged_disabled_updateDimensions() {
        mInstrumentation.runOnMainSync(() -> {
            mWindowMagnificationController.onConfigurationChanged(ActivityInfo.CONFIG_DENSITY);
        });

        verify(mResources, atLeastOnce()).getDimensionPixelSize(anyInt());
    }
}