summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/hardware/camera2/CameraManager.java100
-rw-r--r--core/java/android/hardware/camera2/impl/CameraDeviceSetupImpl.java5
2 files changed, 81 insertions, 24 deletions
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 8feb133e832b..3eb5be04b93d 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -112,6 +112,34 @@ public final class CameraManager {
private static final int CAMERA_TYPE_BACKWARD_COMPATIBLE = 0;
private static final int CAMERA_TYPE_ALL = 1;
+ /**
+ * Caches the mapping between a logical camera ID and 'MultiResolutionStreamConfigurationMap'
+ * that is calculated by {@link #getPhysicalCameraMultiResolutionConfigs} as the calculation
+ * might take many binder calls.
+ * <p>
+ * Note, this is a map of maps. The structure is:
+ * <pre>
+ * {
+ * logicalCameraId_1 -> {
+ * physicalCameraId_1 -> [
+ * streamConfiguration_1,
+ * streamConfiguration_2,
+ * ...
+ * ],
+ * physicalCameraId_2 -> [...],
+ * ...
+ * },
+ * logicalCameraId_2 -> {
+ * ...
+ * },
+ * ...
+ * }
+ * </pre>
+ * </p>
+ */
+ private final Map<String, Map<String, StreamConfiguration[]>>
+ mCameraIdToMultiResolutionStreamConfigurationMap = new HashMap<>();
+
private final Context mContext;
private final Object mLock = new Object();
@@ -566,8 +594,14 @@ public final class CameraManager {
private Map<String, StreamConfiguration[]> getPhysicalCameraMultiResolutionConfigs(
String cameraId, CameraMetadataNative info, ICameraService cameraService)
throws CameraAccessException {
+ if (mCameraIdToMultiResolutionStreamConfigurationMap.containsKey(cameraId)) {
+ return mCameraIdToMultiResolutionStreamConfigurationMap.get(cameraId);
+ }
+
HashMap<String, StreamConfiguration[]> multiResolutionStreamConfigurations =
- new HashMap<String, StreamConfiguration[]>();
+ new HashMap<>();
+ mCameraIdToMultiResolutionStreamConfigurationMap.put(cameraId,
+ multiResolutionStreamConfigurations);
Boolean multiResolutionStreamSupported = info.get(
CameraCharacteristics.SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED);
@@ -676,30 +710,10 @@ public final class CameraManager {
"Camera service is currently unavailable");
}
try {
- Size displaySize = getDisplaySize();
-
CameraMetadataNative info = cameraService.getCameraCharacteristics(cameraId,
mContext.getApplicationInfo().targetSdkVersion, overrideToPortrait,
mContext.getDeviceId(), getDevicePolicyFromContext(mContext));
- try {
- info.setCameraId(Integer.parseInt(cameraId));
- } catch (NumberFormatException e) {
- Log.v(TAG, "Failed to parse camera Id " + cameraId + " to integer");
- }
-
- boolean hasConcurrentStreams =
- CameraManagerGlobal.get().cameraIdHasConcurrentStreamsLocked(cameraId,
- mContext.getDeviceId());
- info.setHasMandatoryConcurrentStreams(hasConcurrentStreams);
- info.setDisplaySize(displaySize);
-
- Map<String, StreamConfiguration[]> multiResolutionSizeMap =
- getPhysicalCameraMultiResolutionConfigs(cameraId, info, cameraService);
- if (multiResolutionSizeMap.size() > 0) {
- info.setMultiResolutionStreamConfigurationMap(multiResolutionSizeMap);
- }
-
- characteristics = new CameraCharacteristics(info);
+ characteristics = prepareCameraCharacteristics(cameraId, info, cameraService);
} catch (ServiceSpecificException e) {
throw ExceptionUtils.throwAsPublicException(e);
} catch (RemoteException e) {
@@ -712,6 +726,48 @@ public final class CameraManager {
return characteristics;
}
+
+ /**
+ * Utility method to take a {@link CameraMetadataNative} object and wrap it into a
+ * {@link CameraCharacteristics} object that has all required fields and keys set and is fit
+ * for apps to consume.
+ *
+ * @param cameraId camera Id that the CameraMetadataNative was fetched for.
+ * @param metadata base CameraMetadataNative to be wrapped
+ * @param cameraService remote cameraservice instance to be used if binder calls need
+ * to be made.
+ * @return A CameraCharacteristics object that can be used by the apps.
+ * @hide
+ */
+ @NonNull
+ public CameraCharacteristics prepareCameraCharacteristics(
+ @NonNull String cameraId, CameraMetadataNative metadata, ICameraService cameraService)
+ throws CameraAccessException {
+ synchronized (mLock) {
+ try {
+ metadata.setCameraId(Integer.parseInt(cameraId));
+ } catch (NumberFormatException e) {
+ Log.v(TAG, "Failed to parse camera Id " + cameraId + " to integer");
+ }
+
+ boolean hasConcurrentStreams =
+ CameraManagerGlobal.get().cameraIdHasConcurrentStreamsLocked(cameraId,
+ mContext.getDeviceId());
+ metadata.setHasMandatoryConcurrentStreams(hasConcurrentStreams);
+
+ Size displaySize = getDisplaySize();
+ metadata.setDisplaySize(displaySize);
+
+ Map<String, StreamConfiguration[]> multiResolutionSizeMap =
+ getPhysicalCameraMultiResolutionConfigs(cameraId, metadata, cameraService);
+ if (!multiResolutionSizeMap.isEmpty()) {
+ metadata.setMultiResolutionStreamConfigurationMap(multiResolutionSizeMap);
+ }
+
+ return new CameraCharacteristics(metadata);
+ }
+ }
+
/**
* <p>Query the camera extension capabilities of a camera device.</p>
*
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceSetupImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceSetupImpl.java
index 24ac0b56a095..81d0976c09bb 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceSetupImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceSetupImpl.java
@@ -132,13 +132,14 @@ public class CameraDeviceSetupImpl extends CameraDevice.CameraDeviceSetup {
}
try {
- CameraMetadataNative metadataNative = cameraService.getSessionCharacteristics(
+ CameraMetadataNative metadata = cameraService.getSessionCharacteristics(
mCameraId, mTargetSdkVersion,
CameraManager.shouldOverrideToPortrait(mContext), sessionConfig,
mContext.getDeviceId(),
mCameraManager.getDevicePolicyFromContext(mContext));
- return new CameraCharacteristics(metadataNative);
+ return mCameraManager.prepareCameraCharacteristics(mCameraId, metadata,
+ cameraService);
} catch (ServiceSpecificException e) {
switch (e.errorCode) {
case ICameraService.ERROR_INVALID_OPERATION ->