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

Commit 83c300c0 authored by Mariia Sandrikova's avatar Mariia Sandrikova
Browse files

[1/n] Camera Compat: Force rotate activities

Camera compatibility treatment that handles orientation mismatch between camera buffers and an app window that can lead to camera issues like sideways or stretched viewfinder.

The treatment is enabled for internal displays that have ignoreOrientationRequest display setting enabled and when a flag config_windowManagerCameraCompatTreatmentEnabled is true. It's only applied to activities that have fixed orientation and are in fullscreen.

Main parts of the solution:
- Listen for the camera changes in DisplayRotationCompatPolicy to trigger orientation update when necessary
- Incorporate DisplayRotationCompatPolicy#getOrientation in orientation resolution logic in DisplayContent
- Don't trigger orientation updates too quickly to avoid orientation flickering during the camera flip or fold-unfold for foldable devices

Bug: 218352945
Test: atest WmTests:DisplayRotationCompatPolicyTests
Change-Id: Iaa3a3efa4e0fa89fbb58c7dbc59c125600972224
parent 4475e902
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -5344,6 +5344,12 @@
         TODO(b/255532890) Enable when ignoreOrientationRequest is set -->
    <bool name="config_letterboxIsEnabledForTranslucentActivities">false</bool>

    <!-- Whether camera compat treatment is enabled for issues caused by orientation mismatch
        between camera buffers and an app window. This includes force rotation of fixed
        orientation activities connected to the camera in fullscreen and showing a tooltip in
        split screen. -->
    <bool name="config_isWindowManagerCameraCompatTreatmentEnabled">false</bool>

    <!-- Whether a camera compat controller is enabled to allow the user to apply or revert
         treatment for stretched issues in camera viewfinder. -->
    <bool name="config_isCameraCompatControlForStretchedIssuesEnabled">false</bool>
+1 −0
Original line number Diff line number Diff line
@@ -4460,6 +4460,7 @@
  <java-symbol type="bool" name="config_letterboxIsEducationEnabled" />
  <java-symbol type="dimen" name="config_letterboxDefaultMinAspectRatioForUnresizableApps" />
  <java-symbol type="bool" name="config_letterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled" />
  <java-symbol type="bool" name="config_isWindowManagerCameraCompatTreatmentEnabled" />
  <java-symbol type="bool" name="config_isCameraCompatControlForStretchedIssuesEnabled" />

  <java-symbol type="bool" name="config_hideDisplayCutoutWithDisplayArea" />
