camera: Update Camera2 API for arbitration.

- Update documentation for new arbitration behavior.
- Ensure an appropriate error is thrown when calling
  open while an existing, higher-priority user holds
  the camera device.

Bug: 19186859
Change-Id: I486193c14b7fd5dc6ce30c1b7471669c009d64b3
This commit is contained in:
Ruben Brunk
2015-04-17 14:23:40 -07:00
parent 83bb765b04
commit 0f2be13dc6
2 changed files with 32 additions and 13 deletions

View File

@@ -580,7 +580,8 @@ public abstract class CameraDevice implements AutoCloseable {
* indicating that the camera device is in use already. * indicating that the camera device is in use already.
* *
* <p> * <p>
* This error can be produced when opening the camera fails. * This error can be produced when opening the camera fails due to the camera
* being used by a higher-priority camera API client.
* </p> * </p>
* *
* @see #onError * @see #onError
@@ -678,7 +679,7 @@ public abstract class CameraDevice implements AutoCloseable {
* {@link CameraAccessException}. The disconnection could be due to a * {@link CameraAccessException}. The disconnection could be due to a
* change in security policy or permissions; the physical disconnection * change in security policy or permissions; the physical disconnection
* of a removable camera device; or the camera being needed for a * of a removable camera device; or the camera being needed for a
* higher-priority use case.</p> * higher-priority camera API client.</p>
* *
* <p>There may still be capture callbacks that are invoked * <p>There may still be capture callbacks that are invoked
* after this method is called, or new image buffers that are delivered * after this method is called, or new image buffers that are delivered
@@ -688,8 +689,9 @@ public abstract class CameraDevice implements AutoCloseable {
* about the disconnection.</p> * about the disconnection.</p>
* *
* <p>You should clean up the camera with {@link CameraDevice#close} after * <p>You should clean up the camera with {@link CameraDevice#close} after
* this happens, as it is not recoverable until opening the camera again * this happens, as it is not recoverable until the camera can be opened
* after it becomes {@link CameraManager.AvailabilityCallback#onCameraAvailable available}. * again. For most use cases, this will be when the camera again becomes
* {@link CameraManager.AvailabilityCallback#onCameraAvailable available}.
* </p> * </p>
* *
* @param camera the device that has been disconnected * @param camera the device that has been disconnected

View File

@@ -77,8 +77,8 @@ public final class CameraManager {
} }
/** /**
* Return the list of currently connected camera devices by * Return the list of currently connected camera devices by identifier, including
* identifier. * cameras that may be in use by other camera API clients.
* *
* <p>Non-removable cameras use integers starting at 0 for their * <p>Non-removable cameras use integers starting at 0 for their
* identifiers, while removable cameras have a unique identifier for each * identifiers, while removable cameras have a unique identifier for each
@@ -103,6 +103,11 @@ public final class CameraManager {
* <p>The first time a callback is registered, it is immediately called * <p>The first time a callback is registered, it is immediately called
* with the availability status of all currently known camera devices.</p> * with the availability status of all currently known camera devices.</p>
* *
* <p>{@link AvailabilityCallback#onCameraUnavailable(String)} will be called whenever a camera
* device is opened by any camera API client. As of API level 23, other camera API clients may
* still be able to open such a camera device, evicting the existing client if they have higher
* priority than the existing client of a camera device. See open() for more details.</p>
*
* <p>Since this callback will be registered with the camera service, remember to unregister it * <p>Since this callback will be registered with the camera service, remember to unregister it
* once it is no longer needed; otherwise the callback will continue to receive events * once it is no longer needed; otherwise the callback will continue to receive events
* indefinitely and it may prevent other resources from being released. Specifically, the * indefinitely and it may prevent other resources from being released. Specifically, the
@@ -259,14 +264,14 @@ public final class CameraManager {
} }
/** /**
* Helper for openning a connection to a camera with the given ID. * Helper for opening a connection to a camera with the given ID.
* *
* @param cameraId The unique identifier of the camera device to open * @param cameraId The unique identifier of the camera device to open
* @param callback The callback for the camera. Must not be null. * @param callback The callback for the camera. Must not be null.
* @param handler The handler to invoke the callback on. Must not be null. * @param handler The handler to invoke the callback on. Must not be null.
* *
* @throws CameraAccessException if the camera is disabled by device policy, * @throws CameraAccessException if the camera is disabled by device policy,
* or too many camera devices are already open, or the cameraId does not match * too many camera devices are already open, or the cameraId does not match
* any currently available camera device. * any currently available camera device.
* *
* @throws SecurityException if the application does not have permission to * @throws SecurityException if the application does not have permission to
@@ -330,7 +335,8 @@ public final class CameraManager {
deviceImpl.setRemoteFailure(e); deviceImpl.setRemoteFailure(e);
if (e.getReason() == CameraAccessException.CAMERA_DISABLED || if (e.getReason() == CameraAccessException.CAMERA_DISABLED ||
e.getReason() == CameraAccessException.CAMERA_DISCONNECTED) { e.getReason() == CameraAccessException.CAMERA_DISCONNECTED ||
e.getReason() == CameraAccessException.CAMERA_IN_USE) {
// Per API docs, these failures call onError and throw // Per API docs, these failures call onError and throw
throw e.asChecked(); throw e.asChecked();
} }
@@ -369,7 +375,19 @@ public final class CameraManager {
* <p>Use {@link #getCameraIdList} to get the list of available camera * <p>Use {@link #getCameraIdList} to get the list of available camera
* devices. Note that even if an id is listed, open may fail if the device * devices. Note that even if an id is listed, open may fail if the device
* is disconnected between the calls to {@link #getCameraIdList} and * is disconnected between the calls to {@link #getCameraIdList} and
* {@link #openCamera}.</p> * {@link #openCamera}, or if a higher-priority camera API client begins using the
* camera device.</p>
*
* <p>As of API level 23, devices for which the
* {@link AvailabilityCallback#onCameraUnavailable(String)} callback has been called due to the
* device being in use by a lower-priority, background camera API client can still potentially
* be opened by calling this method when the calling camera API client has a higher priority
* than the current camera API client using this device. In general, if the top, foreground
* activity is running within your application process, your process will be given the highest
* priority when accessing the camera, and this method will succeed even if the camera device is
* in use by another camera API client. Any lower-priority application that loses control of the
* camera in this way will receive an
* {@link android.hardware.camera2.CameraDevice.StateCallback#onDisconnected} callback.</p>
* *
* <p>Once the camera is successfully opened, {@link CameraDevice.StateCallback#onOpened} will * <p>Once the camera is successfully opened, {@link CameraDevice.StateCallback#onOpened} will
* be invoked with the newly opened {@link CameraDevice}. The camera device can then be set up * be invoked with the newly opened {@link CameraDevice}. The camera device can then be set up
@@ -401,7 +419,7 @@ public final class CameraManager {
* {@code null} to use the current thread's {@link android.os.Looper looper}. * {@code null} to use the current thread's {@link android.os.Looper looper}.
* *
* @throws CameraAccessException if the camera is disabled by device policy, * @throws CameraAccessException if the camera is disabled by device policy,
* or the camera has become or was disconnected. * has been disconnected, or is being used by a higher-priority camera API client.
* *
* @throws IllegalArgumentException if cameraId or the callback was null, * @throws IllegalArgumentException if cameraId or the callback was null,
* or the cameraId does not match any currently or previously available * or the cameraId does not match any currently or previously available
@@ -477,8 +495,7 @@ public final class CameraManager {
} }
/** /**
* A callback for camera devices becoming available or * A callback for camera devices becoming available or unavailable to open.
* unavailable to open.
* *
* <p>Cameras become available when they are no longer in use, or when a new * <p>Cameras become available when they are no longer in use, or when a new
* removable camera is connected. They become unavailable when some * removable camera is connected. They become unavailable when some