/* * Copyright (C) 2013 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 android.hardware.camera2; import android.view.Surface; import java.lang.AutoCloseable; import java.util.List; /** *

The CameraDevice class is an interface to a single camera connected to an * Android device, allowing for fine-grain control of image capture and * post-processing at high frame rates.

* *

Your application must declare the * {@link android.Manifest.permission#CAMERA Camera} permission in its manifest * in order to access camera devices.

* *

A given camera device may provide support at one of two levels: limited or * full. If a device only supports the limited level, then Camera2 exposes a * feature set that is roughly equivalent to the older * {@link android.hardware.Camera Camera} API, although with a cleaner and more * efficient interface. Devices that implement the full level of support * provide substantially improved capabilities over the older camera * API. Applications that target the limited level devices will run unchanged on * the full-level devices; if your application requires a full-level device for * proper operation, declare the "android.hardware.camera2.full" feature in your * manifest.

* * @see CameraManager#openCamera * @see android.Manifest.permission#CAMERA */ public interface CameraDevice extends AutoCloseable { /** * Create a request suitable for a camera preview window. Specifically, this * means that high frame rate is given priority over the highest-quality * post-processing. These requests would normally be used with the * {@link #setRepeatingRequest} method. * * @see #createCaptureRequest */ public static final int TEMPLATE_PREVIEW = 1; /** * Create a request suitable for still image capture. Specifically, this * means prioritizing image quality over frame rate. These requests would * commonly be used with the {@link #capture} method. * * @see #createCaptureRequest */ public static final int TEMPLATE_STILL_CAPTURE = 2; /** * Create a request suitable for video recording. Specifically, this means * that a stable frame rate is used, and post-processing is set for * recording quality. These requests would commonly be used with the * {@link #setRepeatingRequest} method. * * @see #createCaptureRequest */ public static final int TEMPLATE_RECORD = 3; /** * Create a request suitable for still image capture while recording * video. Specifically, this means maximizing image quality without * disrupting the ongoing recording. These requests would commonly be used * with the {@link #capture} method while a request based on * {@link #TEMPLATE_RECORD} is is in use with {@link #setRepeatingRequest}. * * @see #createCaptureRequest */ public static final int TEMPLATE_VIDEO_SNAPSHOT = 4; /** * A basic template for direct application control of capture * parameters. All automatic control is disabled (auto-exposure, auto-white * balance, auto-focus), and post-processing parameters are set to preview * quality. The manual capture parameters (exposure, sensitivity, and so on) * are set to reasonable defaults, but should be overriden by the * application depending on the intended use case. * * @see #createCaptureRequest */ public static final int TEMPLATE_MANUAL = 5; /** * Get the static properties for this camera. These are identical to the * properties returned by {@link CameraManager#getCameraProperties}. * * @return the static properties of the camera. * * @throws CameraAccessException if the camera device is no longer connected * * @see CameraManager#getCameraProperties */ public CameraProperties getProperties() throws CameraAccessException; /** *

Set up a new output set of Surfaces for the camera device.

* *

The configuration determines the set of potential output Surfaces for * the camera device for each capture request. A given request may use all * or a only some of the outputs. This method must be called before requests * can be submitted to the camera with {@link #capture capture}, * {@link #captureBurst captureBurst}, * {@link #setRepeatingRequest setRepeatingRequest}, or * {@link #setRepeatingBurst setRepeatingBurst}.

* *

Surfaces suitable for inclusion as a camera output can be created for * various use cases and targets:

* * * *

* *

This function can take several hundred milliseconds to execute, since * camera hardware may need to be powered on or reconfigured.

* *

The camera device will query each Surface's size and formats upon this * call, so they must be set to a valid setting at this time (in particular: * if the format is user-visible, it must be one of android.scaler.availableFormats; * and the size must be one of android.scaler.available[Processed|Jpeg]Sizes).

* *

To change the configuration after requests have been submitted to the * device, the camera device must be idle. To idle the device, stop any * repeating requests with {@link #stopRepeating stopRepeating}, and then * call {@link #waitUntilIdle waitUntilIdle}.

* *

Using larger resolution outputs, or more outputs, can result in slower * output rate from the device.

* * @param outputs the new set of Surfaces that should be made available as * targets for captured image data. * * @throws IllegalArgumentException if the set of output Surfaces do not * meet the requirements * @throws CameraAccessException if the camera device is no longer connected * @throws IllegalStateException if the camera device is not idle, or has * encountered a fatal error */ public void configureOutputs(List outputs) throws CameraAccessException; /** *

Create a {@link CaptureRequest} initialized with template for a target * use case. The settings are chosen to be the best options for the specific * camera device, so it is not recommended to reuse the same request for a * different camera device; create a request for that device and override * the settings as desired, instead.

* * @param templateType An enumeration selecting the use case for this * request; one of the CameraDevice.TEMPLATE_ values. * @return a filled-in CaptureRequest, except for output streams. * * @throws IllegalArgumentException if the templateType is not in the list * of supported templates. * @throws CameraAccessException if the camera device is no longer connected * @throws IllegalStateException if the camera device has been closed or the * device has encountered a fatal error. * * @see #TEMPLATE_PREVIEW * @see #TEMPLATE_RECORD * @see #TEMPLATE_STILL_CAPTURE * @see #TEMPLATE_VIDEO_SNAPSHOT * @see #TEMPLATE_MANUAL */ public CaptureRequest createCaptureRequest(int templateType) throws CameraAccessException; /** *

Submit a request for an image to be captured by this CameraDevice.

* *

The request defines all the parameters for capturing the single image, * including sensor, lens, flash, and post-processing settings.

* *

Each request will produce one {@link CaptureResult} and produce new * frames for one or more target Surfaces, as defined by the request's .

* *

Multiple requests can be in progress at once. They are processed in * first-in, first-out order, with minimal delays between each * capture. Requests submitted through this method have higher priority than * those submitted through {@link #setRepeatingRequest} or * {@link #setRepeatingBurst}, and will be processed as soon as the current * repeat/repeatBurst processing completes.

* * @param request the settings for this capture. * @param listener the callback object to notify once this request has been * processed. If null, no metadata will be produced for this capture, * although image data will still be produced. * * @throws CameraAccessException if the camera device is no longer connected * @throws IllegalStateException if the camera device has been closed or the * device has encountered a fatal error. * * @see #captureBurst * @see #setRepeatingRequest * @see #setRepeatingBurst */ public void capture(CaptureRequest request, CaptureListener listener) throws CameraAccessException; /** *

Submit a list of requests to be captured in sequence as a burst. The * burst will be captured in the minimum amount of time possible, and will * not be interleaved with requests submitted by other capture or repeat * calls.

* *

The requests will be captured in order, each capture producing one * {@link CaptureResult} and frames for one or more * target {@link android.view.Surface surfaces}.

* *

The main difference between this method and simply calling * {@link #capture} repeatedly is that this method guarantees that no * other requests will be interspersed with the burst.

* * @param requests the list of settings for this burst capture. * @param listener the callback object to notify each time one of the * requests in the burst has been processed. If null, no metadata will be * produced for any requests in this burst, although image data will still * be produced. * * @throws CameraAccessException if the camera device is no longer connected * @throws IllegalStateException if the camera device has been closed or the * device has encountered a fatal error. * * @see #capture * @see #setRepeatingRequest * @see #setRepeatingBurst */ public void captureBurst(List requests, CaptureListener listener) throws CameraAccessException; /** *

Request endlessly repeating capture of images by this * CameraDevice.

* *

With this method, the CameraDevice will continually capture * images using the settings in the provided {@link * CaptureRequest}, at the maximum rate possible.

* *

Repeat requests have lower priority than those submitted * through {@link #capture} or {@link #captureBurst}, so if * capture() is called when a repeating request is active, the * capture request will be processed before any further repeating * requests are processed.

* *

Repeating requests are a simple way for an application to maintain a * preview or other continuous stream of frames, without having to submit * requests through {@link #capture} at video rates.

* *

To stop the repeating capture, call {@link #stopRepeating}

* *

Calling repeat will replace a burst set up by {@link * #setRepeatingBurst}, although any in-progress burst will be * completed before the new repeat request will be used.

* * @param request the request to repeat indefinitely * @param listener the callback object to notify every time the * request finishes processing. If null, no metadata will be * produced for this stream of requests, although image data will * still be produced. * * @throws CameraAccessException if the camera device is no longer * connected * @throws IllegalStateException if the camera device has been closed or the * device has encountered a fatal error. * * @see #capture * @see #captureBurst * @see #setRepeatingBurst */ public void setRepeatingRequest(CaptureRequest request, CaptureListener listener) throws CameraAccessException; /** *

Request endlessly repeating capture of a sequence of images by this * CameraDevice.

* *

With this method, the CameraDevice will continually capture images, * cycling through the settings in the provided list of * {@link CaptureRequest CaptureRequests}, at the maximum rate possible.

* *

If a request is submitted through {@link #capture} or * {@link #captureBurst}, the current repetition of the request list will be * completed before the higher-priority request is handled. This guarantees * that the application always receives a complete repeat burst captured in * minimal time, instead of bursts interleaved with higher-priority * captures, or incomplete captures.

* *

Repeating burst requests are a simple way for an application to * maintain a preview or other continuous stream of frames where each * request is different in a predicatable way, without having to submit * requests through {@link #capture} at video rates.

* *

To stop the repeating capture, call {@link #stopRepeating}. Any * ongoing burst will still be completed, however.

* *

Calling repeatBurst will replace a repeating request set up by * {@link #setRepeatingRequest}, although any in-progress capture will be completed * before the new repeat burst will be used.

* * @param requests the list of requests to cycle through indefinitely. * @param listener the callback object to notify each time one of the * requests in the repeating bursts has finished processing. If null, no * metadata will be produced for this stream of requests, although image * data will still be produced. * * @throws CameraAccessException if the camera device is no longer connected * @throws IllegalStateException if the camera device has been closed or the * device has encountered a fatal error. * * @see #capture * @see #captureBurst * @see #setRepeatingRequest */ public void setRepeatingBurst(List requests, CaptureListener listener) throws CameraAccessException; /** *

Cancel any ongoing repeating capture set by either * {@link #setRepeatingRequest setRepeatingRequest} or * {@link #setRepeatingBurst}. Has no effect on requests submitted through * {@link #capture capture} or {@link #captureBurst captureBurst}.

* *

Any currently in-flight captures will still complete, as will any * burst that is mid-capture. To ensure that the device has finished * processing all of its capture requests and is in idle state, use the * {@link #waitUntilIdle waitUntilIdle} method.

* * @throws CameraAccessException if the camera device is no longer connected * @throws IllegalStateException if the camera device has been closed or the * device has encountered a fatal error. * * @see #setRepeatingRequest * @see #setRepeatingBurst * @see #waitUntilIdle * * @throws CameraAccessException if the camera device is no longer connected * @throws IllegalStateException if the camera device has been closed, the * device has encountered a fatal error, or if there is an active repeating * request or burst. */ public void stopRepeating() throws CameraAccessException; /** *

Wait until all the submitted requests have finished processing

* *

This method blocks until all the requests that have been submitted to * the camera device, either through {@link #capture capture}, * {@link #captureBurst captureBurst}, * {@link #setRepeatingRequest setRepeatingRequest}, or * {@link #setRepeatingBurst setRepeatingBurst}, have completed their * processing.

* *

Once this call returns successfully, the device is in an idle state, * and can be reconfigured with {@link #configureOutputs configureOutputs}.

* *

This method cannot be used if there is an active repeating request or * burst, set with {@link #setRepeatingRequest setRepeatingRequest} or * {@link #setRepeatingBurst setRepeatingBurst}. Call * {@link #stopRepeating stopRepeating} before calling this method.

* * @throws CameraAccessException if the camera device is no longer connected * @throws IllegalStateException if the camera device has been closed, the * device has encountered a fatal error, or if there is an active repeating * request or burst. */ public void waitUntilIdle() throws CameraAccessException; /** * Set the error listener object to call when an asynchronous error * occurs. The errors reported here are only device-wide errors; errors * about individual requests or frames are reported through * {@link CaptureListener#onCaptureFailed}. * * @param listener the ErrorListener to send asynchronous error * notifications to. Setting this to null will stop notifications about * asynchronous errors. */ public void setErrorListener(ErrorListener listener); /** * Close the connection to this camera device. After this call, all calls to * the camera device interface will throw a {@link IllegalStateException}, * except for calls to close(). * @throws Exception */ @Override public void close() throws Exception; // TODO: We should decide on the behavior of in-flight requests should be on close. /** * A listener for receiving metadata about completed image captures. The * metadata includes, among other things, the final capture settings and the * state of the control algorithms. */ public interface CaptureListener { /** *

Called when a capture request has been processed by a * {@link CameraDevice}.

* * @param camera The CameraDevice sending the callback. * @param request The request that was given to the CameraDevice * @param result The output metadata from the capture, including the * final capture parameters and the state of the camera system during * capture. * * @see #capture * @see #captureBurst * @see #setRepeatingRequest * @see #setRepeatingBurst */ public void onCaptureComplete(CameraDevice camera, CaptureRequest request, CaptureResult result); /** *

Called instead of onCaptureComplete when the camera device failed * to produce a CaptureResult for the request. Other requests are * unaffected, and some or all image buffers from the capture may have * been pushed to their respective output streams.

* * @param camera The CameraDevice sending the callback. * @param request The request that was given to the CameraDevice * * @see #capture * @see #captureBurst * @see #setRepeatingRequest * @see #setRepeatingBurst */ public void onCaptureFailed(CameraDevice camera, CaptureRequest request); } /** *

A listener for asynchronous errors from the camera device. Errors * about specific {@link CaptureRequest CaptureRequests} are sent through * the capture {@link CaptureListener#onCaptureFailed listener} * interface. Errors reported through this listener affect the device as a * whole.

*/ public interface ErrorListener { /** *

This camera device has been disconnected by the camera * service. Any attempt to call methods on this CameraDevice will throw * a {@link CameraAccessException}. The disconnection could be due to a * change in security policy or permissions; the physical disconnection * of a removable camera device; or the camera being needed for a * higher-priority use case.

* *

There may still be capture completion or camera stream listeners * that will be called after this error is received.

*/ public static final int DEVICE_DISCONNECTED = 1; /** *

The camera device has encountered a fatal error. Any attempt to * call methods on this CameraDevice will throw a * {@link java.lang.IllegalStateException}.

* *

There may still be capture completion or camera stream listeners * that will be called after this error is received.

* *

The application needs to re-open the camera device to use it * again.

*/ public static final int DEVICE_ERROR = 2; /** *

The camera service has encountered a fatal error. Any attempt to * call methods on this CameraDevice in the future will throw a * {@link java.lang.IllegalStateException}.

* *

There may still be capture completion or camera stream listeners * that will be called after this error is received.

* *

The device may need to be shut down and restarted to restore * camera function, or there may be a persistent hardware problem.

*/ public static final int SERVICE_ERROR = 3; /** * The method to call when a camera device has encountered an error. * * @param camera The device reporting the error * @param error The error code, one of the ErrorListener.ERROR_ values. */ public void onCameraDeviceError(CameraDevice camera, int error); } }