Per-app compat treatment for overrideToPortrait.

Camera framework consumers will have the option to opt in or out to
the rotate and crop fix for foldables via a manifest property.
This will allow apps which correctly handle the landscape sensor
to obtain the full FOV of the camera.

Test: Tested opt-out in Camera2Basic sample, opt-in in CTSVerifier.
Bug: 263965273
Change-Id: I190963c4f8dfba29dab7570397c33f44cab702e3
Merged-in: I190963c4f8dfba29dab7570397c33f44cab702e3
This commit is contained in:
Austin Borger
2022-12-29 13:25:52 -08:00
parent c3f30502f8
commit eb361cec47
3 changed files with 34 additions and 20 deletions

View File

@@ -1139,7 +1139,6 @@ package android.hardware.camera2 {
public final class CameraManager {
method public String[] getCameraIdListNoLazy() throws android.hardware.camera2.CameraAccessException;
method @RequiresPermission(allOf={android.Manifest.permission.SYSTEM_CAMERA, android.Manifest.permission.CAMERA}) public void openCamera(@NonNull String, int, @NonNull java.util.concurrent.Executor, @NonNull android.hardware.camera2.CameraDevice.StateCallback) throws android.hardware.camera2.CameraAccessException;
field public static final long OVERRIDE_FRONT_CAMERA_APP_COMPAT = 250678880L; // 0xef10e60L
}
public abstract static class CameraManager.AvailabilityCallback {

View File

@@ -29,7 +29,6 @@ import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.app.ActivityThread;
import android.app.AppOpsManager;
import android.app.compat.CompatChanges;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.graphics.ImageFormat;
@@ -47,7 +46,6 @@ import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RSIllegalArgumentException;
@@ -284,14 +282,6 @@ public class Camera {
*/
public native static int getNumberOfCameras();
private static final boolean sLandscapeToPortrait =
SystemProperties.getBoolean(CameraManager.LANDSCAPE_TO_PORTRAIT_PROP, false);
private static boolean shouldOverrideToPortrait() {
return CompatChanges.isChangeEnabled(CameraManager.OVERRIDE_FRONT_CAMERA_APP_COMPAT)
&& sLandscapeToPortrait;
}
/**
* Returns the information about a particular camera.
* If {@link #getNumberOfCameras()} returns N, the valid id is 0 to N-1.
@@ -301,7 +291,8 @@ public class Camera {
* low-level failure).
*/
public static void getCameraInfo(int cameraId, CameraInfo cameraInfo) {
boolean overrideToPortrait = shouldOverrideToPortrait();
boolean overrideToPortrait = CameraManager.shouldOverrideToPortrait(
ActivityThread.currentApplication().getApplicationContext());
_getCameraInfo(cameraId, overrideToPortrait, cameraInfo);
IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
@@ -498,7 +489,8 @@ public class Camera {
mEventHandler = null;
}
boolean overrideToPortrait = shouldOverrideToPortrait();
boolean overrideToPortrait = CameraManager.shouldOverrideToPortrait(
ActivityThread.currentApplication().getApplicationContext());
return native_setup(new WeakReference<Camera>(this), cameraId,
ActivityThread.currentOpPackageName(), overrideToPortrait);
}

View File

@@ -115,8 +115,14 @@ public final class CameraManager {
@ChangeId
@Overridable
@EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.BASE)
@TestApi
public static final long OVERRIDE_FRONT_CAMERA_APP_COMPAT = 250678880L;
public static final long OVERRIDE_CAMERA_LANDSCAPE_TO_PORTRAIT = 250678880L;
/**
* Package-level opt in/out for the above.
* @hide
*/
public static final String PROPERTY_COMPAT_OVERRIDE_LANDSCAPE_TO_PORTRAIT =
"android.camera.PROPERTY_COMPAT_OVERRIDE_LANDSCAPE_TO_PORTRAIT";
/**
* System property for allowing the above
@@ -602,7 +608,7 @@ public final class CameraManager {
try {
Size displaySize = getDisplaySize();
boolean overrideToPortrait = shouldOverrideToPortrait();
boolean overrideToPortrait = shouldOverrideToPortrait(mContext);
CameraMetadataNative info = cameraService.getCameraCharacteristics(cameraId,
mContext.getApplicationInfo().targetSdkVersion, overrideToPortrait);
try {
@@ -722,7 +728,7 @@ public final class CameraManager {
"Camera service is currently unavailable");
}
boolean overrideToPortrait = shouldOverrideToPortrait();
boolean overrideToPortrait = shouldOverrideToPortrait(mContext);
cameraUser = cameraService.connectDevice(callbacks, cameraId,
mContext.getOpPackageName(), mContext.getAttributionTag(), uid,
oomScoreOffset, mContext.getApplicationInfo().targetSdkVersion,
@@ -1154,9 +1160,26 @@ public final class CameraManager {
return CameraManagerGlobal.get().getTorchStrengthLevel(cameraId);
}
private static boolean shouldOverrideToPortrait() {
return CompatChanges.isChangeEnabled(OVERRIDE_FRONT_CAMERA_APP_COMPAT)
&& CameraManagerGlobal.sLandscapeToPortrait;
/**
* @hide
*/
public static boolean shouldOverrideToPortrait(@Nullable Context context) {
if (!CameraManagerGlobal.sLandscapeToPortrait) {
return false;
}
if (context != null) {
PackageManager packageManager = context.getPackageManager();
try {
return packageManager.getProperty(context.getOpPackageName(),
PROPERTY_COMPAT_OVERRIDE_LANDSCAPE_TO_PORTRAIT).getBoolean();
} catch (PackageManager.NameNotFoundException e) {
// No such property
}
}
return CompatChanges.isChangeEnabled(OVERRIDE_CAMERA_LANDSCAPE_TO_PORTRAIT);
}
/**