diff options
| author | 2024-01-29 20:13:18 +0000 | |
|---|---|---|
| committer | 2024-02-07 18:13:14 +0000 | |
| commit | 4480a41dd733ea09552400a8b53d4673b5afbfb8 (patch) | |
| tree | 475cb4eb5eab8a4cc50061e2131de44e6a17c3a3 | |
| parent | c7d6d505b2dd5c353132d95ea144a97a72b11fda (diff) | |
Camera: Polish ExtensionService docs and APIs
Improve various extension related system APIs including:
- Missing java docs
- Missing doc links
- Incorrect or missing annotations
- Interface names
Bug: 322520569
Test: make docs
Change-Id: I4fc25b419315e92c1df80479c35b572c412f09b4
9 files changed, 253 insertions, 129 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt index d0fdf694cad7..521d00f0f148 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -4583,7 +4583,7 @@ package android.hardware.camera2 { package android.hardware.camera2.extension { @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract class AdvancedExtender { - ctor @FlaggedApi("com.android.internal.camera.flags.concert_mode") protected AdvancedExtender(@NonNull android.hardware.camera2.CameraManager); + ctor @FlaggedApi("com.android.internal.camera.flags.concert_mode") public AdvancedExtender(@NonNull android.hardware.camera2.CameraManager); method @FlaggedApi("com.android.internal.camera.flags.concert_mode") @NonNull public abstract java.util.List<android.hardware.camera2.CaptureRequest.Key> getAvailableCaptureRequestKeys(@NonNull String); method @FlaggedApi("com.android.internal.camera.flags.concert_mode") @NonNull public abstract java.util.List<android.hardware.camera2.CaptureResult.Key> getAvailableCaptureResultKeys(@NonNull String); method @FlaggedApi("com.android.internal.camera.flags.camera_extensions_characteristics_get") @NonNull public abstract java.util.List<android.util.Pair<android.hardware.camera2.CameraCharacteristics.Key,java.lang.Object>> getAvailableCharacteristicsKeyValues(); @@ -4591,23 +4591,23 @@ package android.hardware.camera2.extension { method @FlaggedApi("com.android.internal.camera.flags.concert_mode") @NonNull public abstract android.hardware.camera2.extension.SessionProcessor getSessionProcessor(); method @FlaggedApi("com.android.internal.camera.flags.concert_mode") @NonNull public abstract java.util.Map<java.lang.Integer,java.util.List<android.util.Size>> getSupportedCaptureOutputResolutions(@NonNull String); method @FlaggedApi("com.android.internal.camera.flags.concert_mode") @NonNull public abstract java.util.Map<java.lang.Integer,java.util.List<android.util.Size>> getSupportedPreviewOutputResolutions(@NonNull String); - method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract void init(@NonNull String, @NonNull android.hardware.camera2.extension.CharacteristicsMap); + method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract void initialize(@NonNull String, @NonNull android.hardware.camera2.extension.CharacteristicsMap); method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract boolean isExtensionAvailable(@NonNull String, @NonNull android.hardware.camera2.extension.CharacteristicsMap); } @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract class CameraExtensionService extends android.app.Service { ctor @FlaggedApi("com.android.internal.camera.flags.concert_mode") protected CameraExtensionService(); - method @FlaggedApi("com.android.internal.camera.flags.concert_mode") @NonNull public android.os.IBinder onBind(@Nullable android.content.Intent); + method @FlaggedApi("com.android.internal.camera.flags.concert_mode") @NonNull public final android.os.IBinder onBind(@Nullable android.content.Intent); method @FlaggedApi("com.android.internal.camera.flags.concert_mode") @NonNull public abstract android.hardware.camera2.extension.AdvancedExtender onInitializeAdvancedExtension(int); method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract boolean onRegisterClient(@NonNull android.os.IBinder); method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract void onUnregisterClient(@NonNull android.os.IBinder); } @FlaggedApi("com.android.internal.camera.flags.concert_mode") public final class CameraOutputSurface { - ctor @FlaggedApi("com.android.internal.camera.flags.concert_mode") public CameraOutputSurface(@NonNull android.view.Surface, @Nullable android.util.Size); + ctor @FlaggedApi("com.android.internal.camera.flags.concert_mode") public CameraOutputSurface(@NonNull android.view.Surface, @NonNull android.util.Size); method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public int getImageFormat(); - method @FlaggedApi("com.android.internal.camera.flags.concert_mode") @Nullable public android.util.Size getSize(); - method @FlaggedApi("com.android.internal.camera.flags.concert_mode") @Nullable public android.view.Surface getSurface(); + method @FlaggedApi("com.android.internal.camera.flags.concert_mode") @NonNull public android.util.Size getSize(); + method @FlaggedApi("com.android.internal.camera.flags.concert_mode") @NonNull public android.view.Surface getSurface(); } @FlaggedApi("com.android.internal.camera.flags.concert_mode") public class CharacteristicsMap { @@ -4625,10 +4625,10 @@ package android.hardware.camera2.extension { @FlaggedApi("com.android.internal.camera.flags.concert_mode") public final class RequestProcessor { method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public void abortCaptures(); - method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public int setRepeating(@NonNull android.hardware.camera2.extension.RequestProcessor.Request, @Nullable java.util.concurrent.Executor, @NonNull android.hardware.camera2.extension.RequestProcessor.RequestCallback); + method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public int setRepeating(@NonNull android.hardware.camera2.extension.RequestProcessor.Request, @NonNull java.util.concurrent.Executor, @NonNull android.hardware.camera2.extension.RequestProcessor.RequestCallback) throws android.hardware.camera2.CameraAccessException; method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public void stopRepeating(); - method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public int submit(@NonNull android.hardware.camera2.extension.RequestProcessor.Request, @Nullable java.util.concurrent.Executor, @NonNull android.hardware.camera2.extension.RequestProcessor.RequestCallback); - method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public int submitBurst(@NonNull java.util.List<android.hardware.camera2.extension.RequestProcessor.Request>, @Nullable java.util.concurrent.Executor, @NonNull android.hardware.camera2.extension.RequestProcessor.RequestCallback); + method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public int submit(@NonNull android.hardware.camera2.extension.RequestProcessor.Request, @NonNull java.util.concurrent.Executor, @NonNull android.hardware.camera2.extension.RequestProcessor.RequestCallback) throws android.hardware.camera2.CameraAccessException; + method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public int submitBurst(@NonNull java.util.List<android.hardware.camera2.extension.RequestProcessor.Request>, @NonNull java.util.concurrent.Executor, @NonNull android.hardware.camera2.extension.RequestProcessor.RequestCallback) throws android.hardware.camera2.CameraAccessException; } @FlaggedApi("com.android.internal.camera.flags.concert_mode") public static final class RequestProcessor.Request { @@ -4647,15 +4647,15 @@ package android.hardware.camera2.extension { } @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract class SessionProcessor { - ctor @FlaggedApi("com.android.internal.camera.flags.concert_mode") protected SessionProcessor(); + ctor @FlaggedApi("com.android.internal.camera.flags.concert_mode") public SessionProcessor(); method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract void deInitSession(@NonNull android.os.IBinder); method @FlaggedApi("com.android.internal.camera.flags.concert_mode") @NonNull public abstract android.hardware.camera2.extension.ExtensionConfiguration initSession(@NonNull android.os.IBinder, @NonNull String, @NonNull android.hardware.camera2.extension.CharacteristicsMap, @NonNull android.hardware.camera2.extension.CameraOutputSurface, @NonNull android.hardware.camera2.extension.CameraOutputSurface); method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract void onCaptureSessionEnd(); method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract void onCaptureSessionStart(@NonNull android.hardware.camera2.extension.RequestProcessor, @NonNull String); method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract void setParameters(@NonNull android.hardware.camera2.CaptureRequest); - method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract int startCapture(@Nullable java.util.concurrent.Executor, @NonNull android.hardware.camera2.extension.SessionProcessor.CaptureCallback); - method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract int startRepeating(@Nullable java.util.concurrent.Executor, @NonNull android.hardware.camera2.extension.SessionProcessor.CaptureCallback); - method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract int startTrigger(@NonNull android.hardware.camera2.CaptureRequest, @Nullable java.util.concurrent.Executor, @NonNull android.hardware.camera2.extension.SessionProcessor.CaptureCallback); + method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract int startMultiFrameCapture(@NonNull java.util.concurrent.Executor, @NonNull android.hardware.camera2.extension.SessionProcessor.CaptureCallback); + method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract int startRepeating(@NonNull java.util.concurrent.Executor, @NonNull android.hardware.camera2.extension.SessionProcessor.CaptureCallback); + method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract int startTrigger(@NonNull android.hardware.camera2.CaptureRequest, @NonNull java.util.concurrent.Executor, @NonNull android.hardware.camera2.extension.SessionProcessor.CaptureCallback); method @FlaggedApi("com.android.internal.camera.flags.concert_mode") public abstract void stopRepeating(); } diff --git a/core/java/android/hardware/camera2/extension/AdvancedExtender.java b/core/java/android/hardware/camera2/extension/AdvancedExtender.java index 665357726ebf..4895f38d7328 100644 --- a/core/java/android/hardware/camera2/extension/AdvancedExtender.java +++ b/core/java/android/hardware/camera2/extension/AdvancedExtender.java @@ -43,8 +43,9 @@ import java.util.Map; * * <p>This advanced contract empowers implementations to gain access to * more Camera2 capability. This includes: (1) Add custom surfaces with - * specific formats like YUV, RAW, RAW_DEPTH. (2) Access to - * the capture request callbacks as well as all the images retrieved of + * specific formats like {@link android.graphics.ImageFormat#YUV_420_888}, + * {@link android.graphics.ImageFormat#RAW10}, {@link android.graphics.ImageFormat#RAW_DEPTH10}. + * (2) Access to the capture request callbacks as well as all the images retrieved of * various image formats. (3) * Able to triggers single or repeating request with the capabilities to * specify target surfaces, template id and parameters. @@ -60,8 +61,14 @@ public abstract class AdvancedExtender { private CameraUsageTracker mCameraUsageTracker; private static final String TAG = "AdvancedExtender"; + + /** + * Initialize a camera extension advanced extender instance. + * + * @param cameraManager the system camera manager + */ @FlaggedApi(Flags.FLAG_CONCERT_MODE) - protected AdvancedExtender(@NonNull CameraManager cameraManager) { + public AdvancedExtender(@NonNull CameraManager cameraManager) { mCameraManager = cameraManager; try { String [] cameraIds = mCameraManager.getCameraIdListNoLazy(); @@ -87,6 +94,14 @@ public abstract class AdvancedExtender { mCameraUsageTracker = tracker; } + /** + * Returns the camera metadata vendor id, that can be used to + * configure and enable vendor tag support for a particular + * camera metadata buffer. + * + * @param cameraId The camera2 id string of the camera. + * @return the camera metadata vendor Id associated with the given camera + */ @FlaggedApi(Flags.FLAG_CONCERT_MODE) public long getMetadataVendorId(@NonNull String cameraId) { long vendorId = mMetadataVendorIdMap.containsKey(cameraId) ? @@ -131,12 +146,15 @@ public abstract class AdvancedExtender { * CameraCharacteristics. */ @FlaggedApi(Flags.FLAG_CONCERT_MODE) - public abstract void init(@NonNull String cameraId, @NonNull CharacteristicsMap map); + public abstract void initialize(@NonNull String cameraId, @NonNull CharacteristicsMap map); /** * Returns supported output format/size map for preview. The format - * could be PRIVATE or YUV_420_888. Implementations must support - * PRIVATE format at least. + * could be {@link android.graphics.ImageFormat#PRIVATE} or + * {@link android.graphics.ImageFormat#YUV_420_888}. Implementations must support + * {@link android.graphics.ImageFormat#PRIVATE} format at least. + * An example of how the map is parsed can be found in + * {@link #initializeParcelable(Map)} * * <p>The preview surface format in the CameraCaptureSession may not * be identical to the supported preview output format returned here. @@ -149,11 +167,16 @@ public abstract class AdvancedExtender { /** * Returns supported output format/size map for image capture. OEM is - * required to support both JPEG and YUV_420_888 format output. + * required to support both {@link android.graphics.ImageFormat#JPEG} and + * {@link android.graphics.ImageFormat#YUV_420_888} format output. + * An example of how the map is parsed can be found in + * {@link #initializeParcelable(Map)} * * <p>The surface created with this supported * format/size could be either added in CameraCaptureSession with HAL - * processing OR it configures intermediate surfaces(YUV/RAW..) and + * processing OR it configures intermediate surfaces( + * {@link android.graphics.ImageFormat#YUV_420_888}/ + * {@link android.graphics.ImageFormat#RAW10}..) and * writes the output to the output surface. * @param cameraId The camera2 id string of the camera. */ @@ -256,7 +279,7 @@ public abstract class AdvancedExtender { @Override public void init(String cameraId, Map<String, CameraMetadataNative> charsMapNative) { - AdvancedExtender.this.init(cameraId, new CharacteristicsMap(charsMapNative)); + AdvancedExtender.this.initialize(cameraId, new CharacteristicsMap(charsMapNative)); } @Override diff --git a/core/java/android/hardware/camera2/extension/CameraExtensionService.java b/core/java/android/hardware/camera2/extension/CameraExtensionService.java index fa0d14a3f05a..01698d54150c 100644 --- a/core/java/android/hardware/camera2/extension/CameraExtensionService.java +++ b/core/java/android/hardware/camera2/extension/CameraExtensionService.java @@ -23,6 +23,7 @@ import android.annotation.SystemApi; import android.app.AppOpsManager; import android.app.Service; import android.content.Intent; +import android.hardware.camera2.CameraExtensionCharacteristics.Extension; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; @@ -92,7 +93,7 @@ public abstract class CameraExtensionService extends Service { @FlaggedApi(Flags.FLAG_CONCERT_MODE) @Override @NonNull - public IBinder onBind(@Nullable Intent intent) { + public final IBinder onBind(@Nullable Intent intent) { if (mCameraUsageTracker == null) { mCameraUsageTracker = new CameraTracker(); } @@ -153,21 +154,21 @@ public abstract class CameraExtensionService extends Service { } @Override - public IPreviewExtenderImpl initializePreviewExtension(int extensionType) + public IPreviewExtenderImpl initializePreviewExtension(@Extension int extensionType) throws RemoteException { // Basic Extension API is not supported return null; } @Override - public IImageCaptureExtenderImpl initializeImageExtension(int extensionType) + public IImageCaptureExtenderImpl initializeImageExtension(@Extension int extensionType) throws RemoteException { // Basic Extension API is not supported return null; } @Override - public IAdvancedExtenderImpl initializeAdvancedExtension(int extensionType) + public IAdvancedExtenderImpl initializeAdvancedExtension(@Extension int extensionType) throws RemoteException { AdvancedExtender extender = CameraExtensionService.this.onInitializeAdvancedExtension( extensionType); @@ -205,5 +206,5 @@ public abstract class CameraExtensionService extends Service { */ @FlaggedApi(Flags.FLAG_CONCERT_MODE) @NonNull - public abstract AdvancedExtender onInitializeAdvancedExtension(int extensionType); + public abstract AdvancedExtender onInitializeAdvancedExtension(@Extension int extensionType); } diff --git a/core/java/android/hardware/camera2/extension/CameraOutputSurface.java b/core/java/android/hardware/camera2/extension/CameraOutputSurface.java index f98ebee5d7c7..b4fe7fe1f0d1 100644 --- a/core/java/android/hardware/camera2/extension/CameraOutputSurface.java +++ b/core/java/android/hardware/camera2/extension/CameraOutputSurface.java @@ -18,8 +18,8 @@ package android.hardware.camera2.extension; import android.annotation.FlaggedApi; import android.annotation.NonNull; -import android.annotation.Nullable; import android.annotation.SystemApi; +import android.graphics.ImageFormat; import android.hardware.camera2.utils.SurfaceUtils; import android.util.Size; import android.view.Surface; @@ -28,6 +28,14 @@ import com.android.internal.camera.flags.Flags; /** + * Helper method used to describe a single camera output + * {@link Surface}. + * + * <p>Instances of this class can be used as arguments when + * initializing {@link ExtensionOutputConfiguration}.</p> + * + * @see ExtensionConfiguration + * @see ExtensionOutputConfiguration * @hide */ @SystemApi @@ -40,27 +48,39 @@ public final class CameraOutputSurface { mOutputSurface = surface; } + /** + * Initialize a camera output surface instance + * + * @param surface Output {@link Surface} to be + * configured as camera output + * @param size Requested size of the camera + * output + */ @FlaggedApi(Flags.FLAG_CONCERT_MODE) public CameraOutputSurface(@NonNull Surface surface, - @Nullable Size size ) { + @NonNull Size size) { mOutputSurface = new OutputSurface(); mOutputSurface.surface = surface; mOutputSurface.imageFormat = SurfaceUtils.getSurfaceFormat(surface); - if (size != null) { - mOutputSurface.size = new android.hardware.camera2.extension.Size(); - mOutputSurface.size.width = size.getWidth(); - mOutputSurface.size.height = size.getHeight(); - } + mOutputSurface.size = new android.hardware.camera2.extension.Size(); + mOutputSurface.size.width = size.getWidth(); + mOutputSurface.size.height = size.getHeight(); } + /** + * Return the current output {@link Surface} + */ @FlaggedApi(Flags.FLAG_CONCERT_MODE) - @Nullable + @NonNull public Surface getSurface() { return mOutputSurface.surface; } + /** + * Return the current requested output size + */ @FlaggedApi(Flags.FLAG_CONCERT_MODE) - @Nullable + @NonNull public android.util.Size getSize() { if (mOutputSurface.size != null) { return new Size(mOutputSurface.size.width, mOutputSurface.size.height); @@ -68,8 +88,11 @@ public final class CameraOutputSurface { return null; } + /** + * Return the current surface output {@link android.graphics.ImageFormat} + */ @FlaggedApi(Flags.FLAG_CONCERT_MODE) - public int getImageFormat() { + public @ImageFormat.Format int getImageFormat() { return mOutputSurface.imageFormat; } } diff --git a/core/java/android/hardware/camera2/extension/CharacteristicsMap.java b/core/java/android/hardware/camera2/extension/CharacteristicsMap.java index af83595babef..495abc8100ae 100644 --- a/core/java/android/hardware/camera2/extension/CharacteristicsMap.java +++ b/core/java/android/hardware/camera2/extension/CharacteristicsMap.java @@ -30,12 +30,22 @@ import java.util.Map; import java.util.Set; /** + * Helper class used to forward the current + * system camera characteristics information. + * * @hide */ @SystemApi @FlaggedApi(Flags.FLAG_CONCERT_MODE) public class CharacteristicsMap { private final HashMap<String, CameraCharacteristics> mCharMap; + + /** + * Initialize a camera characteristics map instance + * + * @param charsMap Maps camera ids to respective + * {@link CameraCharacteristics} + */ @FlaggedApi(Flags.FLAG_CONCERT_MODE) CharacteristicsMap(@NonNull Map<String, CameraMetadataNative> charsMap) { mCharMap = new HashMap<>(); @@ -44,12 +54,26 @@ public class CharacteristicsMap { } } + /** + * Return the set of camera ids stored in the characteristics map + * + * @return Set of the camera ids stored in the map + */ @FlaggedApi(Flags.FLAG_CONCERT_MODE) @NonNull public Set<String> getCameraIds() { return mCharMap.keySet(); } + /** + * Return the corresponding {@link CameraCharacteristics} given + * a valid camera id + * + * @param cameraId Camera device id + * + * @return Valid {@link CameraCharacteristics} instance of null + * in case the camera id is not part of the map + */ @FlaggedApi(Flags.FLAG_CONCERT_MODE) @Nullable public CameraCharacteristics get(@NonNull String cameraId) { diff --git a/core/java/android/hardware/camera2/extension/ExtensionConfiguration.java b/core/java/android/hardware/camera2/extension/ExtensionConfiguration.java index 2d9ab765d1e0..96c88e660e10 100644 --- a/core/java/android/hardware/camera2/extension/ExtensionConfiguration.java +++ b/core/java/android/hardware/camera2/extension/ExtensionConfiguration.java @@ -20,7 +20,9 @@ import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; +import android.hardware.camera2.CameraDevice; import android.hardware.camera2.CaptureRequest; +import android.os.IBinder; import com.android.internal.camera.flags.Flags; @@ -28,6 +30,15 @@ import java.util.ArrayList; import java.util.List; /** + * Helper class used to guide the camera framework when + * initializing the internal camera capture session. + * It contains all required internal outputs, parameters, + * modes and settings. + * + * <p>Extension must decide the final set of output surfaces + * and pass an instance of ExtensionConfiguration as part + * of the result during calls to {@link SessionProcessor#initSession}.</p> + * * @hide */ @SystemApi @@ -38,9 +49,25 @@ public class ExtensionConfiguration { private final List<ExtensionOutputConfiguration> mOutputs; private final CaptureRequest mSessionParameters; + /** + * Initialize an extension configuration instance + * + * @param sessionType The type of camera capture session + * operating mode to be used + * @param sessionTemplateId The request template id to be used + * for generating the session parameter + * capture request + * @param outputs List of {@link ExtensionOutputConfiguration} + * camera outputs to be configured + * as part of the capture session + * @param sessionParams An optional set of camera capture + * session parameter values + */ @FlaggedApi(Flags.FLAG_CONCERT_MODE) - public ExtensionConfiguration(int sessionType, int sessionTemplateId, @NonNull - List<ExtensionOutputConfiguration> outputs, @Nullable CaptureRequest sessionParams) { + public ExtensionConfiguration(@CameraDevice.SessionOperatingMode int sessionType, + @CameraDevice.RequestTemplate int sessionTemplateId, + @NonNull List<ExtensionOutputConfiguration> outputs, + @Nullable CaptureRequest sessionParams) { mSessionType = sessionType; mSessionTemplateId = sessionTemplateId; mOutputs = outputs; diff --git a/core/java/android/hardware/camera2/extension/ExtensionOutputConfiguration.java b/core/java/android/hardware/camera2/extension/ExtensionOutputConfiguration.java index 85d180d379df..9dc6d7bf94b3 100644 --- a/core/java/android/hardware/camera2/extension/ExtensionOutputConfiguration.java +++ b/core/java/android/hardware/camera2/extension/ExtensionOutputConfiguration.java @@ -27,6 +27,10 @@ import java.util.ArrayList; import java.util.List; /** + * Helper class used to describe a single camera + * output configuration that is intended to be configured + * internally by the extension implementation. + * * @hide */ @SystemApi @@ -37,6 +41,21 @@ public class ExtensionOutputConfiguration { private final int mOutputConfigId; private final int mSurfaceGroupId; + /** + * Initialize an extension output configuration instance + * + * @param outputs List of camera {@link CameraOutputSurface outputs}. + * The list may include more than one entry + * only in case of shared camera outputs. + * In all other cases the list will only include + * a single entry. + * @param outputConfigId Unique output configuration id used to identify + * this particular configuration. + * @param physicalCameraId In case of physical camera capture, this field + * must contain a valid physical camera id. + * @param surfaceGroupId In case of surface group, this field must + * contain the surface group id + */ @FlaggedApi(Flags.FLAG_CONCERT_MODE) public ExtensionOutputConfiguration(@NonNull List<CameraOutputSurface> outputs, int outputConfigId, @Nullable String physicalCameraId, int surfaceGroupId) { diff --git a/core/java/android/hardware/camera2/extension/RequestProcessor.java b/core/java/android/hardware/camera2/extension/RequestProcessor.java index bf5ea12df358..0ad27c212d67 100644 --- a/core/java/android/hardware/camera2/extension/RequestProcessor.java +++ b/core/java/android/hardware/camera2/extension/RequestProcessor.java @@ -20,7 +20,9 @@ import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; +import android.hardware.camera2.CameraAccessException; import android.hardware.camera2.CameraCharacteristics; +import android.hardware.camera2.CameraDevice; import android.hardware.camera2.CaptureFailure; import android.hardware.camera2.CaptureRequest; import android.hardware.camera2.CaptureResult; @@ -69,6 +71,8 @@ public final class RequestProcessor { * regular request, or the timestamp at the input * image's start of capture for a * reprocess request, in nanoseconds. + * The timestamp matches with and uses the same + * time base as {@link CaptureResult#SENSOR_TIMESTAMP}. * @param frameNumber the frame number for this capture * */ @@ -225,11 +229,12 @@ public final class RequestProcessor { public final static class Request { private final List<Integer> mOutputIds; private final List<Pair<CaptureRequest.Key, Object>> mParameters; - private final int mTemplateId; + private final @CameraDevice.RequestTemplate int mTemplateId; @FlaggedApi(Flags.FLAG_CONCERT_MODE) public Request(@NonNull List<Integer> outputConfigIds, - @NonNull List<Pair<CaptureRequest.Key, Object>> parameters, int templateId) { + @NonNull List<Pair<CaptureRequest.Key, Object>> parameters, + @CameraDevice.RequestTemplate int templateId) { mOutputIds = outputConfigIds; mParameters = parameters; mTemplateId = templateId; @@ -255,7 +260,10 @@ public final class RequestProcessor { } /** - * Gets the template id. + * Gets the request {@link android.hardware.camera2.CameraDevice.RequestTemplate template} + * id. + * + * @see CameraDevice.RequestTemplate */ @FlaggedApi(Flags.FLAG_CONCERT_MODE) Integer getTemplateId() { @@ -310,26 +318,32 @@ public final class RequestProcessor { * Submit a capture request. * @param request Capture request to queued in the Camera2 session * @param executor the executor which will be used for - * invoking the callbacks or null to use the - * current thread's looper + * invoking the callbacks * @param callback Request callback implementation - * @return the id of the capture sequence or -1 in case the processor - * encounters a fatal error or receives an invalid argument. + * @return the id of the capture sequence */ @FlaggedApi(Flags.FLAG_CONCERT_MODE) - public int submit(@NonNull Request request, @Nullable Executor executor, - @NonNull RequestCallback callback) { + public int submit(@NonNull Request request, @NonNull Executor executor, + @NonNull RequestCallback callback) throws CameraAccessException { ArrayList<Request> requests = new ArrayList<>(1); requests.add(0, request); List<android.hardware.camera2.extension.Request> parcelableRequests = Request.initializeParcelable(mVendorId, requests); + int ret = -1; try { - return mRequestProcessor.submit(parcelableRequests.get(0), + ret = mRequestProcessor.submit(parcelableRequests.get(0), new RequestCallbackImpl(requests, callback, executor)); } catch (RemoteException e) { throw new RuntimeException(e); } + + if (ret == -1) { + throw new CameraAccessException(CameraAccessException.CAMERA_ERROR, + "Failed to submit capture request"); + } + + return ret; } /** @@ -337,24 +351,30 @@ public final class RequestProcessor { * @param requests List of capture requests to be queued in the * Camera2 session * @param executor the executor which will be used for - * invoking the callbacks or null to use the - * current thread's looper + * invoking the callbacks * @param callback Request callback implementation - * @return the id of the capture sequence or -1 in case the processor - * encounters a fatal error or receives an invalid argument. + * @return the id of the capture sequence */ @FlaggedApi(Flags.FLAG_CONCERT_MODE) - public int submitBurst(@NonNull List<Request> requests, @Nullable Executor executor, - @NonNull RequestCallback callback) { + public int submitBurst(@NonNull List<Request> requests, @NonNull Executor executor, + @NonNull RequestCallback callback) throws CameraAccessException { List<android.hardware.camera2.extension.Request> parcelableRequests = Request.initializeParcelable(mVendorId, requests); + int ret = -1; try { - return mRequestProcessor.submitBurst(parcelableRequests, + ret = mRequestProcessor.submitBurst(parcelableRequests, new RequestCallbackImpl(requests, callback, executor)); } catch (RemoteException e) { throw new RuntimeException(e); } + + if (ret == -1) { + throw new CameraAccessException(CameraAccessException.CAMERA_ERROR, + "Failed to submit burst request"); + } + + return ret; } /** @@ -362,26 +382,32 @@ public final class RequestProcessor { * @param request Repeating capture request to be se in the * Camera2 session * @param executor the executor which will be used for - * invoking the callbacks or null to use the - * current thread's looper + * invoking the callbacks * @param callback Request callback implementation - * @return the id of the capture sequence or -1 in case the processor - * encounters a fatal error or receives an invalid argument. + * @return the id of the capture sequence */ @FlaggedApi(Flags.FLAG_CONCERT_MODE) - public int setRepeating(@NonNull Request request, @Nullable Executor executor, - @NonNull RequestCallback callback) { + public int setRepeating(@NonNull Request request, @NonNull Executor executor, + @NonNull RequestCallback callback) throws CameraAccessException { ArrayList<Request> requests = new ArrayList<>(1); requests.add(0, request); List<android.hardware.camera2.extension.Request> parcelableRequests = Request.initializeParcelable(mVendorId, requests); + int ret = -1; try { - return mRequestProcessor.setRepeating(parcelableRequests.get(0), + ret = mRequestProcessor.setRepeating(parcelableRequests.get(0), new RequestCallbackImpl(requests, callback, executor)); } catch (RemoteException e) { throw new RuntimeException(e); } + if (ret == -1) { + throw new CameraAccessException(CameraAccessException.CAMERA_ERROR, + "Failed to set the repeating request"); + + } + + return ret; } /** @@ -414,7 +440,7 @@ public final class RequestProcessor { private final Executor mExecutor; public RequestCallbackImpl(@NonNull List<Request> requests, - @NonNull RequestCallback callback, @Nullable Executor executor) { + @NonNull RequestCallback callback, @NonNull Executor executor) { mCallback = callback; mRequests = requests; mExecutor = executor; @@ -425,13 +451,8 @@ public final class RequestProcessor { if (mRequests.get(requestId) != null) { final long ident = Binder.clearCallingIdentity(); try { - if (mExecutor != null) { - mExecutor.execute(() -> mCallback.onCaptureStarted( - mRequests.get(requestId), frameNumber, timestamp)); - } else { - mCallback.onCaptureStarted(mRequests.get(requestId), frameNumber, - timestamp); - } + mExecutor.execute(() -> mCallback.onCaptureStarted( + mRequests.get(requestId), frameNumber, timestamp)); } finally { Binder.restoreCallingIdentity(ident); } @@ -448,14 +469,9 @@ public final class RequestProcessor { partialResult.frameNumber); final long ident = Binder.clearCallingIdentity(); try { - if (mExecutor != null) { - mExecutor.execute( - () -> mCallback.onCaptureProgressed(mRequests.get(requestId), - result)); - } else { - mCallback.onCaptureProgressed(mRequests.get(requestId), result); - } - + mExecutor.execute( + () -> mCallback.onCaptureProgressed(mRequests.get(requestId), + result)); } finally { Binder.restoreCallingIdentity(ident); } @@ -489,13 +505,9 @@ public final class RequestProcessor { physicalResults); final long ident = Binder.clearCallingIdentity(); try { - if (mExecutor != null) { - mExecutor.execute( - () -> mCallback.onCaptureCompleted(mRequests.get(requestId), - result)); - } else { - mCallback.onCaptureCompleted(mRequests.get(requestId), result); - } + mExecutor.execute( + () -> mCallback.onCaptureCompleted(mRequests.get(requestId), + result)); } finally { Binder.restoreCallingIdentity(ident); } @@ -515,12 +527,8 @@ public final class RequestProcessor { captureFailure.errorPhysicalCameraId); final long ident = Binder.clearCallingIdentity(); try { - if (mExecutor != null) { - mExecutor.execute(() -> mCallback.onCaptureFailed(mRequests.get(requestId), - failure)); - } else { - mCallback.onCaptureFailed(mRequests.get(requestId), failure); - } + mExecutor.execute(() -> mCallback.onCaptureFailed(mRequests.get(requestId), + failure)); } finally { Binder.restoreCallingIdentity(ident); } @@ -534,14 +542,9 @@ public final class RequestProcessor { if (mRequests.get(requestId) != null) { final long ident = Binder.clearCallingIdentity(); try { - if (mExecutor != null) { - mExecutor.execute( - () -> mCallback.onCaptureBufferLost(mRequests.get(requestId), - frameNumber, outputStreamId)); - } else { - mCallback.onCaptureBufferLost(mRequests.get(requestId), frameNumber, - outputStreamId); - } + mExecutor.execute( + () -> mCallback.onCaptureBufferLost(mRequests.get(requestId), + frameNumber, outputStreamId)); } finally { Binder.restoreCallingIdentity(ident); } @@ -554,12 +557,8 @@ public final class RequestProcessor { public void onCaptureSequenceCompleted(int sequenceId, long frameNumber) { final long ident = Binder.clearCallingIdentity(); try { - if (mExecutor != null) { - mExecutor.execute(() -> mCallback.onCaptureSequenceCompleted(sequenceId, - frameNumber)); - } else { - mCallback.onCaptureSequenceCompleted(sequenceId, frameNumber); - } + mExecutor.execute(() -> mCallback.onCaptureSequenceCompleted(sequenceId, + frameNumber)); } finally { Binder.restoreCallingIdentity(ident); } @@ -569,11 +568,7 @@ public final class RequestProcessor { public void onCaptureSequenceAborted(int sequenceId) { final long ident = Binder.clearCallingIdentity(); try { - if (mExecutor != null) { - mExecutor.execute(() -> mCallback.onCaptureSequenceAborted(sequenceId)); - } else { - mCallback.onCaptureSequenceAborted(sequenceId); - } + mExecutor.execute(() -> mCallback.onCaptureSequenceAborted(sequenceId)); } finally { Binder.restoreCallingIdentity(ident); } diff --git a/core/java/android/hardware/camera2/extension/SessionProcessor.java b/core/java/android/hardware/camera2/extension/SessionProcessor.java index 9c5136bcf903..e7cc5303fc18 100644 --- a/core/java/android/hardware/camera2/extension/SessionProcessor.java +++ b/core/java/android/hardware/camera2/extension/SessionProcessor.java @@ -18,13 +18,15 @@ package android.hardware.camera2.extension; import android.annotation.FlaggedApi; import android.annotation.NonNull; -import android.annotation.Nullable; import android.annotation.SystemApi; import android.hardware.camera2.CameraCharacteristics; import android.hardware.camera2.CaptureRequest; import android.hardware.camera2.CaptureResult; +import android.hardware.camera2.impl.CameraExtensionUtils.HandlerExecutor; import android.hardware.camera2.impl.CameraMetadataNative; +import android.os.Handler; import android.os.IBinder; +import android.os.Looper; import android.os.RemoteException; import android.util.Log; @@ -60,7 +62,7 @@ import java.util.concurrent.Executor; * to the repeating request and single requests but the implementation can * choose to apply some of them only. * - * (5) {@link #startCapture}: It is called when apps want + * (5) {@link #startMultiFrameCapture}: It is called when apps want * to start a multi-frame image capture. {@link CaptureCallback} will be * called to report the status and the output image will be written to the * capture output surface specified in {@link #initSession}. @@ -78,8 +80,11 @@ public abstract class SessionProcessor { private static final String TAG = "SessionProcessor"; private CameraUsageTracker mCameraUsageTracker; + /** + * Initialize a session process instance + */ @FlaggedApi(Flags.FLAG_CONCERT_MODE) - protected SessionProcessor() {} + public SessionProcessor() {} void setCameraUsageTracker(CameraUsageTracker tracker) { mCameraUsageTracker = tracker; @@ -87,7 +92,7 @@ public abstract class SessionProcessor { /** * Callback for notifying the status of {@link - * #startCapture} and {@link #startRepeating}. + * #startMultiFrameCapture} and {@link #startRepeating}. * @hide */ @SystemApi @@ -175,7 +180,7 @@ public abstract class SessionProcessor { * @param requestId the capture request id that generated the * capture results. This is the return value of * either {@link #startRepeating} or {@link - * #startCapture}. + * #startMultiFrameCapture}. * @param results The supported capture results. Do note * that if results 'android.jpeg.quality' and * android.jpeg.orientation' are present in the @@ -252,7 +257,14 @@ public abstract class SessionProcessor { * until onCaptureSessionEnd is called. * @param requestProcessor The request processor to be used for * managing capture requests - * @param statsKey Unique key for telemetry + * @param statsKey Unique key that is associated with the + * current Camera2 session and used by the + * framework telemetry. The id can be referenced + * by the extension, in case there is additional + * extension specific telemetry that needs + * to be linked to the regular capture session. + * + * */ @FlaggedApi(Flags.FLAG_CONCERT_MODE) public abstract void onCaptureSessionStart(@NonNull RequestProcessor requestProcessor, @@ -275,13 +287,12 @@ public abstract class SessionProcessor { * repeating request when needed later. * * @param executor the executor which will be used for - * invoking the callbacks or null to use the - * current thread's looper + * invoking the callbacks * @param callback a callback to report the status. * @return the id of the capture sequence. */ @FlaggedApi(Flags.FLAG_CONCERT_MODE) - public abstract int startRepeating(@Nullable Executor executor, + public abstract int startRepeating(@NonNull Executor executor, @NonNull CaptureCallback callback); /** @@ -309,13 +320,12 @@ public abstract class SessionProcessor { * immediately. * * @param executor the executor which will be used for - * invoking the callbacks or null to use the - * current thread's looper + * invoking the callbacks * @param callback a callback to report the status. * @return the id of the capture sequence. */ @FlaggedApi(Flags.FLAG_CONCERT_MODE) - public abstract int startCapture(@Nullable Executor executor, + public abstract int startMultiFrameCapture(@NonNull Executor executor, @NonNull CaptureCallback callback); /** @@ -340,15 +350,14 @@ public abstract class SessionProcessor { * @param captureRequest Capture request that includes the respective * triggers. * @param executor the executor which will be used for - * invoking the callbacks or null to use the - * current thread's looper + * invoking the callbacks * @param callback a callback to report the status. * @return the id of the capture sequence. * */ @FlaggedApi(Flags.FLAG_CONCERT_MODE) public abstract int startTrigger(@NonNull CaptureRequest captureRequest, - @Nullable Executor executor, @NonNull CaptureCallback callback); + @NonNull Executor executor, @NonNull CaptureCallback callback); private final class SessionProcessorImpl extends ISessionProcessorImpl.Stub { private long mVendorId = -1; @@ -401,7 +410,8 @@ public abstract class SessionProcessor { @Override public int startRepeating(ICaptureCallback callback) throws RemoteException { - return SessionProcessor.this.startRepeating(/*executor*/ null, + return SessionProcessor.this.startRepeating( + new HandlerExecutor(new Handler(Looper.getMainLooper())), new CaptureCallbackImpl(callback)); } @@ -413,7 +423,8 @@ public abstract class SessionProcessor { @Override public int startCapture(ICaptureCallback callback, boolean isPostviewRequested) throws RemoteException { - return SessionProcessor.this.startCapture(/*executor*/ null, + return SessionProcessor.this.startMultiFrameCapture( + new HandlerExecutor(new Handler(Looper.getMainLooper())), new CaptureCallbackImpl(callback)); } @@ -425,7 +436,8 @@ public abstract class SessionProcessor { @Override public int startTrigger(CaptureRequest captureRequest, ICaptureCallback callback) throws RemoteException { - return SessionProcessor.this.startTrigger(captureRequest, /*executor*/ null, + return SessionProcessor.this.startTrigger(captureRequest, + new HandlerExecutor(new Handler(Looper.getMainLooper())), new CaptureCallbackImpl(callback)); } |