diff options
author | Wu-cheng Li <wuchengli@google.com> | 2012-02-23 19:01:00 -0800 |
---|---|---|
committer | Wu-cheng Li <wuchengli@google.com> | 2012-03-15 14:50:48 +0800 |
commit | a1c41e13b521cdd611a8fc46e43b5ae0a2c00238 (patch) | |
tree | 48877fa91b94c62482519f040e966997a9d214d2 /core | |
parent | 5571ffdd9d419e3b1e050501e6f8dbfb04159b5d (diff) | |
download | frameworks_base-a1c41e13b521cdd611a8fc46e43b5ae0a2c00238.zip frameworks_base-a1c41e13b521cdd611a8fc46e43b5ae0a2c00238.tar.gz frameworks_base-a1c41e13b521cdd611a8fc46e43b5ae0a2c00238.tar.bz2 |
Add a new camera open API that allows taking the ownership.
The purpose is to let face unlock always get the camera
successfully. What happened was the camera applications may
have opened the camera in onResume under the lock screen.
This API lets face unlock take the camera from the camera
application. A new permission will be added, so other
applicatoins won't be able to take the camera from the face
unlock.
bug:5584464
Change-Id: Ib3d9dcbc2161815b68db42327dc01148453704c6
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/hardware/Camera.java | 84 | ||||
-rw-r--r-- | core/jni/android_hardware_Camera.cpp | 25 |
2 files changed, 97 insertions, 12 deletions
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java index aa92efb..83b6986 100644 --- a/core/java/android/hardware/Camera.java +++ b/core/java/android/hardware/Camera.java @@ -236,6 +236,50 @@ public class Camera { /** * Creates a new Camera object to access a particular hardware camera. * + * <p>When <code>force</code> is set to false, this will throw an exception + * if the same camera is already opened by other clients. If true, the other + * client will be disconnected from the camera they opened. If the device + * can only support one camera running at a time, all camera-using clients + * will be disconnected from their cameras. + * + * <p>A camera being held by an application can be taken away by other + * applications at any time. Before the camera is taken, applications will + * get {@link #CAMERA_ERROR_RELEASED} and have some time to clean up. Apps + * receiving this callback must immediately stop video recording and then + * call {@link #release()} on their camera object. Otherwise, it will be + * released by the frameworks in a short time. After receiving + * CAMERA_ERROR_RELEASED, apps should not call any method except <code> + * release</code> and {@link #isReleased()}. After a camera is taken away, + * all methods will throw exceptions except <code>isReleased</code> and + * <code>release</code>. Apps can use <code>isReleased</code> to see if the + * camera has been taken away. If the camera is taken away, the apps can + * silently finish themselves or show a dialog. + * + * <p>Applications with android.permission.KEEP_CAMERA can request to keep + * the camera. That is, the camera will not be taken by other applications + * while it is opened. The permission can only be obtained by trusted + * platform applications, such as those implementing lock screen security + * features. + * + * @param cameraId the hardware camera to access, between 0 and + * {@link #getNumberOfCameras()}-1. + * @param force true to take the ownership from the existing client if the + * camera has been opened by other clients. + * @param keep true if the applications do not want other apps to take the + * camera. Only the apps with android.permission.KEEP_CAMERA can keep + * the camera. + * @return a new Camera object, connected, locked and ready for use. + * @hide + */ + public static Camera open(int cameraId, boolean force, boolean keep) { + return new Camera(cameraId, force, keep); + } + + /** + * Creates a new Camera object to access a particular hardware camera. If + * the same camera is opened by other applications, 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. * @@ -255,13 +299,13 @@ public class Camera { * @param cameraId the hardware camera to access, between 0 and * {@link #getNumberOfCameras()}-1. * @return a new Camera object, connected, locked and ready for use. - * @throws RuntimeException if connection to the camera service fails (for - * example, if the camera is in use by another process or device policy - * manager has disabled the camera). + * @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) */ public static Camera open(int cameraId) { - return new Camera(cameraId); + return new Camera(cameraId, false, false); } /** @@ -276,13 +320,13 @@ public class Camera { for (int i = 0; i < numberOfCameras; i++) { getCameraInfo(i, cameraInfo); if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) { - return new Camera(i); + return new Camera(i, false, false); } } return null; } - Camera(int cameraId) { + Camera(int cameraId, boolean force, boolean keep) { mShutterCallback = null; mRawImageCallback = null; mJpegCallback = null; @@ -299,7 +343,7 @@ public class Camera { mEventHandler = null; } - native_setup(new WeakReference<Camera>(this), cameraId); + native_setup(new WeakReference<Camera>(this), cameraId, force, keep); } /** @@ -312,7 +356,8 @@ public class Camera { release(); } - private native final void native_setup(Object camera_this, int cameraId); + private native final void native_setup(Object camera_this, int cameraId, + boolean force, boolean keep); private native final void native_release(); @@ -327,6 +372,18 @@ public class Camera { } /** + * Whether the camera is released. When any camera method throws an + * exception, applications can use this to check whether the camera has been + * taken by other clients. If true, it means other clients have taken the + * camera. The applications can silently finish themselves or show a dialog. + * + * @return whether the camera is released. + * @see #open(int, boolean, boolean) + * @hide + */ + public native final boolean isReleased(); + + /** * Unlocks the camera to allow another process to access it. * Normally, the camera is locked to the process with an active Camera * object until {@link #release()} is called. To allow rapid handoff @@ -1322,6 +1379,17 @@ public class Camera { public static final int CAMERA_ERROR_UNKNOWN = 1; /** + * Camera was released because another client has opened the camera. The + * application should call {@link #release()} after getting this. The apps + * should not call any method except <code>release</code> and {@link #isReleased()} + * after this. + * + * @see Camera.ErrorCallback + * @hide + */ + public static final int CAMERA_ERROR_RELEASED = 2; + + /** * Media server died. In this case, the application must release the * Camera object and instantiate a new one. * @see Camera.ErrorCallback diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp index 0c66b86..36b4b45 100644 --- a/core/jni/android_hardware_Camera.cpp +++ b/core/jni/android_hardware_Camera.cpp @@ -457,9 +457,9 @@ static void android_hardware_Camera_getCameraInfo(JNIEnv *env, jobject thiz, // connect to camera service static void android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz, - jobject weak_this, jint cameraId) + jobject weak_this, jint cameraId, jboolean force, jboolean keep) { - sp<Camera> camera = Camera::connect(cameraId); + sp<Camera> camera = Camera::connect(cameraId, force, keep); if (camera == NULL) { jniThrowRuntimeException(env, "Fail to connect to camera service"); @@ -700,7 +700,12 @@ static jstring android_hardware_Camera_getParameters(JNIEnv *env, jobject thiz) sp<Camera> camera = get_native_camera(env, thiz, NULL); if (camera == 0) return 0; - return env->NewStringUTF(camera->getParameters().string()); + String8 params8 = camera->getParameters(); + if (params8.isEmpty()) { + jniThrowRuntimeException(env, "getParameters failed (empty parameters)"); + return 0; + } + return env->NewStringUTF(params8.string()); } static void android_hardware_Camera_reconnect(JNIEnv *env, jobject thiz) @@ -816,6 +821,15 @@ static void android_hardware_Camera_enableFocusMoveCallback(JNIEnv *env, jobject } } +static bool android_hardware_Camera_isReleased(JNIEnv *env, jobject thiz) +{ + ALOGV("isReleased"); + sp<Camera> camera = get_native_camera(env, thiz, NULL); + if (camera == 0) return true; + + return (camera->sendCommand(CAMERA_CMD_PING, 0, 0) != NO_ERROR); +} + //------------------------------------------------- static JNINativeMethod camMethods[] = { @@ -826,7 +840,7 @@ static JNINativeMethod camMethods[] = { "(ILandroid/hardware/Camera$CameraInfo;)V", (void*)android_hardware_Camera_getCameraInfo }, { "native_setup", - "(Ljava/lang/Object;I)V", + "(Ljava/lang/Object;IZZ)V", (void*)android_hardware_Camera_native_setup }, { "native_release", "()V", @@ -894,6 +908,9 @@ static JNINativeMethod camMethods[] = { { "enableFocusMoveCallback", "(I)V", (void *)android_hardware_Camera_enableFocusMoveCallback}, + { "isReleased", + "()Z", + (void *)android_hardware_Camera_isReleased}, }; struct field { |