Initial commit of new camera API, mostly just the interface.
- New core API classes in android.hardware.photography
- android.media.Image and android.media.ImageReader classes for
application access to direct hardware image buffers.
- Additions to android.graphics.ImageFormat to describe new image
types needed by new camera API.
- Some documentation included; very little implementation.
Bug: 9111736
Change-Id: I0680f35944d1cb8845b7dc0c67edc8c0f0864573
diff --git a/api/current.txt b/api/current.txt
index 87891b51..3337837 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5735,6 +5735,7 @@
field public static final int BIND_NOT_FOREGROUND = 4; // 0x4
field public static final int BIND_WAIVE_PRIORITY = 32; // 0x20
field public static final java.lang.String BLUETOOTH_SERVICE = "bluetooth";
+ field public static final java.lang.String CAMERA_SERVICE = "camera";
field public static final java.lang.String CLIPBOARD_SERVICE = "clipboard";
field public static final java.lang.String CONNECTIVITY_SERVICE = "connectivity";
field public static final int CONTEXT_IGNORE_SECURITY = 2; // 0x2
@@ -9002,8 +9003,10 @@
field public static final int JPEG = 256; // 0x100
field public static final int NV16 = 16; // 0x10
field public static final int NV21 = 17; // 0x11
+ field public static final int RAW_SENSOR = 513; // 0x201
field public static final int RGB_565 = 4; // 0x4
field public static final int UNKNOWN = 0; // 0x0
+ field public static final int YUV_420_888 = 35; // 0x23
field public static final int YUY2 = 20; // 0x14
field public static final int YV12 = 842094169; // 0x32315659
}
@@ -10626,6 +10629,133 @@
}
+package android.hardware.photography {
+
+ public class CameraAccessException extends java.lang.Exception {
+ ctor public CameraAccessException(int);
+ ctor public CameraAccessException(int, java.lang.String);
+ ctor public CameraAccessException(int, java.lang.String, java.lang.Throwable);
+ ctor public CameraAccessException(int, java.lang.Throwable);
+ method public final int getReason();
+ field public static final int CAMERA_DISABLED = 3; // 0x3
+ field public static final int CAMERA_DISCONNECTED = 4; // 0x4
+ field public static final int CAMERA_IN_USE = 1; // 0x1
+ field public static final int MAX_CAMERAS_IN_USE = 2; // 0x2
+ }
+
+ public final class CameraDevice implements java.lang.AutoCloseable {
+ ctor public CameraDevice();
+ method public void capture(android.hardware.photography.CaptureRequest, android.hardware.photography.CameraDevice.CaptureListener) throws android.hardware.photography.CameraAccessException;
+ method public void captureBurst(java.util.List<android.hardware.photography.CaptureRequest>, android.hardware.photography.CameraDevice.CaptureListener) throws android.hardware.photography.CameraAccessException;
+ method public void close();
+ method public void configureOutputs(java.util.List<android.view.Surface>);
+ method public android.hardware.photography.CaptureRequest createCaptureRequest(int) throws android.hardware.photography.CameraAccessException;
+ method public android.hardware.photography.CameraProperties getProperties() throws android.hardware.photography.CameraAccessException;
+ method public void setErrorListener(android.hardware.photography.CameraDevice.ErrorListener);
+ method public void setRepeatingBurst(java.util.List<android.hardware.photography.CaptureRequest>, android.hardware.photography.CameraDevice.CaptureListener) throws android.hardware.photography.CameraAccessException;
+ method public void setRepeatingRequest(android.hardware.photography.CaptureRequest, android.hardware.photography.CameraDevice.CaptureListener) throws android.hardware.photography.CameraAccessException;
+ method public void stopRepeating() throws android.hardware.photography.CameraAccessException;
+ method public void waitUntilIdle() throws android.hardware.photography.CameraAccessException;
+ field public static final int TEMPLATE_MANUAL = 5; // 0x5
+ field public static final int TEMPLATE_PREVIEW = 1; // 0x1
+ field public static final int TEMPLATE_RECORD = 2; // 0x2
+ field public static final int TEMPLATE_STILL_CAPTURE = 3; // 0x3
+ field public static final int TEMPLATE_VIDEO_SNAPSHOT = 4; // 0x4
+ }
+
+ public static abstract interface CameraDevice.CaptureListener {
+ method public abstract void onCaptureComplete(android.hardware.photography.CameraDevice, android.hardware.photography.CaptureRequest, android.hardware.photography.CaptureResult);
+ method public abstract void onCaptureFailed(android.hardware.photography.CameraDevice, android.hardware.photography.CaptureRequest);
+ }
+
+ public static abstract interface CameraDevice.ErrorListener {
+ method public abstract void onCameraDeviceError(android.hardware.photography.CameraDevice, int);
+ field public static final int DEVICE_DISCONNECTED = 1; // 0x1
+ field public static final int DEVICE_ERROR = 2; // 0x2
+ field public static final int SERVICE_ERROR = 3; // 0x3
+ }
+
+ public final class CameraManager {
+ method public android.hardware.photography.CameraProperties getCameraProperties(java.lang.String) throws android.hardware.photography.CameraAccessException;
+ method public java.lang.String[] getDeviceIdList();
+ method public android.hardware.photography.CameraDevice openCamera(java.lang.String) throws android.hardware.photography.CameraAccessException;
+ method public void registerCameraListener(android.hardware.photography.CameraManager.CameraListener);
+ method public void unregisterCameraListener(android.hardware.photography.CameraManager.CameraListener);
+ }
+
+ public static abstract interface CameraManager.CameraListener {
+ method public abstract void onCameraAvailable(java.lang.String);
+ method public abstract void onCameraUnavailable(java.lang.String);
+ }
+
+ public class CameraMetadata implements android.os.Parcelable {
+ ctor public CameraMetadata();
+ method public int describeContents();
+ method public T get(android.hardware.photography.CameraMetadata.Key<T>);
+ method public void set(android.hardware.photography.CameraMetadata.Key<T>, T);
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator CREATOR;
+ }
+
+ public static class CameraMetadata.Key {
+ ctor public CameraMetadata.Key(java.lang.String);
+ method public final boolean equals(java.lang.Object);
+ method public final java.lang.String getName();
+ method public final int hashCode();
+ }
+
+ public final class CameraProperties extends android.hardware.photography.CameraMetadata {
+ ctor public CameraProperties();
+ field public static final android.hardware.photography.CameraMetadata.Key INFO_IDENTIFIER;
+ field public static final android.hardware.photography.CameraMetadata.Key INFO_MODEL;
+ field public static final android.hardware.photography.CameraMetadata.Key INFO_REMOVABLE;
+ field public static final android.hardware.photography.CameraMetadata.Key INFO_SUPPORTED_HARDWARE_LEVEL;
+ field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_FULL = 1; // 0x1
+ field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED = 0; // 0x0
+ field public static final android.hardware.photography.CameraMetadata.Key SCALER_AVAILABLE_FORMATS;
+ field public static final android.hardware.photography.CameraMetadata.Key SCALER_AVAILABLE_JPEG_SIZES;
+ field public static final android.hardware.photography.CameraMetadata.Key SCALER_AVAILABLE_PROCESSED_SIZES;
+ field public static final android.hardware.photography.CameraMetadata.Key SCALER_AVAILABLE_RAW_SIZES;
+ field public static final android.hardware.photography.CameraMetadata.Key SENSOR_ACTIVE_ARRAY_SIZE;
+ field public static final android.hardware.photography.CameraMetadata.Key SENSOR_PIXEL_ARRAY_SIZE;
+ }
+
+ public final class CaptureRequest extends android.hardware.photography.CameraMetadata {
+ method public void addTarget(android.view.Surface);
+ method public void removeTarget(android.view.Surface);
+ field public static final android.hardware.photography.CameraMetadata.Key SENSOR_EXPOSURE_TIME;
+ field public static final android.hardware.photography.CameraMetadata.Key SENSOR_SENSITIVITY;
+ }
+
+ public final class CaptureResult extends android.hardware.photography.CameraMetadata {
+ field public static final android.hardware.photography.CameraMetadata.Key CONTROL_AE_STATE;
+ field public static final int CONTROL_AE_STATE_CONVERGED = 2; // 0x2
+ field public static final int CONTROL_AE_STATE_FLASH_REQUIRED = 4; // 0x4
+ field public static final int CONTROL_AE_STATE_INACTIVE = 0; // 0x0
+ field public static final int CONTROL_AE_STATE_LOCKED = 3; // 0x3
+ field public static final int CONTROL_AE_STATE_PRECAPTURE = 5; // 0x5
+ field public static final int CONTROL_AE_STATE_SEARCHING = 1; // 0x1
+ field public static final android.hardware.photography.CameraMetadata.Key SENSOR_TIMESTAMP;
+ field public static final android.hardware.photography.CameraMetadata.Key STATISTICS_DETECTED_FACES;
+ }
+
+ public static class CaptureResult.Face {
+ ctor public CaptureResult.Face();
+ method public android.graphics.Rect getBounds();
+ method public int getId();
+ method public android.graphics.Point getLeftEye();
+ method public android.graphics.Point getMouth();
+ method public android.graphics.Point getRightEye();
+ method public int getScore();
+ }
+
+ public final class Size {
+ method public final int getHeight();
+ method public final int getWidth();
+ }
+
+}
+
package android.hardware.usb {
public class UsbAccessory implements android.os.Parcelable {
@@ -11662,6 +11792,40 @@
field public static final int EULER_Z = 2; // 0x2
}
+ public abstract class Image implements java.lang.AutoCloseable {
+ ctor public Image();
+ method public abstract void close();
+ method protected final void finalize();
+ method public int getFormat();
+ method public int getHeight();
+ method public android.media.Image.Plane[] getPlanes();
+ method public long getTimestamp();
+ method public int getWidth();
+ }
+
+ public static final class Image.Plane {
+ ctor public Image.Plane();
+ method public java.nio.ByteBuffer getBuffer();
+ method public int getPixelStride();
+ method public int getRowStride();
+ }
+
+ public final class ImageReader {
+ ctor public ImageReader(int, int, int, int);
+ method public int getHeight();
+ method public int getImageFormat();
+ method public int getMaxImages();
+ method public android.media.Image getNextImage();
+ method public android.view.Surface getSurface();
+ method public int getWidth();
+ method public void releaseImage(android.media.Image);
+ method public void setOnImageAvailableListener(android.media.ImageReader.OnImageAvailableListener);
+ }
+
+ public static abstract interface ImageReader.OnImageAvailableListener {
+ method public abstract void onImageAvailable(android.media.ImageReader);
+ }
+
public class JetPlayer {
method public boolean clearQueue();
method public java.lang.Object clone() throws java.lang.CloneNotSupportedException;
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 459139f..7968431 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -49,6 +49,7 @@
import android.hardware.ISerialManager;
import android.hardware.SerialManager;
import android.hardware.SystemSensorManager;
+import android.hardware.photography.CameraManager;
import android.hardware.display.DisplayManager;
import android.hardware.input.InputManager;
import android.hardware.usb.IUsbManager;
@@ -540,6 +541,11 @@
IAppOpsService service = IAppOpsService.Stub.asInterface(b);
return new AppOpsManager(ctx, service);
}});
+
+ registerService(CAMERA_SERVICE, new StaticServiceFetcher() {
+ public Object createStaticService() {
+ return new CameraManager();
+ }});
}
static ContextImpl getImpl(Context context) {
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 81d6f0b..35e51a6 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2284,6 +2284,16 @@
public static final String APP_OPS_SERVICE = "appops";
/**
+ * Use with {@link #getSystemService} to retrieve a
+ * {@link android.hardware.photography.CameraManager} for interacting with
+ * camera devices.
+ *
+ * @see #getSystemService
+ * @see android.hardware.camera.CameraManager
+ */
+ public static final String CAMERA_SERVICE = "camera";
+
+ /**
* Determine whether the given permission is allowed for a particular
* process and user ID running in the system.
*
diff --git a/core/java/android/hardware/photography/CameraAccessException.java b/core/java/android/hardware/photography/CameraAccessException.java
new file mode 100644
index 0000000..01114df
--- /dev/null
+++ b/core/java/android/hardware/photography/CameraAccessException.java
@@ -0,0 +1,86 @@
+/*
+ * 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.photography;
+
+/**
+ * <p><code>CameraAccessException</code> is thrown if a camera device could not
+ * be queried or opened by the {@link CameraManager}, or if the connection to an
+ * opened {@link CameraDevice} is no longer valid.</p>
+ *
+ * @see CameraManager
+ * @see CameraDevice
+ */
+public class CameraAccessException extends Exception {
+ /**
+ * The camera device is in use already
+ */
+ public static final int CAMERA_IN_USE = 1;
+
+ /**
+ * The system-wide limit for number of open cameras has been reached,
+ * and more camera devices cannot be opened until previous instances are
+ * closed.
+ */
+ public static final int MAX_CAMERAS_IN_USE = 2;
+
+ /**
+ * The camera is disabled due to a device policy, and cannot be opened.
+ *
+ * @see android.app.admin.DevicePolicyManager#setCameraDisabled(android.content.ComponentName, boolean)
+ */
+ public static final int CAMERA_DISABLED = 3;
+
+ /**
+ * The camera device is removable and has been disconnected from the Android
+ * device, or the camera service has shut down the connection due to a
+ * higher-priority access request for the camera device.
+ */
+ public static final int CAMERA_DISCONNECTED = 4;
+
+ private int mReason;
+
+ /**
+ * The reason for the failure to access the camera.
+ *
+ * @see #CAMERA_IN_USE
+ * @see #MAX_CAMERAS_IN_USE
+ * @see #CAMERA_DISABLED
+ * @see #CAMERA_DISCONNECTED
+ */
+ public final int getReason() {
+ return mReason;
+ }
+
+ public CameraAccessException(int problem) {
+ mReason = problem;
+ }
+
+ public CameraAccessException(int problem, String message) {
+ super(message);
+ mReason = problem;
+ }
+
+ public CameraAccessException(int problem, String message, Throwable cause) {
+ super(message, cause);
+ mReason = problem;
+ }
+
+ public CameraAccessException(int problem, Throwable cause) {
+ super(cause);
+ mReason = problem;
+ }
+}
diff --git a/core/java/android/hardware/photography/CameraDevice.java b/core/java/android/hardware/photography/CameraDevice.java
new file mode 100644
index 0000000..2062db2
--- /dev/null
+++ b/core/java/android/hardware/photography/CameraDevice.java
@@ -0,0 +1,555 @@
+/*
+ * 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.photography;
+
+import android.graphics.ImageFormat;
+import android.renderscript.Allocation;
+import android.renderscript.RenderScript;
+import android.view.Surface;
+
+import java.lang.AutoCloseable;
+import java.util.List;
+
+/**
+ * <p>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.</p>
+ *
+ * <p>Your application must declare the
+ * {@link android.Manifest.permission#CAMERA Camera} permission in its manifest
+ * in order to access camera devices.</p>
+ *
+ * <p>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.</p>
+ *
+ * @see CameraManager#openCamera
+ * @see android.Manifest.permission#CAMERA
+ */
+public final class CameraDevice implements 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 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 = 2;
+
+ /**
+ * 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 = 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 {
+ return null;
+ }
+
+ /**
+ * <p>Set up a new output set of Surfaces for the camera device.</p>
+ *
+ * <p>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}.</p>
+ *
+ * <p>Surfaces suitable for inclusion as a camera output can be created for
+ * various use cases and targets:</p>
+ *
+ * <ul>
+ *
+ * <li>For drawing to a {@link android.view.SurfaceView SurfaceView}: Set
+ * the size of the Surface with
+ * {@link android.view.SurfaceHolder#setFixedSize} to be one of the
+ * supported
+ * {@link CameraProperties#SCALER_AVAILABLE_PROCESSED_SIZES processed sizes}
+ * before calling {@link android.view.SurfaceHolder#getSurface}.</li>
+ *
+ * <li>For accessing through an OpenGL texture via a
+ * {@link android.graphics.SurfaceTexture SurfaceTexture}: Set the size of
+ * the SurfaceTexture with
+ * {@link android.graphics.SurfaceTexture#setDefaultBufferSize} to be one
+ * of the supported
+ * {@link CameraProperties#SCALER_AVAILABLE_PROCESSED_SIZES processed sizes}
+ * before creating a Surface from the SurfaceTexture with
+ * {@link Surface#Surface}.</li>
+ *
+ * <li>For recording with {@link android.media.MediaCodec}: Call
+ * {@link android.media.MediaCodec#createInputSurface} after configuring
+ * the media codec to use one of the
+ * {@link CameraProperties#SCALER_AVAILABLE_PROCESSED_SIZES processed sizes}
+ * </li>
+ *
+ * <li>For recording with {@link android.media.MediaRecorder}: TODO</li>
+ *
+ * <li>For efficient YUV processing with {@link android.renderscript}:
+ * Create a RenderScript
+ * {@link android.renderscript.Allocation Allocation} with a supported YUV
+ * type, the IO_INPUT flag, and one of the supported
+ * {@link CameraProperties#SCALER_AVAILABLE_PROCESSED_SIZES processed sizes}. Then
+ * obtain the Surface with
+ * {@link android.renderscript.Allocation#getSurface}.</li>
+ *
+ * <li>For access to uncompressed, JPEG, or raw sensor data in the
+ * application: Create a {@link android.media.ImageReader} object with the
+ * desired {@link CameraProperties#SCALER_AVAILABLE_FORMATS image format},
+ * and a size from the matching
+ * {@link CameraProperties#SCALER_AVAILABLE_PROCESSED_SIZES processed},
+ * {@link CameraProperties#SCALER_AVAILABLE_JPEG_SIZES jpeg}, or
+ * {@link CameraProperties#SCALER_AVAILABLE_RAW_SIZES raw} sizes. Then
+ * obtain a Surface from it.</li>
+ *
+ * </ul>
+ *
+ * </p>
+ *
+ * <p>This function can take several hundred milliseconds to execute, since
+ * camera hardware may need to be powered on or reconfigured.</p>
+ *
+ * <p>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}.</p>
+ *
+ * <p>Using larger resolution outputs, or more outputs, can result in slower
+ * output rate from the device.</p>
+ *
+ * @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<Surface> outputs) {
+ }
+
+ /**
+ * <p>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.</p>
+ *
+ * @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 {
+ return null;
+ }
+
+ /**
+ * <p>Submit a request for an image to be captured by this CameraDevice.</p>
+ *
+ * <p>The request defines all the parameters for capturing the single image,
+ * including sensor, lens, flash, and post-processing settings.</p>
+ *
+ * <p>Each request will produce one {@link CaptureResult} and produce new
+ * frames for one or more target Surfaces, as defined by the request's .</p>
+ *
+ * <p>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.</p>
+ *
+ * @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 {
+ }
+
+ /**
+ * <p>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.</p>
+ *
+ * <p>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}.</p>
+ *
+ * <p>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.</p>
+ *
+ * @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<CaptureRequest> requests,
+ CaptureListener listener) throws CameraAccessException {
+ }
+
+ /**
+ * <p>Request endlessly repeating capture of images by this
+ * CameraDevice.</p>
+ *
+ * <p>With this method, the CameraDevice will continually capture
+ * images using the settings in the provided {@link
+ * CaptureRequest}, at the maximum rate possible.</p>
+ *
+ * <p>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.<p>
+ *
+ * <p>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.</p>
+ *
+ * <p>To stop the repeating capture, call {@link #stopRepeating}</p>
+ *
+ * <p>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.</p>
+ *
+ * @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 {
+ }
+
+ /**
+ * <p>Request endlessly repeating capture of a sequence of images by this
+ * CameraDevice.</p>
+ *
+ * <p>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.</p>
+ *
+ * <p>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.</p>
+ *
+ * <p>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.</p>
+ *
+ * <p>To stop the repeating capture, call {@link #stopRepeating}. Any
+ * ongoing burst will still be completed, however.</p>
+ *
+ * <p>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.</p>
+ *
+ * @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<CaptureRequest> requests, CaptureListener listener)
+ throws CameraAccessException {
+ }
+
+ /**
+ * <p>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}.</p>
+ *
+ * <p>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.</p>
+ *
+ * @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 {
+ }
+
+ /**
+ * <p>Wait until all the submitted requests have finished processing</p>
+ *
+ * <p>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.</p>
+ *
+ * <p>Once this call returns successfully, the device is in an idle state,
+ * and can be reconfigured with {@link #configureOutputs configureOutputs}.</p>
+ *
+ * <p>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.</p>
+ *
+ * @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().
+ */
+ public void 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 {
+ /**
+ * <p>Called when a capture request has been processed by a
+ * {@link CameraDevice}.</p>
+ *
+ * @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);
+
+ /**
+ * <p>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.</p>
+ *
+ * @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);
+ }
+
+ /**
+ * <p>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.</p>
+ */
+ public interface ErrorListener {
+ /**
+ * <p>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.</p>
+ *
+ * <p>There may still be capture completion or camera stream listeners
+ * that will be called after this error is received.</p>
+ */
+ public static final int DEVICE_DISCONNECTED = 1;
+
+ /**
+ * <p>The camera device has encountered a fatal error. Any attempt to
+ * call methods on this CameraDevice will throw a
+ * {@link java.lang.IllegalStateException}.</p>
+ *
+ * <p>There may still be capture completion or camera stream listeners
+ * that will be called after this error is received.</p>
+ *
+ * <p>The application needs to re-open the camera device to use it
+ * again.</p>
+ */
+ public static final int DEVICE_ERROR = 2;
+
+ /**
+ * <p>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}.</p>
+ *
+ * <p>There may still be capture completion or camera stream listeners
+ * that will be called after this error is received.</p>
+ *
+ * <p>The device may need to be shut down and restarted to restore
+ * camera function, or there may be a persistent hardware problem.</p>
+ */
+ 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);
+ }
+
+}
diff --git a/core/java/android/hardware/photography/CameraManager.java b/core/java/android/hardware/photography/CameraManager.java
new file mode 100644
index 0000000..328ba4b
--- /dev/null
+++ b/core/java/android/hardware/photography/CameraManager.java
@@ -0,0 +1,138 @@
+/*
+ * 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.photography;
+
+/**
+ * <p>An interface for iterating, listing, and connecting to
+ * {@link CameraDevice CameraDevices}.</p>
+ *
+ * <p>You can get an instance of this class by calling
+ * {@link android.content.Context#getSystemService(String) Context.getSystemService()}.</p>
+ *
+ * <pre>CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);</pre>
+ *
+ * <p>For more details about communicating with camera devices, read the Camera
+ * developer guide or the {@link android.hardware.photography photography}
+ * package documentation.</p>
+ */
+public final class CameraManager {
+
+ /**
+ * @hide
+ */
+ public CameraManager() {
+ }
+
+ /**
+ * <p>Return the list of currently connected camera devices by
+ * identifier. Non-removable cameras use integers starting at 0 for their
+ * identifiers, while removable cameras have a unique identifier for each
+ * individual device, even if they are the same model.</p>
+ *
+ * @return The list of currently connected camera devices.
+ */
+ public String[] getDeviceIdList() {
+ return null;
+ }
+
+ /**
+ * Register a listener to be notified about camera device availability.
+ *
+ * @param listener the new listener to send camera availablity notices to.
+ */
+ public void registerCameraListener(CameraListener listener) {
+ }
+
+ /**
+ * Remove a previously-added listener; the listener will no longer receive
+ * connection and disconnection callbacks.
+ *
+ * @param listener the listener to remove from the notification list
+ */
+ public void unregisterCameraListener(CameraListener listener) {
+ }
+
+ /**
+ * <p>Query the capabilities of a camera device. These capabilities are
+ * immutable for a given camera.</p>
+ *
+ * @param cameraId The id of the camera device to query
+ * @return The properties of the given camera
+ *
+ * @throws IllegalArgumentException if the cameraId does not match any
+ * currently connected camera device.
+ * @throws CameraAccessException if the camera is disabled by device policy.
+ * @throws SecurityException if the application does not have permission to
+ * access the camera
+ *
+ * @see #getDeviceIdList
+ * @see android.app.admin.DevicePolicyManager#setCameraDisabled
+ */
+ public CameraProperties getCameraProperties(String cameraId)
+ throws CameraAccessException {
+ throw new IllegalArgumentException();
+ }
+
+ /**
+ * Open a connection to a camera with the given ID. Use
+ * {@link #getDeviceIdList} to get the list of available camera
+ * devices. Note that even if an id is listed, open may fail if the device
+ * is disconnected between the calls to {@link #getDeviceIdList} and
+ * {@link #openCamera}.
+ *
+ * @param cameraId The unique identifier of the camera device to open
+ *
+ * @throws IllegalArgumentException if the cameraId does not match any
+ * currently connected camera device.
+ * @throws CameraAccessException if the camera is disabled by device policy,
+ * or too many camera devices are already open.
+ * @throws SecurityException if the application does not have permission to
+ * access the camera
+ *
+ * @see #getDeviceIdList
+ * @see android.app.admin.DevicePolicyManager#setCameraDisabled
+ */
+ public CameraDevice openCamera(String cameraId) throws CameraAccessException {
+ throw new IllegalArgumentException();
+ }
+
+ /**
+ * Interface for listening to cameras becoming available or unavailable.
+ * Cameras become available when they are no longer in use, or when a new
+ * removable camera is connected. They become unavailable when some
+ * application or service starts using a camera, or when a removable camera
+ * is disconnected.
+ */
+ public interface CameraListener {
+ /**
+ * A new camera has become available to use.
+ *
+ * @param cameraId The unique identifier of the new camera.
+ */
+ public void onCameraAvailable(String cameraId);
+
+ /**
+ * A previously-available camera has become unavailable for use. If an
+ * application had an active CameraDevice instance for the
+ * now-disconnected camera, that application will receive a {@link
+ * CameraDevice.ErrorListener#DEVICE_DISCONNECTED disconnection error}.
+ *
+ * @param cameraId The unique identifier of the disconnected camera.
+ */
+ public void onCameraUnavailable(String cameraId);
+ }
+}
diff --git a/core/java/android/hardware/photography/CameraMetadata.java b/core/java/android/hardware/photography/CameraMetadata.java
new file mode 100644
index 0000000..385a1b9
--- /dev/null
+++ b/core/java/android/hardware/photography/CameraMetadata.java
@@ -0,0 +1,129 @@
+/*
+ * 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.photography;
+
+import android.os.Parcelable;
+import android.os.Parcel;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * The base class for camera controls and information.
+ *
+ * This class defines the basic key/value map used for querying for camera
+ * characteristics or capture results, and for setting camera request
+ * parameters.
+ *
+ * @see CameraDevice
+ * @see CameraManager
+ * @see CameraProperties
+ **/
+public class CameraMetadata implements Parcelable {
+
+ public CameraMetadata() {
+ mMetadataMap = new HashMap<Key<?>, Object>();
+ }
+
+ private CameraMetadata(Parcel in) {
+
+ }
+
+ public static final Parcelable.Creator<CameraMetadata> CREATOR =
+ new Parcelable.Creator<CameraMetadata>() {
+ public CameraMetadata createFromParcel(Parcel in) {
+ return new CameraMetadata(in);
+ }
+
+ public CameraMetadata[] newArray(int size) {
+ return new CameraMetadata[size];
+ }
+ };
+
+ /**
+ * Set a camera metadata field to a value. The field definitions can be
+ * found in {@link CameraProperties}, {@link CaptureResult}, and
+ * {@link CaptureRequest}.
+ *
+ * @param key the metadata field to write.
+ * @param value the value to set the field to, which must be of a matching
+ * type to the key.
+ */
+ public <T> void set(Key<T> key, T value) {
+ mMetadataMap.put(key, value);
+ }
+
+ /**
+ * Get a camera metadata field value. The field definitions can be
+ * found in {@link CameraProperties}, {@link CaptureResult}, and
+ * {@link CaptureRequest}.
+ *
+ * @param key the metadata field to read.
+ * @return the value of that key, or {@code null} if the field is not set.
+ */
+ @SuppressWarnings("unchecked")
+ public <T> T get(Key<T> key) {
+ return (T) mMetadataMap.get(key);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+
+ }
+
+ public static class Key<T> {
+ public Key(String name) {
+ if (name == null) {
+ throw new NullPointerException("Key needs a valid name");
+ }
+ mName = name;
+ }
+
+ public final String getName() {
+ return mName;
+ }
+
+ @Override
+ public final int hashCode() {
+ return mName.hashCode();
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public final boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+
+ if (!(o instanceof Key)) {
+ return false;
+ }
+
+ Key lhs = (Key) o;
+
+ return mName.equals(lhs.mName);
+ }
+
+ private final String mName;
+ }
+
+ private Map<Key<?>, Object> mMetadataMap;
+}
\ No newline at end of file
diff --git a/core/java/android/hardware/photography/CameraProperties.java b/core/java/android/hardware/photography/CameraProperties.java
new file mode 100644
index 0000000..1bfd712
--- /dev/null
+++ b/core/java/android/hardware/photography/CameraProperties.java
@@ -0,0 +1,247 @@
+/*
+ * 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.photography;
+
+import android.graphics.Rect;
+
+import java.util.List;
+
+/**
+ * <p>The properties describing a
+ * {@link CameraDevice CameraDevice}.</p>
+ *
+ * <p>These properties are fixed for a given CameraDevice, and can be queried
+ * through the {@link CameraManager CameraManager}
+ * interface in addition to through the CameraDevice interface.</p>
+ *
+ * @see CameraDevice
+ * @see CameraManager
+ */
+public final class CameraProperties extends CameraMetadata {
+ /**
+ * The model name of the camera. For fixed (non-removable) cameras, this is
+ * the manufacturer's name. For removable cameras, this is a string that
+ * uniquely identifies the camera model and manufacturer. The
+ * {@link #INFO_IDENTIFIER} can be used to distinguish between multiple
+ * removable cameras of the same model.
+ */
+ public static final Key INFO_MODEL =
+ new Key<String>("android.info.model");
+
+ /**
+ * A unique identifier for this camera. For removable cameras, every
+ * camera will have a unique identifier, including two cameras of the
+ * same model and manufacturer. For non-removable cameras, the
+ * identifier is equal to the the device's id.
+ */
+ public static final Key INFO_IDENTIFIER =
+ new Key<String>("android.info.identifier");
+
+ /**
+ * <p>Whether this camera is removable or not.</p>
+ *
+ * <p>Applications using a removable camera must be prepared for the camera
+ * to be disconnected during use. Use the {@link #INFO_IDENTIFIER} field to
+ * determine if this camera is a match for a camera device seen earlier.</p>
+ */
+ public static final Key INFO_REMOVABLE =
+ new Key<Boolean>("android.info.isRemovable");
+
+ /**
+ * <p>The hardware operational model of this device. One of the
+ * INFO_SUPPORTED_HARDWARE_LEVEL_* constants.</p>
+ *
+ * <p>Limited-capability devices have a number of limitations relative to
+ * full-capability cameras. Roughly, they have capabilities comparable to
+ * those provided by the deprecated {@link android.hardware.Camera}
+ * class.</p>
+ *
+ * <p>Specifically, limited-mode devices:</p>
+ *
+ * <ol>
+ *
+ * <li>Do not provide per-frame result metadata for repeating
+ * captures. This means that a CaptureListener will not be called for
+ * captures done through {@link CameraDevice#setRepeatingRequest
+ * setRepeatingRequest} or {@link CameraDevice#setRepeatingBurst
+ * setRepeatingBurst}.</li>
+ *
+ * <li>Do not support complete result metadata. Only a few fields are
+ * provided, such as the timestamp (TODO).</li>
+ *
+ * <li>Do not support manual capture controls. Only the (TODO)
+ * ANDROID_CONTROL_* fields and TODO controls are used, and the various
+ * AE/AF/AWB_OFF control values cannot be used.</li>
+ *
+ * <li>Do not support high frame rate captures. To obtain high frame rate,
+ * the {@link CameraDevice#setRepeatingRequest setRepeatingRequest} method
+ * must be used. The {@link CameraDevice#capture capture},
+ * {@link CameraDevice#captureBurst captureBurst}, and
+ * {@link CameraDevice#setRepeatingBurst setRepeatingBurst} methods will
+ * result in slow frame captures.</li>
+ *
+ * </ol>
+ *
+ * @see #INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED
+ * @see #INFO_SUPPORTED_HARDWARE_LEVEL_FULL
+ */
+ public static final Key INFO_SUPPORTED_HARDWARE_LEVEL =
+ new Key<Integer>("android.info.supportedHardwareLevel");
+
+ /**
+ * <p>The type reported by limited-capability camera devices.</p>
+ *
+ * <p>Limited-capability devices have a number of limitations relative to
+ * full-capability cameras. Roughly, they have capabilities comparable to
+ * those provided by the deprecated {@link android.hardware.Camera}
+ * class.</p>
+ *
+ * <p>Specifically, limited-mode devices:</p>
+ *
+ * <ol>
+ *
+ * <li>Do not provide per-frame result metadata for repeating
+ * captures. This means that a CaptureListener will not be called for
+ * captures done through {@link CameraDevice#setRepeatingRequest
+ * setRepeatingRequest} or {@link CameraDevice#setRepeatingBurst
+ * setRepeatingBurst}.</li>
+ *
+ * <li>Do not support complete result metadata. Only a few fields are
+ * provided, such as the timestamp (TODO).</li>
+ *
+ * <li>Do not support manual capture controls. Only the (TODO)
+ * ANDROID_CONTROL_* fields and TODO controls are used, and the various
+ * AE/AF/AWB_OFF control values cannot be used.</li>
+ *
+ * <li>Do not support high frame rate captures. To obtain high frame rate,
+ * the {@link CameraDevice#setRepeatingRequest setRepeatingRequest} method
+ * must be used. The {@link CameraDevice#capture capture},
+ * {@link CameraDevice#captureBurst captureBurst}, and
+ * {@link CameraDevice#setRepeatingBurst setRepeatingBurst} methods will
+ * result in slow frame captures.</li>
+ *
+ * </ol>
+ *
+ * @see #INFO_SUPPORTED_HARDWARE_LEVEL
+ */
+ public static final int INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED = 0;
+
+ /**
+ * <p>The type reported by full-capability camera devices</p>
+ *
+ * <p>Full-capability devices allow for per-frame control of capture
+ * hardware and post-processing parameters at high frame rates. They also
+ * provide output data at high resolution in uncompressed formats, in
+ * addition to compressed JPEG output.</p>
+ *
+ * @see #INFO_SUPPORTED_HARDWARE_LEVEL
+ */
+ public static final int INFO_SUPPORTED_HARDWARE_LEVEL_FULL = 1;
+
+ /**
+ * <p>The available output formats from this camera device. When using a
+ * {@link android.media.ImageReader} as an output target, the
+ * ImageReader must be configured to use one of these formats.</p>
+ *
+ * <p>The list is a subset of the formats defined in
+ * {@link android.graphics.ImageFormat}.</p>
+ *
+ * <p>The image formats {@link android.graphics.ImageFormat#JPEG},
+ * {@link android.graphics.ImageFormat#YUV_420_888} are guaranteed to be
+ * supported.</p>
+ */
+ public static final Key SCALER_AVAILABLE_FORMATS =
+ new Key<Integer[]>("android.scaler.availableFormats");
+
+ /**
+ * <p>The available output sizes for JPEG buffers from this camera
+ * device. When using a {@link android.media.ImageReader} as an output
+ * target, the ImageReader must be configured to use one of these sizes
+ * when using format {@link android.graphics.ImageFormat#JPEG}.</p>
+ */
+ public static final Key SCALER_AVAILABLE_JPEG_SIZES =
+ new Key<Size[]>("android.scaler.availableJpegSizes");
+
+ /**
+ * <p>The available sizes for output buffers from this camera device, when
+ * the buffers are neither of the {@link android.graphics.ImageFormat#JPEG}
+ * or of the {@link android.graphics.ImageFormat#RAW_SENSOR} type.</p>
+ *
+ * <p>When using a {@link android.view.SurfaceView},
+ * {@link android.graphics.SurfaceTexture},
+ * {@link android.media.MediaRecorder}, {@link android.media.MediaCodec}, or
+ * {@link android.renderscript.Allocation} as an output target, that target
+ * must be configured to one of these sizes. See
+ * {@link CameraDevice#configureOutputs} for details.
+ *
+ * <p>When using a {@link android.media.ImageReader} as an output
+ * target, the ImageReader must be configured to use one of these sizes
+ * when using format {@link android.graphics.ImageFormat#YUV_420_888}.</p>
+ *
+ */
+ public static final Key SCALER_AVAILABLE_PROCESSED_SIZES =
+ new Key<Size[]>("android.scaler.availableProcessedSizes");
+
+ /**
+ * <p>The available sizes for output buffers from this camera device, when
+ * the buffers are of the {@link android.graphics.ImageFormat#RAW_SENSOR} type. This type of output may not be
+ * supported by the device; check {@link #SCALER_AVAILABLE_FORMATS} to
+ * check. In that case, this list will not exist.</p>
+ *
+ * <p>When using a {@link android.media.ImageReader} as an output
+ * target, the ImageReader must be configured to use one of these sizes
+ * when using image format {@link android.graphics.ImageFormat#RAW_SENSOR}.</p>
+ */
+ public static final Key SCALER_AVAILABLE_RAW_SIZES =
+ new Key<Size[]>("android.scaler.availableRawSizes");
+
+ /**
+ * <p>The coordinates of the sensor's active pixel array, relative to its
+ * total pixel array. These are the pixels that are actually used for image
+ * capture. The active pixel region may be smaller than the total number of
+ * pixels, if some pixels are used for other tasks such as calibrating the
+ * sensor's black level. If all pixels available for readout are used for
+ * imaging, then this rectangle will be
+ * {@code (0,0) - (SENSOR_PIXEL_ARRAY_SIZE.width,
+ * SENSOR_PIXEL_ARRAY_SIZE.height)}.</p>
+ *
+ * <p>If raw sensor capture is supported by this device, the width and
+ * height of the active pixel array match up to one of the supported raw
+ * capture sizes, and using that size will capture just the active pixel
+ * array region.</p>
+ *
+ * <p>Most other coordinates used by the camera device (for example, for
+ * metering and crop region selection, or for reporting detected faces) use
+ * a coordinate system based on the active array dimensions, with (0,0)
+ * being the top-left corner of the active array.</p>
+ */
+ public static final Key SENSOR_ACTIVE_ARRAY_SIZE =
+ new Key<Rect>("android.sensor.activeArraySize");
+
+ /**
+ * <p>The size of the sensor's total pixel array available for readout. Some
+ * of these pixels may not be used for image capture, in which case
+ * {@link #SENSOR_ACTIVE_ARRAY_SIZE} will describe a rectangle smaller than
+ * this. If raw sensor capture is supported by this device, this is one of
+ * the supported capture sizes.</p>
+ */
+ public static final Key SENSOR_PIXEL_ARRAY_SIZE =
+ new Key<Size>("android.sensor.activeArraySize");
+
+ // TODO: Many more of these.
+
+}
diff --git a/core/java/android/hardware/photography/CaptureRequest.java b/core/java/android/hardware/photography/CaptureRequest.java
new file mode 100644
index 0000000..a54c743
--- /dev/null
+++ b/core/java/android/hardware/photography/CaptureRequest.java
@@ -0,0 +1,85 @@
+/*
+ * 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.photography;
+
+import android.view.Surface;
+
+import java.util.List;
+
+
+/**
+ * <p>All the settings required to capture a single image from the image sensor.</p>
+ *
+ * <p>Contains the configuration for the capture hardware (sensor, lens, flash),
+ * the processing pipeline, the control algorithms, and the output buffers.</p>
+ *
+ * <p>CaptureRequests can be created by calling
+ * {@link CameraDevice#createCaptureRequest}</p>
+ *
+ * <p>CaptureRequests are given to {@link CameraDevice#capture} or
+ * {@link CameraDevice#setRepeatingRequest} to capture images from a camera.</p>
+ *
+ * <p>Each request can specify a different subset of target Surfaces for the
+ * camera to send the captured data to. All the surfaces used in a request must
+ * be part of the surface list given to the last call to
+ * {@link CameraDevice#configureOutputs}.</p>
+ *
+ * <p>For example, a request meant for repeating preview might only include the
+ * Surface for the preview SurfaceView or SurfaceTexture, while a
+ * high-resolution still capture would also include a Surface from a ImageReader
+ * configured for high-resolution JPEG images.</p>
+ *
+ * @see CameraDevice#capture
+ * @see CameraDevice#setRepeatingRequest
+ * @see CameraDevice#createRequest
+ */
+public final class CaptureRequest extends CameraMetadata {
+
+ /**
+ * The exposure time for this capture, in nanoseconds.
+ */
+ public static final Key SENSOR_EXPOSURE_TIME =
+ new Key<Long>("android.sensor.exposureTime");
+
+ /**
+ * The sensor sensitivity (gain) setting for this camera.
+ * This is represented as an ISO sensitivity value
+ */
+ public static final Key SENSOR_SENSITIVITY =
+ new Key<Integer>("android.sensor.sensitivity");
+
+ // Many more settings
+
+ CaptureRequest() {
+ }
+
+ /**
+ * <p>Add a surface to the list of targets for this request</p>
+ *
+ * <p>The Surface added must be one of the surfaces included in the last
+ * call to {@link CameraDevice#configureOutputs}.</p>
+ */
+ public void addTarget(Surface outputTarget) {
+ }
+
+ /**
+ * <p>Remove a surface from the list of targets for this request.</p>
+ */
+ public void removeTarget(Surface outputTarget) {
+ }
+
+}
\ No newline at end of file
diff --git a/core/java/android/hardware/photography/CaptureResult.java b/core/java/android/hardware/photography/CaptureResult.java
new file mode 100644
index 0000000..dd36f1d
--- /dev/null
+++ b/core/java/android/hardware/photography/CaptureResult.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2012 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.photography;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+
+/**
+ * <p>The results of a single image capture from the image sensor.</p>
+ *
+ * <p>Contains the final configuration for the capture hardware (sensor, lens,
+ * flash), the processing pipeline, the control algorithms, and the output
+ * buffers.</p>
+ *
+ * <p>CaptureResults are produced by a {@link CameraDevice} after processing a
+ * {@link CaptureRequest}. All properties listed for capture requests can also
+ * be queried on the capture result, to determine the final values used for
+ * capture. The result also includes additional metadata about the state of the
+ * camera device during the capture.</p>
+ *
+ */
+public final class CaptureResult extends CameraMetadata {
+
+ /**
+ * The timestamp representing the start of image capture, in nanoseconds.
+ * This corresponds to the timestamp available through
+ * {@link android.graphics.SurfaceTexture#getTimestamp SurfaceTexture.getTimestamp()}
+ * or {@link android.media.Image#getTimestamp Image.getTimestamp()} for this
+ * capture's image data.
+ */
+ public static final Key SENSOR_TIMESTAMP =
+ new Key<Long>("android.sensor.timestamp");
+
+ /**
+ * The state of the camera device's auto-exposure algorithm. One of the
+ * CONTROL_AE_STATE_* enumerations.
+ */
+ public static final Key CONTROL_AE_STATE =
+ new Key<Integer>("android.control.aeState");
+
+ /**
+ * The auto-exposure algorithm is inactive.
+ * @see CONTROL_AE_STATE
+ */
+ public static final int CONTROL_AE_STATE_INACTIVE = 0;
+
+ /**
+ * The auto-exposure algorithm is currently searching for proper exposure.
+ * @see CONTROL_AE_STATE
+ */
+ public static final int CONTROL_AE_STATE_SEARCHING = 1;
+
+ /**
+ * The auto-exposure algorithm has reached proper exposure values for the
+ * current scene.
+ * @see CONTROL_AE_STATE
+ */
+ public static final int CONTROL_AE_STATE_CONVERGED = 2;
+
+ /**
+ * The auto-exposure algorithm has been locked to its current values.
+ * @see CONTROL_AE_STATE
+ */
+ public static final int CONTROL_AE_STATE_LOCKED = 3;
+
+ /**
+ * The auto-exposure algorithm has reached proper exposure values as with
+ * CONTROL_AE_STATE_CONVERGED, but the scene is too dark to take a good
+ * quality image without firing the camera flash.
+ * @see CONTROL_AE_STATE
+ */
+ public static final int CONTROL_AE_STATE_FLASH_REQUIRED = 4;
+
+ /**
+ * The precapture sequence of the auto-exposure algorithm has been triggered,
+ * and is underway.
+ * @see CONTROL_AE_STATE
+ */
+ public static final int CONTROL_AE_STATE_PRECAPTURE =5;
+
+ /**
+ * The list of faces detected in this capture. Available if face detection
+ * was enabled for this capture
+ */
+ public static final Key STATISTICS_DETECTED_FACES =
+ new Key<Face[]>("android.statistics.faces");
+
+ // TODO: Many many more
+
+ CaptureResult() {
+ }
+
+ /**
+ * Describes a face detected in an image.
+ */
+ public static class Face {
+
+ /**
+ * <p>Bounds of the face. A rectangle relative to the sensor's
+ * {@link CameraProperties#SENSOR_ACTIVE_ARRAY_SIZE}, with (0,0)
+ * representing the top-left corner of the active array rectangle.</p>
+ */
+ public Rect getBounds() {
+ return mBounds;
+ }
+
+ /* <p>The confidence level for the detection of the face. The range is 1 to
+ * 100. 100 is the highest confidence.</p>
+ *
+ * <p>Depending on the device, even very low-confidence faces may be
+ * listed, so applications should filter out faces with low confidence,
+ * depending on the use case. For a typical point-and-shoot camera
+ * application that wishes to display rectangles around detected faces,
+ * filtering out faces with confidence less than 50 is recommended.</p>
+ *
+ */
+ public int getScore() {
+ return mScore;
+ }
+
+ /**
+ * An unique id per face while the face is visible to the tracker. If
+ * the face leaves the field-of-view and comes back, it will get a new
+ * id. This is an optional field, may not be supported on all devices.
+ * If not supported, id will always be set to -1. The optional fields
+ * are supported as a set. Either they are all valid, or none of them
+ * are.
+ */
+ public int getId() {
+ return mId;
+ }
+
+ /**
+ * The coordinates of the center of the left eye. The coordinates are in
+ * the same space as the ones for {@link #getBounds}. This is an
+ * optional field, may not be supported on all devices. If not
+ * supported, the value will always be set to null. The optional fields
+ * are supported as a set. Either they are all valid, or none of them
+ * are.
+ */
+ public Point getLeftEye() {
+ return mLeftEye;
+ }
+
+ /**
+ * The coordinates of the center of the right eye. The coordinates are
+ * in the same space as the ones for {@link #getBounds}.This is an
+ * optional field, may not be supported on all devices. If not
+ * supported, the value will always be set to null. The optional fields
+ * are supported as a set. Either they are all valid, or none of them
+ * are.
+ */
+ public Point getRightEye() {
+ return mRightEye;
+ }
+
+ /**
+ * The coordinates of the center of the mouth. The coordinates are in
+ * the same space as the ones for {@link #getBounds}. This is an optional
+ * field, may not be supported on all devices. If not supported, the
+ * value will always be set to null. The optional fields are supported
+ * as a set. Either they are all valid, or none of them are.
+ */
+ public Point getMouth() {
+ return mMouth;
+ }
+
+ private Rect mBounds;
+ private int mScore;
+ private int mId;
+ private Point mLeftEye;
+ private Point mRightEye;
+ private Point mMouth;
+ }
+}
diff --git a/core/java/android/hardware/photography/Size.java b/core/java/android/hardware/photography/Size.java
new file mode 100644
index 0000000..e1115d3
--- /dev/null
+++ b/core/java/android/hardware/photography/Size.java
@@ -0,0 +1,45 @@
+/*
+ * 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.photography;
+
+/**
+ * A simple immutable class for describing the dimensions of camera image
+ * buffers.
+ */
+public final class Size {
+ /**
+ * Create a new immutable Size instance
+ *
+ * @param w The width to store in the Size instance
+ * @param h The height to store in the Size instance
+ */
+ Size(int w, int h) {
+ mWidth = w;
+ mHeight = h;
+ }
+
+ public final int getWidth() {
+ return mWidth;
+ }
+
+ public final int getHeight() {
+ return mHeight;
+ }
+
+ private final int mWidth;
+ private final int mHeight;
+};
diff --git a/core/java/android/hardware/photography/package.html b/core/java/android/hardware/photography/package.html
new file mode 100644
index 0000000..578bdf5
--- /dev/null
+++ b/core/java/android/hardware/photography/package.html
@@ -0,0 +1,84 @@
+<!-- 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.
+-->
+<HTML>
+<BODY>
+<p>The android.hardware.photography package provides an interface to
+individual camera devices connected to an Android device. It replaces
+the deprecated {@link android.hardware.Camera} class.</p>
+
+<p>This package models a camera device as a pipeline, which takes in
+input requests for capturing a single frame, captures the single image
+per the request, and then outputs one capture result metadata packet,
+plus a set of output image buffers for the request. The requests are
+processed in-order, and multiple requests can be in flight at
+once. Since the camera device is a pipeline with multiple stages,
+having multiple requests in flight is required to maintain full
+framerate on most Android devices.</p>
+
+<p>To enumerate, query, and open available camera devices, obtain a
+{@link android.hardware.photography.CameraManager} instance.</p>
+
+<p>Individual {@link android.hardware.photography.CameraDevice
+CameraDevices} provide a set of static property information that
+describes the hardware device and the available settings and output
+parameters for the device. This information is provided through the
+{@link android.hardware.photography.CameraProperties} object.</p>
+
+<p>To capture or stream images from a camera device, the application
+must first configure a set of output Surfaces for use with the camera
+device, with {@link
+android.hardware.photography.CameraDevice#configureOutputs}. Each
+Surface has to be pre-configured with an appropriate size and format
+(if applicable) to match the sizes and formats available from the
+camera device. A target Surface can be obtained from a variety of
+classes, including {@link android.view.SurfaceView}, {@link
+android.graphics.SurfaceTexture} via {@link
+android.view.Surface#Surface(SurfaceTexture), {@link
+android.media.MediaCodec}, and {@link android.media.ImageReader}.
+</p>
+
+<p>The application then needs to construct a {@link
+android.hardware.photography.CaptureRequest}, which defines all the
+capture parameters needed by a camera device to capture a single
+image. The request also lists which of the configured output Surfaces
+should be used as targets for this capture. The CameraDevice has a
+{@link android.hardware.photography.CameraDevice#createCaptureRequest
+convenience factory method} for creating a request for a given use
+case which is optimized for the Android device the application is
+running on.</p>
+
+<p>Once the request has been set up, it can be handed to the
+CameraDevice either for a one-shot {@link
+android.hardware.photography.CameraDevice#capture} or for an endlessly
+{@link android.hardware.photography.CameraDevice#setRepeatingRequest
+repeating} use. Both methods also accept a list of requests to use as
+a burst capture / repeating burst. Repeating requests have a lower
+priority than captures, so a request submitted
+through <code>capture()</code> while there's a repeating request
+configured will be captured as soon as the current repeat (burst)
+capture completes.</p>
+
+<p>After processing a request, the camera device will produce a {@link
+android.hardware.photography.CaptureResult} object, which contains
+information about the state of the camera device at time of capture,
+and the final settings used. These may vary somewhat from the request,
+if rounding or resolving contradictory parameters was necessary. The
+camera device will also send a frame of image data into each of the
+output streams included in the request. These are produced
+asynchronously relative to the output CaptureResult, sometimes
+substantially later.</p>
+
+</BODY>
+</HTML>
diff --git a/core/java/android/view/SurfaceHolder.java b/core/java/android/view/SurfaceHolder.java
index 015a78e..99fa2a4 100644
--- a/core/java/android/view/SurfaceHolder.java
+++ b/core/java/android/view/SurfaceHolder.java
@@ -277,9 +277,6 @@
*
* <p>This method is intended to be used by frameworks which often need
* direct access to the Surface object (usually to pass it to native code).
- * When designing APIs always use SurfaceHolder to pass surfaces around
- * as opposed to the Surface object itself. A rule of thumb is that
- * application code should never have to call this method.
*
* @return Surface The surface.
*/
diff --git a/graphics/java/android/graphics/ImageFormat.java b/graphics/java/android/graphics/ImageFormat.java
index f6b747a..972ce47 100644
--- a/graphics/java/android/graphics/ImageFormat.java
+++ b/graphics/java/android/graphics/ImageFormat.java
@@ -100,6 +100,41 @@
public static final int JPEG = 0x100;
/**
+ * <p>Multi-plane Android YUV format</p>
+ *
+ * <p>This format is a generic YCbCr format, capable of describing any 4:2:0
+ * chroma-subsampled planar or semiplanar buffer, with 8 bits per color
+ * sample.</p>
+ *
+ * <p>Images in this format are always represented by three separate buffers
+ * of data, one for each color plane. Additional information always
+ * accompanies the buffers, describing the row stride and the pixel stride
+ * for each plane.</p>
+ *
+ * <p>For example, the {@link android.media.Image} object can provide data
+ * in this format from a {@link android.hardware.photography.CameraDevice}
+ * through a {@link android.media.ImageReader} object.</p>
+ *
+ * @see android.media.Image
+ * @see android.media.ImageReader
+ * @see android.hardware.camera.CameraDevice
+ */
+ public static final int YUV_420_888 = 0x23;
+
+ /**
+ * <p>General raw camera sensor image format, usually representing a
+ * single-channel Bayer-mosaic image. Each pixel color sample is stored with
+ * 16 bits of precision.</p>
+ *
+ * <p>The layout of the color mosaic, the maximum and minimum encoding
+ * values of the raw pixel data, the color space of the image, and all other
+ * needed information to interpret a raw sensor image must be queried from
+ * the {@link android.hardware.photography.CameraDevice} which produced the
+ * image.</p>
+ */
+ public static final int RAW_SENSOR = 0x201;
+
+ /**
* Raw bayer format used for images, which is 10 bit precision samples
* stored in 16 bit words. The filter pattern is RGGB. Whether this format
* is supported by the camera hardware can be determined by
@@ -129,6 +164,10 @@
return 12;
case NV21:
return 12;
+ case YUV_420_888:
+ return 12;
+ case RAW_SENSOR:
+ return 16;
case BAYER_RGGB:
return 16;
}
diff --git a/media/java/android/media/Image.java b/media/java/android/media/Image.java
new file mode 100644
index 0000000..eb94346
--- /dev/null
+++ b/media/java/android/media/Image.java
@@ -0,0 +1,184 @@
+/*
+ * 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.media;
+
+import android.graphics.ImageFormat;
+import java.nio.ByteBuffer;
+import java.lang.AutoCloseable;
+
+/**
+ * <p>A single complete image buffer to use with a media source such as a
+ * {@link MediaCodec} or a
+ * {@link android.hardware.photography.CameraDevice}.</p>
+ *
+ * <p>This class allows for efficient direct application access to the pixel
+ * data of the Image through one or more
+ * {@link java.nio.ByteBuffer ByteBuffers}. Each buffer is encapsulated in a
+ * {@link Plane} that describes the layout of the pixel data in that plane. Due
+ * to this direct access, and unlike the {@link android.graphics.Bitmap} class,
+ * Images are not directly usable as as UI resources.</p>
+ *
+ * <p>Since Images are often directly produced or consumed by hardware
+ * components, they are a limited resource shared across the system, and should
+ * be closed as soon as they are no longer needed.</p>
+ *
+ * <p>For example, when using the {@link ImageReader} class to read out Images
+ * from various media sources, not closing old Image objects will prevent the
+ * availability of new Images once
+ * {@link ImageReader#getMaxImages the maximum outstanding image count} is
+ * reached.</p>
+ *
+ * @see ImageReader
+ */
+public abstract class Image implements AutoCloseable {
+ /**
+ * Get the format for this image. This format determines the number of
+ * ByteBuffers needed to represent the image, and the general layout of the
+ * pixel data in each in ByteBuffer.
+ *
+ * The format is one of the values from
+ * {@link android.graphics.ImageFormat}. The mapping between the formats and
+ * the planes is as follows:
+ *
+ * <table>
+ * <th>
+ * <td>Format</td>
+ * <td>Plane count</td>
+ * <td>Layout details</td>
+ * </th>
+ * <tr>
+ * <td>{@link android.graphics.ImageFormat#JPEG}</td>
+ * <td>1</td>
+ * <td>Compressed data, so row and pixel strides are 0. To uncompress, use
+ * {@link android.graphics.BitmapFactory#decodeByteArray}.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link android.graphics.ImageFormat#YUV_420_888}</td>
+ * <td>3</td>
+ * <td>A luminance plane followed by the Cb and Cr chroma planes.
+ * The chroma planes have half the width and height of the luminance
+ * plane (4:2:0 subsampling). Each pixel sample in each plane has 8 bits.
+ * Each plane has its own row stride and pixel stride.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link android.graphics.ImageFormat#RAW_SENSOR}</td>
+ * <td>1</td>
+ * <td>A single plane of raw sensor image data, with 16 bits per color
+ * sample. The details of the layout need to be queried from the source of
+ * the raw sensor data, such as
+ * {@link android.hardware.photography.CameraDevice}.
+ * </td>
+ * </tr>
+ * </table>
+ *
+ * @see android.graphics.ImageFormat
+ */
+ public int getFormat() {
+ return ImageFormat.UNKNOWN;
+ }
+
+ /**
+ * The width of the image in pixels. For formats where some color channels
+ * are subsampled, this is the width of the largest-resolution plane.
+ */
+ public int getWidth() {
+ return 0;
+ }
+
+ /**
+ * The height of the image in pixels. For formats where some color channels
+ * are subsampled, this is the height of the largest-resolution plane.
+ */
+ public int getHeight() {
+ return 0;
+ }
+
+ /**
+ * Get the timestamp associated with this frame. The timestamp is measured
+ * in nanoseconds, and is monotonically increasing. However, the zero point
+ * and whether the timestamp can be compared against other sources of time
+ * or images depend on the source of this image.
+ */
+ public long getTimestamp() {
+ return 0;
+ }
+
+ /**
+ * Get the array of pixel planes for this Image. The number of planes is
+ * determined by the format of the Image.
+ */
+ public Plane[] getPlanes() {
+ return null;
+ }
+
+ /**
+ * Free up this frame for reuse. After calling this method, calling any
+ * methods on this Image will result in an IllegalStateException, and
+ * attempting to read from ByteBuffers returned by an earlier
+ * {@code Plane#getBuffer} call will have undefined behavior.
+ */
+ public abstract void close();
+
+ protected final void finalize() {
+ close();
+ }
+
+ /**
+ * <p>A single color plane of image data.</p>
+ *
+ * <p>The number and meaning of the planes in an Image are determined by the
+ * format of the Image.</p>
+ *
+ * <p>Once the Image has been closed, any access to the the plane's
+ * ByteBuffer will fail.</p>
+ *
+ * @see #getFormat
+ */
+ public static final class Plane {
+ /**
+ * <p>The row stride for this color plane, in bytes.
+ *
+ * <p>This is the distance between the start of two consecutive rows of
+ * pixels in the image.</p>
+ */
+ public int getRowStride() {
+ return 0;
+ }
+
+ /**
+ * <p>The distance between adjacent pixel samples, in bytes.</p>
+ *
+ * <p>This is the distance between two consecutive pixel values in a row
+ * of pixels. It may be larger than the size of a single pixel to
+ * account for interleaved image data or padded formats.</p>
+ */
+ public int getPixelStride() {
+ return 0;
+ }
+
+ /**
+ * <p>Get a set of direct {@link java.nio.ByteBuffer byte buffers}
+ * containing the frame data.</p>
+ *
+ * @return the byte buffer containing the image data for this plane.
+ */
+ public ByteBuffer getBuffer() {
+ return null;
+ }
+ }
+
+}
diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java
new file mode 100644
index 0000000..9384c14
--- /dev/null
+++ b/media/java/android/media/ImageReader.java
@@ -0,0 +1,171 @@
+/*
+ * 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.media;
+
+import android.view.Surface;
+import java.lang.AutoCloseable;
+
+/**
+ * <p>The ImageReader class allows direct application access to image data
+ * rendered into a {@link android.view.Surface}</p>
+ *
+ * <p>Several Android media API classes accept Surface objects as targets to
+ * render to, including {@link MediaPlayer}, {@link MediaCodec},
+ * {@link android.hardware.photography.CameraDevice}, and
+ * {@link android.renderscript.Allocation RenderScript Allocations}. The image
+ * sizes and formats that can be used with each source vary, and should be
+ * checked in the documentation for the specific API.</p>
+ *
+ * <p>The image data is encapsulated in {@link Image} objects, and multiple such
+ * objects can be accessed at the same time, up to the number specified by the
+ * {@code maxImages} constructor parameter. New images sent to an ImageReader
+ * through its Surface are queued until accessed through the
+ * {@link #getNextImage} call. Due to memory limits, an image source will
+ * eventually stall or drop Images in trying to render to the Surface if the
+ * ImageReader does not obtain and release Images at a rate equal to the
+ * production rate.</p>
+ */
+public final class ImageReader {
+
+ /**
+ * <p>Create a new reader for images of the desired size and format.</p>
+ *
+ * <p>The maxImages parameter determines the maximum number of {@link Image}
+ * objects that can be be acquired from the ImageReader
+ * simultaneously. Requesting more buffers will use up more memory, so it is
+ * important to use only the minimum number necessary for the use case.</p>
+ *
+ * <p>The valid sizes and formats depend on the source of the image
+ * data.</p>
+ *
+ * @param width the width in pixels of the Images that this reader will
+ * produce.
+ * @param height the height in pixels of the Images that this reader will
+ * produce.
+ * @param format the format of the Image that this reader will produce. This
+ * must be one of the {@link android.graphics.ImageFormat} constants.
+ * @param maxImages the maximum number of images the user will want to
+ * access simultaneously. This should be as small as possible to limit
+ * memory use. Once maxImages Images are obtained by the user, one of them
+ * has to be released before a new Image will become available for access
+ * through getImage(). Must be greater than 0.
+ *
+ * @see Image
+ */
+ public ImageReader(int width, int height, int format, int maxImages) {
+ mWidth = width;
+ mHeight = height;
+ mFormat = format;
+ mMaxImages = maxImages;
+
+ if (width < 1 || height < 1) {
+ throw new IllegalArgumentException(
+ "The image dimensions must be positive");
+ }
+ if (mMaxImages < 1) {
+ throw new IllegalArgumentException(
+ "Maximum outstanding image count must be at least 1");
+ }
+ }
+
+ public int getWidth() {
+ return mWidth;
+ }
+
+ public int getHeight() {
+ return mHeight;
+ }
+
+ public int getImageFormat() {
+ return mFormat;
+ }
+
+ public int getMaxImages() {
+ return mMaxImages;
+ }
+
+ /**
+ * <p>Get a Surface that can be used to produce Images for this
+ * ImageReader.</p>
+ *
+ * <p>Until valid image data is rendered into this Surface, the
+ * {@link #getNextImage} method will return {@code null}. Only one source
+ * can be producing data into this Surface at the same time, although the
+ * same Surface can be reused with a different API once the first source is
+ * disconnected from the Surface.</p>
+ *
+ * @return A Surface to use for a drawing target for various APIs.
+ */
+ public Surface getSurface() {
+ return null;
+ }
+
+ /**
+ * <p>Get the next Image from the ImageReader's queue. Returns {@code null}
+ * if no new image is available.</p>
+ *
+ * @return a new frame of image data, or {@code null} if no image data is
+ * available.
+ */
+ public Image getNextImage() {
+ return null;
+ }
+
+ /**
+ * <p>Return the frame to the ImageReader for reuse.</p>
+ */
+ public void releaseImage(Image i) {
+ if (! (i instanceof SurfaceImage) ) {
+ throw new IllegalArgumentException(
+ "This image was not produced by an ImageReader");
+ }
+ SurfaceImage si = (SurfaceImage) i;
+ if (si.getReader() != this) {
+ throw new IllegalArgumentException(
+ "This image was not produced by this ImageReader");
+ }
+ }
+
+ public void setOnImageAvailableListener(OnImageAvailableListener l) {
+ mImageListener = l;
+ }
+
+ public interface OnImageAvailableListener {
+ void onImageAvailable(ImageReader reader);
+ }
+
+ private final int mWidth;
+ private final int mHeight;
+ private final int mFormat;
+ private final int mMaxImages;
+
+ private OnImageAvailableListener mImageListener;
+
+ private class SurfaceImage extends android.media.Image {
+ public SurfaceImage() {
+ }
+
+ @Override
+ public void close() {
+ ImageReader.this.releaseImage(this);
+ }
+
+ public ImageReader getReader() {
+ return ImageReader.this;
+ }
+ }
+}