summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/java/android/hardware/Camera.java131
-rw-r--r--core/java/android/hardware/ICameraService.aidl7
-rw-r--r--core/jni/android_hardware_Camera.cpp19
3 files changed, 150 insertions, 7 deletions
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 0705e0c..44fc3b6 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -172,6 +172,11 @@ public class Camera {
private static final int NO_ERROR = 0;
private static final int EACCESS = -13;
private static final int ENODEV = -19;
+ private static final int EBUSY = -16;
+ private static final int EINVAL = -22;
+ private static final int ENOSYS = -38;
+ private static final int EUSERS = -87;
+ private static final int EOPNOTSUPP = -95;
/**
* Broadcast Action: A new picture is taken by the camera, and the entry of
@@ -190,6 +195,22 @@ public class Camera {
public static final String ACTION_NEW_VIDEO = "android.hardware.action.NEW_VIDEO";
/**
+ * Camera HAL device API version 1.0
+ * @hide
+ */
+ public static final int CAMERA_HAL_API_VERSION_1_0 = 0x100;
+
+ /**
+ * A constant meaning the normal camera connect/open will be used.
+ * @hide
+ */
+ public static final int CAMERA_HAL_API_VERSION_NORMAL_OPEN = -2;
+
+ /**
+ * Used to indicate HAL version un-specified.
+ */
+ private static final int CAMERA_HAL_API_VERSION_UNSPECIFIED = -1;
+ /**
* Hardware face detection. It does not use much CPU.
*/
private static final int CAMERA_FACE_DETECTION_HW = 0;
@@ -331,6 +352,111 @@ public class Camera {
return null;
}
+ /**
+ * Creates a new Camera object to access a particular hardware camera with
+ * given hal API version. If the same camera is opened by other applications
+ * or the hal API version is not supported by this device, this will throw a
+ * RuntimeException.
+ * <p>
+ * You must call {@link #release()} when you are done using the camera,
+ * otherwise it will remain locked and be unavailable to other applications.
+ * <p>
+ * Your application should only have one Camera object active at a time for
+ * a particular hardware camera.
+ * <p>
+ * Callbacks from other methods are delivered to the event loop of the
+ * thread which called open(). If this thread has no event loop, then
+ * callbacks are delivered to the main application event loop. If there is
+ * no main application event loop, callbacks are not delivered.
+ * <p class="caution">
+ * <b>Caution:</b> On some devices, this method may take a long time to
+ * complete. It is best to call this method from a worker thread (possibly
+ * using {@link android.os.AsyncTask}) to avoid blocking the main
+ * application UI thread.
+ *
+ * @param cameraId The hardware camera to access, between 0 and
+ * {@link #getNumberOfCameras()}-1.
+ * @param halVersion The HAL API version this camera device to be opened as. When
+ * it is {@value #CAMERA_HAL_API_VERSION_NORMAL_OPEN}, the methods will be equivalent
+ * to {@link #open}, but more detailed error information will be returned to managed code.
+ * @return a new Camera object, connected, locked and ready for use.
+ * @throws RuntimeException if opening the camera fails (for example, if the
+ * camera is in use by another process or device policy manager has disabled
+ * the camera).
+ * @see android.app.admin.DevicePolicyManager#getCameraDisabled(android.content.ComponentName)
+ *
+ * @hide
+ */
+ public static Camera openLegacy(int cameraId, int halVersion) {
+ return new Camera(cameraId, halVersion);
+ }
+
+ /**
+ * Create a legacy camera object.
+ *
+ * @param cameraId The hardware camera to access, between 0 and
+ * {@link #getNumberOfCameras()}-1.
+ * @param halVersion The HAL API version this camera device to be opened as.
+ */
+ private Camera(int cameraId, int halVersion) {
+ int err = cameraInit(cameraId, halVersion);
+ if (checkInitErrors(err)) {
+ switch(err) {
+ case EACCESS:
+ throw new RuntimeException("Fail to connect to camera service");
+ case ENODEV:
+ throw new RuntimeException("Camera initialization failed");
+ case ENOSYS:
+ throw new RuntimeException("Camera initialization failed because some methods"
+ + " are not implemented");
+ case EOPNOTSUPP:
+ throw new RuntimeException("Camera initialization failed because the hal"
+ + " version is not supported by this device");
+ case EINVAL:
+ throw new RuntimeException("Camera initialization failed because the input"
+ + " arugments are invalid");
+ case EBUSY:
+ throw new RuntimeException("Camera initialization failed because the camera"
+ + " device was already opened");
+ case EUSERS:
+ throw new RuntimeException("Camera initialization failed because the max"
+ + " number of camera devices were already opened");
+ default:
+ // Should never hit this.
+ throw new RuntimeException("Unknown camera error");
+ }
+ }
+ }
+
+ private int cameraInit(int cameraId, int halVersion) {
+ // This function should be only called by Camera(int cameraId, int halVersion).
+ if (halVersion < CAMERA_HAL_API_VERSION_1_0 &&
+ halVersion != CAMERA_HAL_API_VERSION_NORMAL_OPEN) {
+ throw new IllegalArgumentException("Invalid HAL version " + halVersion);
+ }
+
+ mShutterCallback = null;
+ mRawImageCallback = null;
+ mJpegCallback = null;
+ mPreviewCallback = null;
+ mPostviewCallback = null;
+ mUsingPreviewAllocation = false;
+ mZoomListener = null;
+
+ Looper looper;
+ if ((looper = Looper.myLooper()) != null) {
+ mEventHandler = new EventHandler(this, looper);
+ } else if ((looper = Looper.getMainLooper()) != null) {
+ mEventHandler = new EventHandler(this, looper);
+ } else {
+ mEventHandler = null;
+ }
+
+ String packageName = ActivityThread.currentPackageName();
+
+ return native_setup(new WeakReference<Camera>(this), cameraId, halVersion, packageName);
+ }
+
Camera(int cameraId) {
int err = cameraInit(cameraId);
if (checkInitErrors(err)) {
@@ -369,7 +495,8 @@ public class Camera {
String packageName = ActivityThread.currentPackageName();
- return native_setup(new WeakReference<Camera>(this), cameraId, packageName);
+ return native_setup(new WeakReference<Camera>(this), cameraId,
+ CAMERA_HAL_API_VERSION_UNSPECIFIED, packageName);
}
/**
@@ -396,7 +523,7 @@ public class Camera {
release();
}
- private native final int native_setup(Object camera_this, int cameraId,
+ private native final int native_setup(Object camera_this, int cameraId, int halVersion,
String packageName);
private native final void native_release();
diff --git a/core/java/android/hardware/ICameraService.aidl b/core/java/android/hardware/ICameraService.aidl
index 31896f5..2bc3dd4 100644
--- a/core/java/android/hardware/ICameraService.aidl
+++ b/core/java/android/hardware/ICameraService.aidl
@@ -74,4 +74,11 @@ interface ICameraService
int getLegacyParameters(int cameraId, out String[] parameters);
// Determines if a particular API version is supported; see ICameraService.h for version defines
int supportsCameraApi(int cameraId, int apiVersion);
+
+ int connectLegacy(ICameraClient client, int cameraId,
+ int halVersion,
+ String clientPackageName,
+ int clientUid,
+ // Container for an ICamera object
+ out BinderHolder device);
}
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index 3a53331..4c9feca 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -466,7 +466,7 @@ static void android_hardware_Camera_getCameraInfo(JNIEnv *env, jobject thiz,
// connect to camera service
static jint android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,
- jobject weak_this, jint cameraId, jstring clientPackageName)
+ jobject weak_this, jint cameraId, jint halVersion, jstring clientPackageName)
{
// Convert jstring to String16
const char16_t *rawClientName = env->GetStringChars(clientPackageName, NULL);
@@ -474,8 +474,18 @@ static jint android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,
String16 clientName(rawClientName, rawClientNameLen);
env->ReleaseStringChars(clientPackageName, rawClientName);
- sp<Camera> camera = Camera::connect(cameraId, clientName,
- Camera::USE_CALLING_UID);
+ sp<Camera> camera;
+ if (halVersion == ICameraService::CAMERA_HAL_API_VERSION_UNSPECIFIED) {
+ // Default path: hal version is unspecified, do normal camera open.
+ camera = Camera::connect(cameraId, clientName,
+ Camera::USE_CALLING_UID);
+ } else {
+ jint status = Camera::connectLegacy(cameraId, halVersion, clientName,
+ Camera::USE_CALLING_UID, camera);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ }
if (camera == NULL) {
return -EACCES;
@@ -510,7 +520,6 @@ static jint android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,
// finalizer is invoked later.
static void android_hardware_Camera_release(JNIEnv *env, jobject thiz)
{
- // TODO: Change to ALOGV
ALOGV("release camera");
JNICameraContext* context = NULL;
sp<Camera> camera;
@@ -891,7 +900,7 @@ static JNINativeMethod camMethods[] = {
"(ILandroid/hardware/Camera$CameraInfo;)V",
(void*)android_hardware_Camera_getCameraInfo },
{ "native_setup",
- "(Ljava/lang/Object;ILjava/lang/String;)I",
+ "(Ljava/lang/Object;IILjava/lang/String;)I",
(void*)android_hardware_Camera_native_setup },
{ "native_release",
"()V",