From 0317ae8469e78cd0d6d11608adfb28b6025e2535 Mon Sep 17 00:00:00 2001 From: Shuzhen Wang Date: Fri, 28 May 2021 11:23:05 -0700 Subject: [PATCH] Camera: Pass targetSdkVersion to camera service APIs This is needed to filter out small JPEG sizes based on targetSdkVersion to maintain backward compatibility. Test: Camera CTS Bug: 187913092 Change-Id: I75bbb4d6130df62c32b01de862ad1b79fcdb7b63 --- .../camera2/CameraCharacteristics.java | 21 ++++++++++++------- .../hardware/camera2/CameraManager.java | 16 +++++++------- core/jni/android_hardware_Camera.cpp | 5 +++-- .../integration/CameraBinderTest.java | 6 ++++-- .../integration/CameraDeviceBinderTest.java | 5 +++-- 5 files changed, 33 insertions(+), 20 deletions(-) diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java index 0a124701fc0ab..e0138c5db1784 100644 --- a/core/java/android/hardware/camera2/CameraCharacteristics.java +++ b/core/java/android/hardware/camera2/CameraCharacteristics.java @@ -2511,9 +2511,9 @@ public final class CameraCharacteristics extends CameraMetadataNot all output formats may be supported in a configuration with * an input stream of a particular format. For more details, see * android.scaler.availableInputOutputFormatsMap.

- *

The following table describes the minimum required output stream - * configurations based on the hardware level - * ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel}), prior to Android 12:

+ *

For applications targeting SDK version older than 31, the following table + * describes the minimum required output stream configurations based on the hardware level + * ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel}):

* * * @@ -2574,10 +2574,13 @@ public final class CameraCharacteristics extends CameraMetadata * *
- *

Starting from Android 12, the camera device may not support JPEG sizes smaller than the - * minimum of 1080p and the camera sensor active array size. The requirements for - * IMPLEMENTATION_DEFINED and YUV_420_888 stay the same. This new minimum required output - * stream configurations are illustrated by the table below:

+ *

For applications targeting SDK version 31 or newer, if the mobile device declares to be + * {@link android.os.Build.VERSION_CDOES.MEDIA_PERFORMANCE_CLASS media performance class} S, + * the primary camera devices (first rear/front camera in the camera ID list) will not + * support JPEG sizes smaller than 1080p. If the application configures a JPEG stream + * smaller than 1080p, the camera device will round up the JPEG image size to at least + * 1080p. The requirements for IMPLEMENTATION_DEFINED and YUV_420_888 stay the same. + * This new minimum required output stream configurations are illustrated by the table below:

* * * @@ -2644,6 +2647,10 @@ public final class CameraCharacteristics extends CameraMetadata * *
+ *

For applications targeting SDK version 31 or newer, if the mobile device doesn't declare + * to be media performance class S, or if the camera device isn't a primary rear/front + * camera, the minimum required output stream configurations are the same as for applications + * targeting SDK version older than 31.

*

Refer to {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} for additional * mandatory stream configurations on a per-capability basis.

*

