Merge "CameraServiceProxy: Estimate rotate&crop override value" into sc-v2-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
fc47105390
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.server.camera;
|
package com.android.server.camera;
|
||||||
|
|
||||||
|
import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
|
||||||
import static android.os.Build.VERSION_CODES.M;
|
import static android.os.Build.VERSION_CODES.M;
|
||||||
|
|
||||||
import android.annotation.IntDef;
|
import android.annotation.IntDef;
|
||||||
@@ -39,7 +40,9 @@ import android.hardware.CameraSessionStats;
|
|||||||
import android.hardware.CameraStreamStats;
|
import android.hardware.CameraStreamStats;
|
||||||
import android.hardware.ICameraService;
|
import android.hardware.ICameraService;
|
||||||
import android.hardware.ICameraServiceProxy;
|
import android.hardware.ICameraServiceProxy;
|
||||||
|
import android.hardware.camera2.CameraCharacteristics;
|
||||||
import android.hardware.camera2.CameraMetadata;
|
import android.hardware.camera2.CameraMetadata;
|
||||||
|
import android.hardware.camera2.CaptureRequest;
|
||||||
import android.hardware.devicestate.DeviceStateManager;
|
import android.hardware.devicestate.DeviceStateManager;
|
||||||
import android.hardware.devicestate.DeviceStateManager.FoldStateListener;
|
import android.hardware.devicestate.DeviceStateManager.FoldStateListener;
|
||||||
import android.hardware.display.DisplayManager;
|
import android.hardware.display.DisplayManager;
|
||||||
@@ -346,13 +349,13 @@ public class CameraServiceProxy extends SystemService
|
|||||||
|
|
||||||
private final TaskStateHandler mTaskStackListener = new TaskStateHandler();
|
private final TaskStateHandler mTaskStackListener = new TaskStateHandler();
|
||||||
|
|
||||||
private final class TaskInfo {
|
public static final class TaskInfo {
|
||||||
private int frontTaskId;
|
public int frontTaskId;
|
||||||
private boolean isResizeable;
|
public boolean isResizeable;
|
||||||
private boolean isFixedOrientationLandscape;
|
public boolean isFixedOrientationLandscape;
|
||||||
private boolean isFixedOrientationPortrait;
|
public boolean isFixedOrientationPortrait;
|
||||||
private int displayId;
|
public int displayId;
|
||||||
private int userId;
|
public int userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class TaskStateHandler extends TaskStackListener {
|
private final class TaskStateHandler extends TaskStackListener {
|
||||||
@@ -367,7 +370,8 @@ public class CameraServiceProxy extends SystemService
|
|||||||
synchronized (mMapLock) {
|
synchronized (mMapLock) {
|
||||||
TaskInfo info = new TaskInfo();
|
TaskInfo info = new TaskInfo();
|
||||||
info.frontTaskId = taskInfo.taskId;
|
info.frontTaskId = taskInfo.taskId;
|
||||||
info.isResizeable = taskInfo.isResizeable;
|
info.isResizeable =
|
||||||
|
(taskInfo.topActivityInfo.resizeMode != RESIZE_MODE_UNRESIZEABLE);
|
||||||
info.displayId = taskInfo.displayId;
|
info.displayId = taskInfo.displayId;
|
||||||
info.userId = taskInfo.userId;
|
info.userId = taskInfo.userId;
|
||||||
info.isFixedOrientationLandscape = ActivityInfo.isFixedOrientationLandscape(
|
info.isFixedOrientationLandscape = ActivityInfo.isFixedOrientationLandscape(
|
||||||
@@ -427,97 +431,108 @@ public class CameraServiceProxy extends SystemService
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private final ICameraServiceProxy.Stub mCameraServiceProxy = new ICameraServiceProxy.Stub() {
|
private static boolean isMOrBelow(Context ctx, String packageName) {
|
||||||
private boolean isMOrBelow(Context ctx, String packageName) {
|
try {
|
||||||
try {
|
return ctx.getPackageManager().getPackageInfo(
|
||||||
return ctx.getPackageManager().getPackageInfo(
|
packageName, 0).applicationInfo.targetSdkVersion <= M;
|
||||||
packageName, 0).applicationInfo.targetSdkVersion <= M;
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
Slog.e(TAG,"Package name not found!");
|
||||||
Slog.e(TAG,"Package name not found!");
|
}
|
||||||
}
|
return false;
|
||||||
return false;
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Estimate the app crop-rotate-scale compensation value.
|
||||||
|
*/
|
||||||
|
public static int getCropRotateScale(@NonNull Context ctx, @NonNull String packageName,
|
||||||
|
@Nullable TaskInfo taskInfo, int displayRotation, int lensFacing,
|
||||||
|
boolean ignoreResizableAndSdkCheck) {
|
||||||
|
if (taskInfo == null) {
|
||||||
|
return CaptureRequest.SCALER_ROTATE_AND_CROP_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// External cameras do not need crop-rotate-scale.
|
||||||
* Gets whether crop-rotate-scale is needed.
|
if (lensFacing != CameraMetadata.LENS_FACING_FRONT
|
||||||
*/
|
&& lensFacing != CameraMetadata.LENS_FACING_BACK) {
|
||||||
private boolean getNeedCropRotateScale(@NonNull Context ctx, @NonNull String packageName,
|
Log.v(TAG, "lensFacing=" + lensFacing + ". Crop-rotate-scale is disabled.");
|
||||||
@Nullable TaskInfo taskInfo, int sensorOrientation, int lensFacing,
|
return CaptureRequest.SCALER_ROTATE_AND_CROP_NONE;
|
||||||
boolean ignoreResizableAndSdkCheck) {
|
}
|
||||||
if (taskInfo == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// External cameras do not need crop-rotate-scale.
|
// In case the activity behavior is not explicitly overridden, enable the
|
||||||
if (lensFacing != CameraMetadata.LENS_FACING_FRONT
|
// crop-rotate-scale workaround if the app targets M (or below) or is not
|
||||||
&& lensFacing != CameraMetadata.LENS_FACING_BACK) {
|
// resizeable.
|
||||||
Log.v(TAG, "lensFacing=" + lensFacing + ". Crop-rotate-scale is disabled.");
|
if (!ignoreResizableAndSdkCheck && !isMOrBelow(ctx, packageName) &&
|
||||||
return false;
|
taskInfo.isResizeable) {
|
||||||
}
|
|
||||||
|
|
||||||
// In case the activity behavior is not explicitly overridden, enable the
|
|
||||||
// crop-rotate-scale workaround if the app targets M (or below) or is not
|
|
||||||
// resizeable.
|
|
||||||
if (!ignoreResizableAndSdkCheck && !isMOrBelow(ctx, packageName) &&
|
|
||||||
taskInfo.isResizeable) {
|
|
||||||
Slog.v(TAG,
|
|
||||||
"The activity is N or above and claims to support resizeable-activity. "
|
|
||||||
+ "Crop-rotate-scale is disabled.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayManager displayManager = ctx.getSystemService(DisplayManager.class);
|
|
||||||
int rotationDegree = 0;
|
|
||||||
if (displayManager != null) {
|
|
||||||
Display display = displayManager.getDisplay(taskInfo.displayId);
|
|
||||||
if (display == null) {
|
|
||||||
Slog.e(TAG, "Invalid display id: " + taskInfo.displayId);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int rotation = display.getRotation();
|
|
||||||
switch (rotation) {
|
|
||||||
case Surface.ROTATION_0:
|
|
||||||
rotationDegree = 0;
|
|
||||||
break;
|
|
||||||
case Surface.ROTATION_90:
|
|
||||||
rotationDegree = 90;
|
|
||||||
break;
|
|
||||||
case Surface.ROTATION_180:
|
|
||||||
rotationDegree = 180;
|
|
||||||
break;
|
|
||||||
case Surface.ROTATION_270:
|
|
||||||
rotationDegree = 270;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Slog.e(TAG, "Failed to query display manager!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Here we only need to know whether the camera is landscape or portrait. Therefore we
|
|
||||||
// don't need to consider whether it is a front or back camera. The formula works for
|
|
||||||
// both.
|
|
||||||
boolean landscapeCamera = ((rotationDegree + sensorOrientation) % 180 == 0);
|
|
||||||
Slog.v(TAG,
|
Slog.v(TAG,
|
||||||
"Display.getRotation()=" + rotationDegree
|
"The activity is N or above and claims to support resizeable-activity. "
|
||||||
+ " CameraCharacteristics.SENSOR_ORIENTATION=" + sensorOrientation
|
+ "Crop-rotate-scale is disabled.");
|
||||||
+ " isFixedOrientationPortrait=" + taskInfo.isFixedOrientationPortrait
|
return CaptureRequest.SCALER_ROTATE_AND_CROP_NONE;
|
||||||
+ " isFixedOrientationLandscape=" +
|
|
||||||
taskInfo.isFixedOrientationLandscape);
|
|
||||||
// We need to do crop-rotate-scale when camera is landscape and activity is portrait or
|
|
||||||
// vice versa.
|
|
||||||
return (taskInfo.isFixedOrientationPortrait && landscapeCamera)
|
|
||||||
|| (taskInfo.isFixedOrientationLandscape && !landscapeCamera);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!taskInfo.isFixedOrientationPortrait && !taskInfo.isFixedOrientationLandscape) {
|
||||||
|
Log.v(TAG, "Non-fixed orientation activity. Crop-rotate-scale is disabled.");
|
||||||
|
return CaptureRequest.SCALER_ROTATE_AND_CROP_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rotationDegree;
|
||||||
|
switch (displayRotation) {
|
||||||
|
case Surface.ROTATION_0:
|
||||||
|
rotationDegree = 0;
|
||||||
|
break;
|
||||||
|
case Surface.ROTATION_90:
|
||||||
|
rotationDegree = 90;
|
||||||
|
break;
|
||||||
|
case Surface.ROTATION_180:
|
||||||
|
rotationDegree = 180;
|
||||||
|
break;
|
||||||
|
case Surface.ROTATION_270:
|
||||||
|
rotationDegree = 270;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Log.e(TAG, "Unsupported display rotation: " + displayRotation);
|
||||||
|
return CaptureRequest.SCALER_ROTATE_AND_CROP_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Slog.v(TAG,
|
||||||
|
"Display.getRotation()=" + rotationDegree
|
||||||
|
+ " isFixedOrientationPortrait=" + taskInfo.isFixedOrientationPortrait
|
||||||
|
+ " isFixedOrientationLandscape=" +
|
||||||
|
taskInfo.isFixedOrientationLandscape);
|
||||||
|
// We are trying to estimate the necessary rotation compensation for clients that
|
||||||
|
// don't handle various display orientations.
|
||||||
|
// The logic that is missing on client side is similar to the reference code
|
||||||
|
// in {@link android.hardware.Camera#setDisplayOrientation} where "info.orientation"
|
||||||
|
// is already applied in "CameraUtils::getRotationTransform".
|
||||||
|
// Care should be taken to reverse the rotation direction depending on the camera
|
||||||
|
// lens facing.
|
||||||
|
if (rotationDegree == 0) {
|
||||||
|
return CaptureRequest.SCALER_ROTATE_AND_CROP_NONE;
|
||||||
|
}
|
||||||
|
if (lensFacing == CameraCharacteristics.LENS_FACING_FRONT) {
|
||||||
|
// Switch direction for front facing cameras
|
||||||
|
rotationDegree = 360 - rotationDegree;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (rotationDegree) {
|
||||||
|
case 90:
|
||||||
|
return CaptureRequest.SCALER_ROTATE_AND_CROP_90;
|
||||||
|
case 270:
|
||||||
|
return CaptureRequest.SCALER_ROTATE_AND_CROP_270;
|
||||||
|
case 180:
|
||||||
|
return CaptureRequest.SCALER_ROTATE_AND_CROP_180;
|
||||||
|
case 0:
|
||||||
|
default:
|
||||||
|
return CaptureRequest.SCALER_ROTATE_AND_CROP_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final ICameraServiceProxy.Stub mCameraServiceProxy = new ICameraServiceProxy.Stub() {
|
||||||
@Override
|
@Override
|
||||||
public boolean isRotateAndCropOverrideNeeded(String packageName, int sensorOrientation,
|
public int getRotateAndCropOverride(String packageName, int lensFacing) {
|
||||||
int lensFacing) {
|
|
||||||
if (Binder.getCallingUid() != Process.CAMERASERVER_UID) {
|
if (Binder.getCallingUid() != Process.CAMERASERVER_UID) {
|
||||||
Slog.e(TAG, "Calling UID: " + Binder.getCallingUid() + " doesn't match expected " +
|
Slog.e(TAG, "Calling UID: " + Binder.getCallingUid() + " doesn't match expected " +
|
||||||
" camera service UID!");
|
" camera service UID!");
|
||||||
return false;
|
return CaptureRequest.SCALER_ROTATE_AND_CROP_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Modify the sensor orientation in camera characteristics along with any 3A
|
// TODO: Modify the sensor orientation in camera characteristics along with any 3A
|
||||||
@@ -531,10 +546,10 @@ public class CameraServiceProxy extends SystemService
|
|||||||
if (CompatChanges.isChangeEnabled(OVERRIDE_CAMERA_ROTATE_AND_CROP, packageName,
|
if (CompatChanges.isChangeEnabled(OVERRIDE_CAMERA_ROTATE_AND_CROP, packageName,
|
||||||
UserHandle.getUserHandleForUid(taskInfo.userId))) {
|
UserHandle.getUserHandleForUid(taskInfo.userId))) {
|
||||||
Slog.v(TAG, "OVERRIDE_CAMERA_ROTATE_AND_CROP enabled!");
|
Slog.v(TAG, "OVERRIDE_CAMERA_ROTATE_AND_CROP enabled!");
|
||||||
return true;
|
return CaptureRequest.SCALER_ROTATE_AND_CROP_NONE;
|
||||||
} else {
|
} else {
|
||||||
Slog.v(TAG, "OVERRIDE_CAMERA_ROTATE_AND_CROP disabled!");
|
Slog.v(TAG, "OVERRIDE_CAMERA_ROTATE_AND_CROP disabled!");
|
||||||
return false;
|
return CaptureRequest.SCALER_ROTATE_AND_CROP_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
boolean ignoreResizableAndSdkCheck = false;
|
boolean ignoreResizableAndSdkCheck = false;
|
||||||
@@ -544,7 +559,23 @@ public class CameraServiceProxy extends SystemService
|
|||||||
Slog.v(TAG, "OVERRIDE_CAMERA_RESIZABLE_AND_SDK_CHECK enabled!");
|
Slog.v(TAG, "OVERRIDE_CAMERA_RESIZABLE_AND_SDK_CHECK enabled!");
|
||||||
ignoreResizableAndSdkCheck = true;
|
ignoreResizableAndSdkCheck = true;
|
||||||
}
|
}
|
||||||
return getNeedCropRotateScale(mContext, packageName, taskInfo, sensorOrientation,
|
|
||||||
|
DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
|
||||||
|
int displayRotation;
|
||||||
|
if (displayManager != null) {
|
||||||
|
Display display = displayManager.getDisplay(taskInfo.displayId);
|
||||||
|
if (display == null) {
|
||||||
|
Slog.e(TAG, "Invalid display id: " + taskInfo.displayId);
|
||||||
|
return CaptureRequest.SCALER_ROTATE_AND_CROP_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
displayRotation = display.getRotation();
|
||||||
|
} else {
|
||||||
|
Slog.e(TAG, "Failed to query display manager!");
|
||||||
|
return CaptureRequest.SCALER_ROTATE_AND_CROP_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return getCropRotateScale(mContext, packageName, taskInfo, displayRotation,
|
||||||
lensFacing, ignoreResizableAndSdkCheck);
|
lensFacing, ignoreResizableAndSdkCheck);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.server.camera;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.JUnit4;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import androidx.test.InstrumentationRegistry;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.hardware.camera2.CameraCharacteristics;
|
||||||
|
import android.hardware.camera2.CameraMetadata;
|
||||||
|
import android.view.Display;
|
||||||
|
import android.view.Surface;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
@RunWith(JUnit4.class)
|
||||||
|
public class CameraServiceProxyTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetCropRotateScale() {
|
||||||
|
|
||||||
|
Context ctx = InstrumentationRegistry.getContext();
|
||||||
|
|
||||||
|
// Check resizeability and SDK
|
||||||
|
CameraServiceProxy.TaskInfo taskInfo = new CameraServiceProxy.TaskInfo();
|
||||||
|
taskInfo.isResizeable = true;
|
||||||
|
taskInfo.displayId = Display.DEFAULT_DISPLAY;
|
||||||
|
taskInfo.isFixedOrientationLandscape = false;
|
||||||
|
taskInfo.isFixedOrientationPortrait = true;
|
||||||
|
// Resizeable apps should be ignored
|
||||||
|
assertThat(CameraServiceProxy.getCropRotateScale(ctx, ctx.getPackageName(), taskInfo,
|
||||||
|
Surface.ROTATION_90 , CameraCharacteristics.LENS_FACING_BACK,
|
||||||
|
/*ignoreResizableAndSdkCheck*/false)).isEqualTo(
|
||||||
|
CameraMetadata.SCALER_ROTATE_AND_CROP_NONE);
|
||||||
|
// Resizeable apps will be considered in case the ignore flag is set
|
||||||
|
assertThat(CameraServiceProxy.getCropRotateScale(ctx, ctx.getPackageName(), taskInfo,
|
||||||
|
Surface.ROTATION_90, CameraCharacteristics.LENS_FACING_BACK,
|
||||||
|
/*ignoreResizableAndSdkCheck*/true)).isEqualTo(
|
||||||
|
CameraMetadata.SCALER_ROTATE_AND_CROP_90);
|
||||||
|
taskInfo.isResizeable = false;
|
||||||
|
// Non-resizeable apps should be considered
|
||||||
|
assertThat(CameraServiceProxy.getCropRotateScale(ctx, ctx.getPackageName(), taskInfo,
|
||||||
|
Surface.ROTATION_90, CameraCharacteristics.LENS_FACING_BACK,
|
||||||
|
/*ignoreResizableAndSdkCheck*/false)).isEqualTo(
|
||||||
|
CameraMetadata.SCALER_ROTATE_AND_CROP_90);
|
||||||
|
// The ignore flag for non-resizeable should have no effect
|
||||||
|
assertThat(CameraServiceProxy.getCropRotateScale(ctx, ctx.getPackageName(), taskInfo,
|
||||||
|
Surface.ROTATION_90, CameraCharacteristics.LENS_FACING_BACK,
|
||||||
|
/*ignoreResizableAndSdkCheck*/true)).isEqualTo(
|
||||||
|
CameraMetadata.SCALER_ROTATE_AND_CROP_90);
|
||||||
|
// Non-fixed orientation should be ignored
|
||||||
|
taskInfo.isFixedOrientationLandscape = false;
|
||||||
|
taskInfo.isFixedOrientationPortrait = false;
|
||||||
|
assertThat(CameraServiceProxy.getCropRotateScale(ctx, ctx.getPackageName(), taskInfo,
|
||||||
|
Surface.ROTATION_90, CameraCharacteristics.LENS_FACING_BACK,
|
||||||
|
/*ignoreResizableAndSdkCheck*/true)).isEqualTo(
|
||||||
|
CameraMetadata.SCALER_ROTATE_AND_CROP_NONE);
|
||||||
|
// Check rotation and lens facing combinations
|
||||||
|
HashMap<Integer, Integer> backFacingMap = new HashMap<Integer, Integer>() {{
|
||||||
|
put(Surface.ROTATION_0, CameraMetadata.SCALER_ROTATE_AND_CROP_NONE);
|
||||||
|
put(Surface.ROTATION_90, CameraMetadata.SCALER_ROTATE_AND_CROP_90);
|
||||||
|
put(Surface.ROTATION_270, CameraMetadata.SCALER_ROTATE_AND_CROP_270);
|
||||||
|
put(Surface.ROTATION_180, CameraMetadata.SCALER_ROTATE_AND_CROP_180);
|
||||||
|
}};
|
||||||
|
taskInfo.isFixedOrientationPortrait = true;
|
||||||
|
backFacingMap.forEach((key, value) -> {
|
||||||
|
assertThat(CameraServiceProxy.getCropRotateScale(ctx, ctx.getPackageName(), taskInfo,
|
||||||
|
key, CameraCharacteristics.LENS_FACING_BACK,
|
||||||
|
/*ignoreResizableAndSdkCheck*/true)).isEqualTo(value);
|
||||||
|
});
|
||||||
|
HashMap<Integer, Integer> frontFacingMap = new HashMap<Integer, Integer>() {{
|
||||||
|
put(Surface.ROTATION_0, CameraMetadata.SCALER_ROTATE_AND_CROP_NONE);
|
||||||
|
put(Surface.ROTATION_90, CameraMetadata.SCALER_ROTATE_AND_CROP_270);
|
||||||
|
put(Surface.ROTATION_270, CameraMetadata.SCALER_ROTATE_AND_CROP_90);
|
||||||
|
put(Surface.ROTATION_180, CameraMetadata.SCALER_ROTATE_AND_CROP_180);
|
||||||
|
}};
|
||||||
|
frontFacingMap.forEach((key, value) -> {
|
||||||
|
assertThat(CameraServiceProxy.getCropRotateScale(ctx, ctx.getPackageName(), taskInfo,
|
||||||
|
key, CameraCharacteristics.LENS_FACING_FRONT,
|
||||||
|
/*ignoreResizableAndSdkCheck*/true)).isEqualTo(value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
include platform/frameworks/av:/camera/OWNERS
|
||||||
Reference in New Issue
Block a user