+24 −0
Original line number Diff line number Diff line
@@ -295,6 +295,12 @@
      "group": "WM_DEBUG_IME",
      "at": "com\/android\/server\/wm\/DisplayContent.java"
    },
    "-1812743677": {
      "message": "Display id=%d is ignoring all orientation requests, camera is active and the top activity is eligible for force rotation, return %s,portrait activity: %b, is natural orientation portrait: %b.",
      "level": "VERBOSE",
      "group": "WM_DEBUG_ORIENTATION",
      "at": "com\/android\/server\/wm\/DisplayRotationCompatPolicy.java"
    },
    "-1810446914": {
      "message": "Trying to update display configuration for system\/invalid process.",
      "level": "WARN",
@@ -1321,6 +1327,12 @@
      "group": "WM_DEBUG_CONFIGURATION",
      "at": "com\/android\/server\/wm\/ActivityRecord.java"
    },
    "-799396645": {
      "message": "Display id=%d is notified that Camera %s is closed, updating rotation.",
      "level": "VERBOSE",
      "group": "WM_DEBUG_ORIENTATION",
      "at": "com\/android\/server\/wm\/DisplayRotationCompatPolicy.java"
    },
    "-799003045": {
      "message": "Set animatingExit: reason=remove\/replaceWindow win=%s",
      "level": "VERBOSE",
@@ -1543,6 +1555,12 @@
      "group": "WM_DEBUG_SCREEN_ON",
      "at": "com\/android\/server\/wm\/DisplayContent.java"
    },
    "-627759820": {
      "message": "Display id=%d is notified that Camera %s is open for package %s",
      "level": "VERBOSE",
      "group": "WM_DEBUG_ORIENTATION",
      "at": "com\/android\/server\/wm\/DisplayRotationCompatPolicy.java"
    },
    "-622997754": {
      "message": "postWindowRemoveCleanupLocked: %s",
      "level": "VERBOSE",
@@ -2101,6 +2119,12 @@
      "group": "WM_SHOW_TRANSACTIONS",
      "at": "com\/android\/server\/wm\/Session.java"
    },
    "-81260230": {
      "message": "Display id=%d is notified that Camera %s is closed, scheduling rotation update.",
      "level": "VERBOSE",
      "group": "WM_DEBUG_ORIENTATION",
      "at": "com\/android\/server\/wm\/DisplayRotationCompatPolicy.java"
    },
    "-81121442": {
      "message": "ImeContainer just became organized but it doesn't have a parent or the parent doesn't have a surface control. mSurfaceControl=%s imeParentSurfaceControl=%s",
      "level": "ERROR",
+11 −0
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ import android.view.Surface;
import android.view.WindowManagerGlobal;

import com.android.framework.protobuf.nano.MessageNano;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.FrameworkStatsLog;
import com.android.server.LocalServices;
@@ -389,6 +390,16 @@ public class CameraServiceProxy extends SystemService
            return CaptureRequest.SCALER_ROTATE_AND_CROP_NONE;
        }

        // When config_isWindowManagerCameraCompatTreatmentEnabled is true,
        // DisplayRotationCompatPolicy in WindowManager force rotates fullscreen activities with
        // fixed orientation to align them with the natural orientation of the device.
        if (ctx.getResources().getBoolean(
                R.bool.config_isWindowManagerCameraCompatTreatmentEnabled)) {
            Slog.v(TAG, "Disable Rotate and Crop to avoid conflicts with"
                    + " WM force rotation treatment.");
            return CaptureRequest.SCALER_ROTATE_AND_CROP_NONE;
        }

        // External cameras do not need crop-rotate-scale.
        if (lensFacing != CameraMetadata.LENS_FACING_FRONT
                && lensFacing != CameraMetadata.LENS_FACING_BACK) {
+17 −0
Original line number Diff line number Diff line
@@ -431,6 +431,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
    private final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
    private final DisplayPolicy mDisplayPolicy;
    private final DisplayRotation mDisplayRotation;
    @Nullable private final DisplayRotationCompatPolicy mDisplayRotationCompatPolicy;
    DisplayFrames mDisplayFrames;

    private final RemoteCallbackList<ISystemGestureExclusionListener>
@@ -1158,6 +1159,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        onDisplayChanged(this);
        updateDisplayAreaOrganizers();

        mDisplayRotationCompatPolicy =
                DisplayRotationCompatPolicy.isTreatmentEnabled(mWmService.mContext)
                        ? new DisplayRotationCompatPolicy(this) : null;

        mInputMonitor = new InputMonitor(mWmService, this);
        mInsetsPolicy = new InsetsPolicy(mInsetsStateController, this);
        mMinSizeOfResizeableTaskDp = getMinimalTaskSizeDp();
@@ -2704,6 +2709,14 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
            }
        }

        if (mDisplayRotationCompatPolicy != null) {
            int compatOrientation = mDisplayRotationCompatPolicy.getOrientation();
            if (compatOrientation != SCREEN_ORIENTATION_UNSPECIFIED) {
                mLastOrientationSource = null;
                return compatOrientation;
            }
        }

        final int orientation = super.getOrientation();

        if (!handlesOrientationChangeFromDescendant(orientation)) {
@@ -3260,6 +3273,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        // on the next traversal if it's removed from RootWindowContainer child list.
        getPendingTransaction().apply();
        mWmService.mWindowPlacerLocked.requestTraversal();

        if (mDisplayRotationCompatPolicy != null) {
            mDisplayRotationCompatPolicy.dispose();
        }
    }

    /** Returns true if a removal action is still being deferred. */
Loading