Camera2: Listener rework and other API updates
- Add Handlers to each callback-accepting function
- Expand CameraDevice ErrorListener to CameraDeviceListener
- Add idle callback
- Split out disconnect error to its own callback
- Add CameraDevice#getId
- Rename CameraManager's listener to AvailabilityListener
- Rename CameraManager register/unregister*Listener to
add/remove*Listener
- Rename getDeviceIdList to getCameraIdList
Bug: 10549567
Bug: 10549462
Change-Id: Idd2ae8ad8eb126f35a15d765306ada7c1cf74eea
diff --git a/core/java/android/hardware/camera2/impl/CameraDevice.java b/core/java/android/hardware/camera2/impl/CameraDevice.java
index 86a073f..966fcfa 100644
--- a/core/java/android/hardware/camera2/impl/CameraDevice.java
+++ b/core/java/android/hardware/camera2/impl/CameraDevice.java
@@ -29,6 +29,8 @@
import android.hardware.camera2.utils.CameraRuntimeException;
import android.os.IBinder;
import android.os.RemoteException;
+import android.os.Handler;
+import android.os.Looper;
import android.util.Log;
import android.util.SparseArray;
import android.view.Surface;
@@ -53,10 +55,11 @@
private final Object mLock = new Object();
private final CameraDeviceCallbacks mCallbacks = new CameraDeviceCallbacks();
- // XX: Make this a WeakReference<CaptureListener> ?
- // TODO: Convert to SparseIntArray
- private final HashMap<Integer, CaptureListenerHolder> mCaptureListenerMap =
- new HashMap<Integer, CaptureListenerHolder>();
+ private CameraDeviceListener mDeviceListener;
+ private Handler mDeviceHandler;
+
+ private final SparseArray<CaptureListenerHolder> mCaptureListenerMap =
+ new SparseArray<CaptureListenerHolder>();
private final Stack<Integer> mRepeatingRequestIdStack = new Stack<Integer>();
// Map stream IDs to Surfaces
@@ -80,6 +83,11 @@
}
@Override
+ public String getId() {
+ return mCameraId;
+ }
+
+ @Override
public CameraProperties getProperties() throws CameraAccessException {
CameraProperties properties = new CameraProperties();
@@ -173,14 +181,14 @@
}
@Override
- public void capture(CaptureRequest request, CaptureListener listener)
+ public void capture(CaptureRequest request, CaptureListener listener, Handler handler)
throws CameraAccessException {
- submitCaptureRequest(request, listener, /*streaming*/false);
+ submitCaptureRequest(request, listener, handler, /*streaming*/false);
}
@Override
- public void captureBurst(List<CaptureRequest> requests, CaptureListener listener)
- throws CameraAccessException {
+ public void captureBurst(List<CaptureRequest> requests, CaptureListener listener,
+ Handler handler) throws CameraAccessException {
if (requests.isEmpty()) {
Log.w(TAG, "Capture burst request list is empty, do nothing!");
return;
@@ -191,7 +199,18 @@
}
private void submitCaptureRequest(CaptureRequest request, CaptureListener listener,
- boolean repeating) throws CameraAccessException {
+ Handler handler, boolean repeating) throws CameraAccessException {
+
+ // 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);
+ }
synchronized (mLock) {
@@ -205,9 +224,10 @@
// impossible
return;
}
-
- mCaptureListenerMap.put(requestId, new CaptureListenerHolder(listener, request,
- repeating));
+ if (listener != null) {
+ mCaptureListenerMap.put(requestId, new CaptureListenerHolder(listener, request,
+ handler, repeating));
+ }
if (repeating) {
mRepeatingRequestIdStack.add(requestId);
@@ -217,14 +237,14 @@
}
@Override
- public void setRepeatingRequest(CaptureRequest request, CaptureListener listener)
- throws CameraAccessException {
- submitCaptureRequest(request, listener, /*streaming*/true);
+ public void setRepeatingRequest(CaptureRequest request, CaptureListener listener,
+ Handler handler) throws CameraAccessException {
+ submitCaptureRequest(request, listener, handler, /*streaming*/true);
}
@Override
- public void setRepeatingBurst(List<CaptureRequest> requests, CaptureListener listener)
- throws CameraAccessException {
+ public void setRepeatingBurst(List<CaptureRequest> requests, CaptureListener listener,
+ Handler handler) throws CameraAccessException {
if (requests.isEmpty()) {
Log.w(TAG, "Set Repeating burst request list is empty, do nothing!");
return;
@@ -274,9 +294,11 @@
}
@Override
- public void setErrorListener(ErrorListener listener) {
- // TODO Auto-generated method stub
-
+ public void setDeviceListener(CameraDeviceListener listener, Handler handler) {
+ synchronized (mLock) {
+ mDeviceListener = listener;
+ mDeviceHandler = handler;
+ }
}
@Override
@@ -332,9 +354,16 @@
private final boolean mRepeating;
private final CaptureListener mListener;
private final CaptureRequest mRequest;
+ private final Handler mHandler;
- CaptureListenerHolder(CaptureListener listener, CaptureRequest request, boolean repeating) {
+ CaptureListenerHolder(CaptureListener listener, CaptureRequest request, Handler handler,
+ boolean repeating) {
+ if (listener == null || handler == null) {
+ throw new UnsupportedOperationException(
+ "Must have a valid handler and a valid listener");
+ }
mRepeating = repeating;
+ mHandler = handler;
mRequest = request;
mListener = listener;
}
@@ -350,6 +379,11 @@
public CaptureRequest getRequest() {
return mRequest;
}
+
+ public Handler getHandler() {
+ return mHandler;
+ }
+
}
// TODO: unit tests
@@ -374,7 +408,7 @@
if (DEBUG) {
Log.d(TAG, "Received result for id " + requestId);
}
- CaptureListenerHolder holder;
+ final CaptureListenerHolder holder;
synchronized (mLock) {
// TODO: move this whole map into this class to make it more testable,
@@ -393,18 +427,23 @@
}
}
+ // Check if we have a listener for this
if (holder == null) {
- Log.e(TAG, "Result had no listener holder associated with it, dropping result");
return;
}
- CaptureResult resultAsCapture = new CaptureResult();
+ final CaptureResult resultAsCapture = new CaptureResult();
resultAsCapture.swap(result);
- if (holder.getListener() != null) {
- holder.getListener().onCaptureComplete(CameraDevice.this, holder.getRequest(),
- resultAsCapture);
- }
+ holder.getHandler().post(
+ new Runnable() {
+ public void run() {
+ holder.getListener().onCaptureCompleted(
+ CameraDevice.this,
+ holder.getRequest(),
+ resultAsCapture);
+ }
+ });
}
}