Exception on 176x144 (QCIF) resolution: camera devices usually have a fixed capability for diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java index c1af99a82bc80..a1c8d29566bee 100644 --- a/core/java/android/hardware/camera2/CameraManager.java +++ b/core/java/android/hardware/camera2/CameraManager.java @@ -217,7 +217,7 @@ public final class CameraManager { @NonNull Map cameraIdAndSessionConfig) throws CameraAccessException { return CameraManagerGlobal.get().isConcurrentSessionConfigurationSupported( - cameraIdAndSessionConfig); + cameraIdAndSessionConfig, mContext.getApplicationInfo().targetSdkVersion); } /** @@ -413,7 +413,8 @@ public final class CameraManager { try { for (String physicalCameraId : physicalCameraIds) { CameraMetadataNative physicalCameraInfo = - cameraService.getCameraCharacteristics(physicalCameraId); + cameraService.getCameraCharacteristics(physicalCameraId, + mContext.getApplicationInfo().targetSdkVersion); StreamConfiguration[] configs = physicalCameraInfo.get( CameraCharacteristics. SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS); @@ -472,7 +473,8 @@ public final class CameraManager { try { Size displaySize = getDisplaySize(); - CameraMetadataNative info = cameraService.getCameraCharacteristics(cameraId); + CameraMetadataNative info = cameraService.getCameraCharacteristics(cameraId, + mContext.getApplicationInfo().targetSdkVersion); try { info.setCameraId(Integer.parseInt(cameraId)); } catch (NumberFormatException e) { @@ -590,7 +592,7 @@ public final class CameraManager { } cameraUser = cameraService.connectDevice(callbacks, cameraId, mContext.getOpPackageName(), mContext.getAttributionTag(), uid, - oomScoreOffset); + oomScoreOffset, mContext.getApplicationInfo().targetSdkVersion); } catch (ServiceSpecificException e) { if (e.errorCode == ICameraService.ERROR_DEPRECATED_HAL) { throw new AssertionError("Should've gone down the shim path"); @@ -1613,8 +1615,8 @@ public final class CameraManager { } public boolean isConcurrentSessionConfigurationSupported( - @NonNull Map cameraIdsAndSessionConfigurations) - throws CameraAccessException { + @NonNull Map cameraIdsAndSessionConfigurations, + int targetSdkVersion) throws CameraAccessException { if (cameraIdsAndSessionConfigurations == null) { throw new IllegalArgumentException("cameraIdsAndSessionConfigurations was null"); @@ -1650,7 +1652,7 @@ public final class CameraManager { } try { return mCameraService.isConcurrentSessionConfigurationSupported( - cameraIdsAndConfigs); + cameraIdsAndConfigs, targetSdkVersion); } catch (ServiceSpecificException e) { throwAsPublicException(e); } catch (RemoteException e) { diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp index e47f18a943d9c..365a18d174c9e 100644 --- a/core/jni/android_hardware_Camera.cpp +++ b/core/jni/android_hardware_Camera.cpp @@ -566,8 +566,9 @@ static jint android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz, env->ReleaseStringChars(clientPackageName, reinterpret_cast(rawClientName)); - sp camera = - Camera::connect(cameraId, clientName, Camera::USE_CALLING_UID, Camera::USE_CALLING_PID); + int targetSdkVersion = android_get_application_target_sdk_version(); + sp camera = Camera::connect(cameraId, clientName, Camera::USE_CALLING_UID, + Camera::USE_CALLING_PID, targetSdkVersion); if (camera == NULL) { return -EACCES; } diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java index 8de507404ca9b..6dc05ad010e6a 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java @@ -158,7 +158,8 @@ public class CameraBinderTest extends AndroidTestCase { ICamera cameraUser = mUtils.getCameraService() .connect(dummyCallbacks, cameraId, clientPackageName, ICameraService.USE_CALLING_UID, - ICameraService.USE_CALLING_PID); + ICameraService.USE_CALLING_PID, + getContext().getApplicationInfo().targetSdkVersion); assertNotNull(String.format("Camera %s was null", cameraId), cameraUser); Log.v(TAG, String.format("Camera %s connected", cameraId)); @@ -262,7 +263,8 @@ public class CameraBinderTest extends AndroidTestCase { mUtils.getCameraService().connectDevice( dummyCallbacks, String.valueOf(cameraId), clientPackageName, clientAttributionTag, - ICameraService.USE_CALLING_UID, 0 /*oomScoreOffset*/); + ICameraService.USE_CALLING_UID, 0 /*oomScoreOffset*/, + getContext().getApplicationInfo().targetSdkVersion); assertNotNull(String.format("Camera %s was null", cameraId), cameraUser); Log.v(TAG, String.format("Camera %s connected", cameraId)); diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java index 408f2f88b26e9..0890346db1985 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java @@ -244,7 +244,7 @@ public class CameraDeviceBinderTest extends AndroidTestCase { mCameraUser = mUtils.getCameraService().connectDevice(mMockCb, mCameraId, clientPackageName, clientAttributionTag, ICameraService.USE_CALLING_UID, - /*oomScoreOffset*/0); + /*oomScoreOffset*/0, getContext().getApplicationInfo().targetSdkVersion); assertNotNull(String.format("Camera %s was null", mCameraId), mCameraUser); mHandlerThread = new HandlerThread(TAG); mHandlerThread.start(); @@ -416,7 +416,8 @@ public class CameraDeviceBinderTest extends AndroidTestCase { @SmallTest public void testCameraCharacteristics() throws RemoteException { - CameraMetadataNative info = mUtils.getCameraService().getCameraCharacteristics(mCameraId); + CameraMetadataNative info = mUtils.getCameraService().getCameraCharacteristics(mCameraId, + getContext().getApplicationInfo().targetSdkVersion); assertFalse(info.isEmpty()); assertNotNull(info.get(CameraCharacteristics.SCALER_AVAILABLE_FORMATS));