diff options
author | Eino-Ville Talvala <etalvala@google.com> | 2013-09-05 09:04:08 -0700 |
---|---|---|
committer | Eino-Ville Talvala <etalvala@google.com> | 2013-10-03 15:44:32 +0000 |
commit | e841d4e16526a2e466f662305682aa3459d07c15 (patch) | |
tree | a789fa5471f2b21c91c92466e53beabab0fd3eb1 /core/java/android/hardware | |
parent | 778c2de060473636ba7237a460b53a2f03f50f05 (diff) | |
download | frameworks_base-e841d4e16526a2e466f662305682aa3459d07c15.zip frameworks_base-e841d4e16526a2e466f662305682aa3459d07c15.tar.gz frameworks_base-e841d4e16526a2e466f662305682aa3459d07c15.tar.bz2 |
Camera2: Implement idle callbacks
- Rework camera callback binder interface
- Connect up idle, disconnect callbacks
- A few unit tests for shutter firing and idle use
Bug: 10549462
Change-Id: I8455a8a0561e366b7edeef6b101682be2ec44d79
Diffstat (limited to 'core/java/android/hardware')
3 files changed, 124 insertions, 16 deletions
diff --git a/core/java/android/hardware/camera2/ICameraDeviceCallbacks.aidl b/core/java/android/hardware/camera2/ICameraDeviceCallbacks.aidl index 4054a92..02a73d66 100644 --- a/core/java/android/hardware/camera2/ICameraDeviceCallbacks.aidl +++ b/core/java/android/hardware/camera2/ICameraDeviceCallbacks.aidl @@ -25,6 +25,8 @@ interface ICameraDeviceCallbacks * Keep up-to-date with frameworks/av/include/camera/camera2/ICameraDeviceCallbacks.h */ - oneway void notifyCallback(int msgType, int ext1, int ext2); - oneway void onResultReceived(int frameId, in CameraMetadataNative result); + oneway void onCameraError(int errorCode); + oneway void onCameraIdle(); + oneway void onCaptureStarted(int requestId, long timestamp); + oneway void onResultReceived(int requestId, in CameraMetadataNative result); } diff --git a/core/java/android/hardware/camera2/impl/CameraDevice.java b/core/java/android/hardware/camera2/impl/CameraDevice.java index 70a6f44..463063c 100644 --- a/core/java/android/hardware/camera2/impl/CameraDevice.java +++ b/core/java/android/hardware/camera2/impl/CameraDevice.java @@ -183,13 +183,8 @@ public class CameraDevice implements android.hardware.camera2.CameraDevice { // Need a valid handler, or current thread needs to have a looper, if // listener is valid - if (handler == null && listener != null) { - Looper looper = Looper.myLooper(); - if (looper == null) { - throw new IllegalArgumentException( - "No handler given, and current thread has no looper!"); - } - handler = new Handler(looper); + if (listener != null) { + handler = checkHandler(handler); } synchronized (mLock) { @@ -271,12 +266,16 @@ public class CameraDevice implements android.hardware.camera2.CameraDevice { // impossible return; } - } + } } @Override public void setDeviceListener(StateListener listener, Handler handler) { synchronized (mLock) { + if (listener != null) { + handler = checkHandler(handler); + } + mDeviceListener = listener; mDeviceHandler = handler; } @@ -365,21 +364,113 @@ public class CameraDevice implements android.hardware.camera2.CameraDevice { } - // TODO: unit tests public class CameraDeviceCallbacks extends ICameraDeviceCallbacks.Stub { + // + // Constants below need to be kept up-to-date with + // frameworks/av/include/camera/camera2/ICameraDeviceCallbacks.h + // + + // + // Error codes for onCameraError + // + + /** + * Camera has been disconnected + */ + static final int ERROR_CAMERA_DISCONNECTED = 0; + + /** + * Camera has encountered a device-level error + * Matches CameraDevice.StateListener#ERROR_CAMERA_DEVICE + */ + static final int ERROR_CAMERA_DEVICE = 1; + + /** + * Camera has encountered a service-level error + * Matches CameraDevice.StateListener#ERROR_CAMERA_SERVICE + */ + static final int ERROR_CAMERA_SERVICE = 2; + @Override public IBinder asBinder() { return this; } - // TODO: consider rename to onMessageReceived @Override - public void notifyCallback(int msgType, int ext1, int ext2) throws RemoteException { + public void onCameraError(final int errorCode) { + synchronized (mLock) { + if (CameraDevice.this.mDeviceListener == null) return; + final StateListener listener = CameraDevice.this.mDeviceListener; + Runnable r = null; + switch (errorCode) { + case ERROR_CAMERA_DISCONNECTED: + r = new Runnable() { + public void run() { + listener.onDisconnected(CameraDevice.this); + } + }; + break; + case ERROR_CAMERA_DEVICE: + case ERROR_CAMERA_SERVICE: + r = new Runnable() { + public void run() { + listener.onError(CameraDevice.this, errorCode); + } + }; + break; + default: + Log.e(TAG, "Unknown error from camera device: " + errorCode); + } + if (r != null) { + CameraDevice.this.mDeviceHandler.post(r); + } + } + } + + @Override + public void onCameraIdle() { + if (DEBUG) { + Log.d(TAG, "Camera now idle"); + } + synchronized (mLock) { + if (CameraDevice.this.mDeviceListener == null) return; + final StateListener listener = CameraDevice.this.mDeviceListener; + Runnable r = new Runnable() { + public void run() { + listener.onIdle(CameraDevice.this); + } + }; + CameraDevice.this.mDeviceHandler.post(r); + } + } + + @Override + public void onCaptureStarted(int requestId, final long timestamp) { if (DEBUG) { - Log.d(TAG, "Got message " + msgType + " ext1: " + ext1 + " , ext2: " + ext2); + Log.d(TAG, "Capture started for id " + requestId); + } + final CaptureListenerHolder holder; + + // Get the listener for this frame ID, if there is one + synchronized (mLock) { + holder = CameraDevice.this.mCaptureListenerMap.get(requestId); } - // TODO implement rest + + if (holder == null) { + return; + } + + // Dispatch capture start notice + holder.getHandler().post( + new Runnable() { + public void run() { + holder.getListener().onCaptureStarted( + CameraDevice.this, + holder.getRequest(), + timestamp); + } + }); } @Override @@ -429,6 +520,22 @@ public class CameraDevice implements android.hardware.camera2.CameraDevice { } + /** + * Default handler management. If handler is null, get the current thread's + * Looper to create a Handler with. If no looper exists, throw exception. + */ + private Handler checkHandler(Handler handler) { + if (handler == null) { + Looper looper = Looper.myLooper(); + if (looper == null) { + throw new IllegalArgumentException( + "No handler given, and current thread has no looper!"); + } + handler = new Handler(looper); + } + return handler; + } + private void checkIfCameraClosed() { if (mRemoteDevice == null) { throw new IllegalStateException("CameraDevice was already closed"); diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java index 6d7b03e..6d04bf8 100644 --- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java +++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java @@ -652,7 +652,6 @@ public class CameraMetadataNative extends CameraMetadata implements Parcelable { * We use a class initializer to allow the native code to cache some field offsets */ static { - System.loadLibrary("media_jni"); nativeClassInit(); Log.v(TAG, "Shall register metadata marshalers"); |