diff options
| -rw-r--r-- | core/java/android/hardware/camera2/CameraManager.java | 100 | ||||
| -rw-r--r-- | core/java/android/hardware/camera2/impl/CameraDeviceSetupImpl.java | 5 |
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 -> |