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

Commit c2acd70c authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Check display rotation for rotateAndCrop." into main

parents d24ff84d f3b34910
Loading
Loading
Loading
Loading
+33 −2
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package android.app;

import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
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;

import android.annotation.IntDef;
@@ -87,9 +89,19 @@ public class CameraCompatTaskInfo implements Parcelable {
     * <p>This field is used by the WM and the camera framework, to coordinate camera compat mode
     * setup.
     */
    // TODO(b/414347702): Revisit data structure.
    @FreeformCameraCompatMode
    public int freeformCameraCompatMode;

    /**
     * Real display rotation, never affected by camera compat sandboxing.
     *
     * <p>This value is used by the Camera Framework to calculate rotate-and-crop rotation degrees.
     */
    // TODO(b/414347702): Revisit data structure.
    @Surface.Rotation
    public int displayRotation;

    private CameraCompatTaskInfo() {
        // Do nothing
    }
@@ -126,6 +138,7 @@ public class CameraCompatTaskInfo implements Parcelable {
     */
    void readFromParcel(Parcel source) {
        freeformCameraCompatMode = source.readInt();
        displayRotation = source.readInt();
    }

    /**
@@ -134,6 +147,7 @@ public class CameraCompatTaskInfo implements Parcelable {
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(freeformCameraCompatMode);
        dest.writeInt(displayRotation);
    }

    /**
@@ -144,7 +158,8 @@ public class CameraCompatTaskInfo implements Parcelable {
        if (that == null) {
            return false;
        }
        return freeformCameraCompatMode == that.freeformCameraCompatMode;
        return freeformCameraCompatMode == that.freeformCameraCompatMode
                && displayRotation == that.displayRotation;
    }

    /**
@@ -154,13 +169,15 @@ public class CameraCompatTaskInfo implements Parcelable {
        if (that == null) {
            return false;
        }
        return freeformCameraCompatMode == that.freeformCameraCompatMode;
        return freeformCameraCompatMode == that.freeformCameraCompatMode
                && displayRotation == that.displayRotation;
    }

    @Override
    public String toString() {
        return "CameraCompatTaskInfo { freeformCameraCompatMode="
                + freeformCameraCompatModeToString(freeformCameraCompatMode)
                + displayRotationToString(displayRotation)
                + "}";
    }

@@ -204,4 +221,18 @@ public class CameraCompatTaskInfo implements Parcelable {
                    "Unexpected camera compat mode: " + freeformCameraCompatMode);
        };
    }

    /** Human readable version of the freeform camera compat mode. */
    @NonNull
    public static String displayRotationToString(@Surface.Rotation int displayRotation) {
        return switch (displayRotation) {
            case ROTATION_UNDEFINED -> "undefined";
            case ROTATION_0 -> "0";
            case ROTATION_90 -> "90";
            case ROTATION_180 -> "180";
            case ROTATION_270 -> "270";
            default -> throw new AssertionError(
                    "Unexpected display rotation: " + displayRotation);
        };
    }
}
+40 −3
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@ import static android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_DEFAUL
import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_CAMERA;
import static android.content.Context.DEVICE_ID_DEFAULT;
import static android.content.Context.DEVICE_ID_INVALID;
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;

import android.annotation.CallbackExecutor;
import android.annotation.FlaggedApi;
@@ -79,6 +81,7 @@ import android.util.Log;
import android.util.Pair;
import android.util.Size;
import android.view.Display;
import android.view.Surface;
import android.window.DesktopModeFlags;

import com.android.internal.camera.flags.Flags;
@@ -211,6 +214,16 @@ public final class CameraManager {
    public static final int ROTATION_OVERRIDE_ROTATION_ONLY =
            ICameraService.ROTATION_OVERRIDE_ROTATION_ONLY;

    /**
     * Crops and rotates landscape camera feed to portrait counterclockwise, but doesn't change
     * sensor orientation.
     *
     * @hide
     */
    // TODO(b/414347702): Revisit data structure.
    static final int ROTATION_OVERRIDE_ROTATION_ONLY_REVERSE =
            ICameraService.ROTATION_OVERRIDE_ROTATION_ONLY_REVERSE;

    /**
     * Enable physical camera availability callbacks when the logical camera is unavailable
     *
@@ -1719,7 +1732,8 @@ public final class CameraManager {
                            && taskInfo.topActivity != null
                            && taskInfo.topActivity.getPackageName().equals(packageName)) {
                        // WindowManager has requested rotation override.
                        return getRotationOverrideForCompatFreeform(freeformCameraCompatMode);
                        return getRotationOverrideForCompatFreeform(freeformCameraCompatMode,
                                taskInfo.appCompatTaskInfo.cameraCompatTaskInfo.displayRotation);
                    }
                }
            }
@@ -1749,13 +1763,36 @@ public final class CameraManager {
    }

    private static int getRotationOverrideForCompatFreeform(
            @CameraCompatTaskInfo.FreeformCameraCompatMode int freeformCameraCompatMode) {
            @CameraCompatTaskInfo.FreeformCameraCompatMode int freeformCameraCompatMode,
            @Surface.Rotation int displayRotation) {
        // Only rotate-and-crop if the app and device orientations do not match.
        if (freeformCameraCompatMode
                == CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_PORTRAIT
                || freeformCameraCompatMode
                    == CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_LANDSCAPE) {
            // Rotate-and-crop compensates for changes in camera preview calculations (sandboxing).
            // Recommended calculation of camera preview is:
            // rotation = (sensorOrientationDegrees - deviceOrientationDegrees * sign + 360) % 360
            // (camera-facing - sign - is accounted for later).
            // If any of the parameters above are changed, rotate-and-crop should be applied to
            // equal the changed amount.
            // For example, with real display rotation 90 sandboxed to 0, rotate-and-crop by 270
            // degrees (-90) for back camera, and 90 for front camera.
            // Use `displayRotation` param, sent by WindowManager, as the display rotation in the
            // app process might be sandboxed.
            if (displayRotation == ROTATION_90 && com.android.window.flags.Flags
                    .enableCameraCompatCheckDeviceRotationBugfix()) {
                // back camera: 270 degrees, front camera: 90 degrees
                return ICameraService.ROTATION_OVERRIDE_ROTATION_ONLY_REVERSE;
            } else if (displayRotation == ROTATION_270) {
                // back camera: 90 degrees, front camera: 270 degrees
                return ICameraService.ROTATION_OVERRIDE_ROTATION_ONLY;
            } else {
                // TODO(b/390183440): differentiate between LANDSCAPE and REVERSE_LANDSCAPE
                //  requested orientation for landscape apps. 'displayRotation` is 0 or 180 (rare)
                //  in either case.
                return ICameraService.ROTATION_OVERRIDE_ROTATION_ONLY;
            }
        } else {
            return ICameraService.ROTATION_OVERRIDE_NONE;
        }
+10 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.wm;

import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;

import static com.android.server.wm.AppCompatConfiguration.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO;
@@ -25,6 +26,7 @@ import android.annotation.Nullable;
import android.app.CameraCompatTaskInfo;
import android.content.pm.ActivityInfo.ScreenOrientation;
import android.content.res.Configuration;
import android.view.Surface;
import android.widget.Toast;
import android.window.DesktopModeFlags;

@@ -271,6 +273,14 @@ class AppCompatCameraPolicy {
                : CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_NONE;
    }

    @Surface.Rotation
    static int getCameraDeviceRotation(@NonNull ActivityRecord activity) {
        final AppCompatCameraPolicy cameraPolicy = getAppCompatCameraPolicy(activity);
        return cameraPolicy != null && cameraPolicy.mCameraCompatFreeformPolicy != null
                ? cameraPolicy.mCameraCompatFreeformPolicy.getCameraDeviceRotation()
                : ROTATION_UNDEFINED;
    }

    /**
     * Whether we should apply the min aspect ratio per-app override only when an app is connected
     * to the camera.
+4 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.wm;

import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
@@ -235,6 +236,9 @@ final class AppCompatUtils {
        appCompatTaskInfo.setEligibleForUserAspectRatioButton(eligibleForAspectRatioButton);
        appCompatTaskInfo.cameraCompatTaskInfo.freeformCameraCompatMode =
                AppCompatCameraPolicy.getCameraCompatFreeformMode(top);
        appCompatTaskInfo.cameraCompatTaskInfo.displayRotation =
                Flags.enableCameraCompatCheckDeviceRotationBugfix()
                        ? AppCompatCameraPolicy.getCameraDeviceRotation(top) : ROTATION_UNDEFINED;
        appCompatTaskInfo.setHasMinAspectRatioOverride(top.mAppCompatController
                .getDesktopAspectRatioPolicy().hasMinAspectRatioOverride(task));
        appCompatTaskInfo.setOptOutEdgeToEdge(top.mOptOutEdgeToEdge);
+5 −0
Original line number Diff line number Diff line
@@ -93,6 +93,11 @@ final class CameraCompatFreeformPolicy implements CameraStateMonitor.CameraCompa
        mIsRunning = true;
    }

    int getCameraDeviceRotation() {
        // TODO(b/276432441): Check device orientation when running on an external display.
        return mDisplayContent.getRotation();
    }

    /** Releases camera callback listener. */
    void dispose() {
        mCameraStateMonitor.removeCameraStateListener(this);
Loading