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

Commit 7c6271b7 authored by Jiaming Liu's avatar Jiaming Liu
Browse files

Use rotation from WindowConfiguration to rotate FoldingFeature to avoid race condition

We used DisplayInfo.rotation to rotate the FoldingFeature while using WindowConfiguration to validate the rotated FoldingFeature. Based on logs in b/295277561 and b/297215998, the rotations in WindowConfiguration and DisplayInfo were out of sync and caused validation failure and app crash. Using the
rotation from WindowConfiguration for feature rotation should prevent this issue.

Bug: 295277561
Bug: 297215998
Bug: 297153447
Test: atest CtsWindowManagerJetpackTestCases
Change-Id: I5f2322b73616e7b2746c4c0081d9e051bb0e4d56
parent a9a54263
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -319,13 +319,17 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
            return features;
        }

        // We will transform the feature bounds to the Activity window, so using the rotation
        // from the same source (WindowConfiguration) to make sure they are synchronized.
        final int rotation = windowConfiguration.getDisplayRotation();

        for (CommonFoldingFeature baseFeature : storedFeatures) {
            Integer state = convertToExtensionState(baseFeature.getState());
            if (state == null) {
                continue;
            }
            Rect featureRect = baseFeature.getRect();
            rotateRectToDisplayRotation(displayId, featureRect);
            rotateRectToDisplayRotation(displayId, rotation, featureRect);
            transformToWindowSpaceRect(windowConfiguration, featureRect);

            if (isZero(featureRect)) {
+3 −1
Original line number Diff line number Diff line
@@ -120,10 +120,12 @@ class SampleSidecarImpl extends StubSidecar {
        }

        List<SidecarDisplayFeature> features = new ArrayList<>();
        final int rotation = activity.getResources().getConfiguration().windowConfiguration
                .getDisplayRotation();
        for (CommonFoldingFeature baseFeature : mStoredFeatures) {
            SidecarDisplayFeature feature = new SidecarDisplayFeature();
            Rect featureRect = baseFeature.getRect();
            rotateRectToDisplayRotation(displayId, featureRect);
            rotateRectToDisplayRotation(displayId, rotation, featureRect);
            transformToWindowSpaceRect(activity, featureRect);
            feature.setRect(featureRect);
            feature.setType(baseFeature.getType());
+3 −34
Original line number Diff line number Diff line
@@ -16,8 +16,6 @@

package androidx.window.util;

import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_180;
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;

@@ -25,8 +23,8 @@ import android.app.WindowConfiguration;
import android.content.Context;
import android.graphics.Rect;
import android.hardware.display.DisplayManagerGlobal;
import android.util.RotationUtils;
import android.view.DisplayInfo;
import android.view.Surface;
import android.view.WindowManager;

import androidx.annotation.NonNull;
@@ -45,10 +43,9 @@ public final class ExtensionHelper {
     * Rotates the input rectangle specified in default display orientation to the current display
     * rotation.
     */
    public static void rotateRectToDisplayRotation(int displayId, Rect inOutRect) {
    public static void rotateRectToDisplayRotation(int displayId, int rotation, Rect inOutRect) {
        DisplayManagerGlobal dmGlobal = DisplayManagerGlobal.getInstance();
        DisplayInfo displayInfo = dmGlobal.getDisplayInfo(displayId);
        int rotation = displayInfo.rotation;

        boolean isSideRotation = rotation == ROTATION_90 || rotation == ROTATION_270;
        int displayWidth = isSideRotation ? displayInfo.logicalHeight : displayInfo.logicalWidth;
@@ -56,35 +53,7 @@ public final class ExtensionHelper {

        inOutRect.intersect(0, 0, displayWidth, displayHeight);

        rotateBounds(inOutRect, displayWidth, displayHeight, rotation);
    }

    /**
     * Rotates the input rectangle within parent bounds for a given delta.
     */
    private static void rotateBounds(Rect inOutRect, int parentWidth, int parentHeight,
            @Surface.Rotation int delta) {
        int origLeft = inOutRect.left;
        switch (delta) {
            case ROTATION_0:
                return;
            case ROTATION_90:
                inOutRect.left = inOutRect.top;
                inOutRect.top = parentWidth - inOutRect.right;
                inOutRect.right = inOutRect.bottom;
                inOutRect.bottom = parentWidth - origLeft;
                return;
            case ROTATION_180:
                inOutRect.left = parentWidth - inOutRect.right;
                inOutRect.right = parentWidth - origLeft;
                return;
            case ROTATION_270:
                inOutRect.left = parentHeight - inOutRect.bottom;
                inOutRect.bottom = inOutRect.right;
                inOutRect.right = parentHeight - inOutRect.top;
                inOutRect.top = origLeft;
                return;
        }
        RotationUtils.rotateBounds(inOutRect, displayWidth, displayHeight, rotation);
    }

    /** Transforms rectangle from absolute coordinate space to the window coordinate space. */