diff options
| author | 2016-03-09 03:43:00 +0000 | |
|---|---|---|
| committer | 2016-03-09 03:43:01 +0000 | |
| commit | f52ebd119e76187366e9f9d0f388fbdef46a33c8 (patch) | |
| tree | 4ae8d886a52b85a473bf22e91c413d4a7180d87f | |
| parent | 7f284419f7fb028746ba738068359657a75f426a (diff) | |
| parent | 783929368b554b1fc85da81137e1762fb939c4d7 (diff) | |
Merge "Camera2: Handle binder death on ICameraDeviceUser" into nyc-dev
| -rw-r--r-- | core/java/android/hardware/camera2/CameraManager.java | 2 | ||||
| -rw-r--r-- | core/java/android/hardware/camera2/impl/CameraDeviceImpl.java | 50 |
2 files changed, 50 insertions, 2 deletions
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java index b3c8e3bb2efd..04e64af8c25e 100644 --- a/core/java/android/hardware/camera2/CameraManager.java +++ b/core/java/android/hardware/camera2/CameraManager.java @@ -358,6 +358,8 @@ public final class CameraManager { // TODO: factor out callback to be non-nested, then move setter to constructor // For now, calling setRemoteDevice will fire initial // onOpened/onUnconfigured callbacks. + // This function call may post onDisconnected and throw CAMERA_DISCONNECTED if + // cameraUser dies during setup. deviceImpl.setRemoteDevice(cameraUser); device = deviceImpl; } diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java index 00dd7802526a..37d2ea2badfb 100644 --- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java @@ -63,7 +63,8 @@ import java.util.TreeMap; /** * HAL2.1+ implementation of CameraDevice. Use CameraManager#open to instantiate */ -public class CameraDeviceImpl extends CameraDevice { +public class CameraDeviceImpl extends CameraDevice + implements IBinder.DeathRecipient { private final String TAG; private final boolean DEBUG = false; @@ -261,7 +262,14 @@ public class CameraDeviceImpl extends CameraDevice { return mCallbacks; } - public void setRemoteDevice(ICameraDeviceUser remoteDevice) { + /** + * Set remote device, which triggers initial onOpened/onUnconfigured callbacks + * + * <p>This function may post onDisconnected and throw CAMERA_DISCONNECTED if remoteDevice dies + * during setup.</p> + * + */ + public void setRemoteDevice(ICameraDeviceUser remoteDevice) throws CameraAccessException { synchronized(mInterfaceLock) { // TODO: Move from decorator to direct binder-mediated exceptions // If setRemoteFailure already called, do nothing @@ -269,6 +277,20 @@ public class CameraDeviceImpl extends CameraDevice { mRemoteDevice = new ICameraDeviceUserWrapper(remoteDevice); + IBinder remoteDeviceBinder = remoteDevice.asBinder(); + // For legacy camera device, remoteDevice is in the same process, and + // asBinder returns NULL. + if (remoteDeviceBinder != null) { + try { + remoteDeviceBinder.linkToDeath(this, /*flag*/ 0); + } catch (RemoteException e) { + CameraDeviceImpl.this.mDeviceHandler.post(mCallOnDisconnected); + + throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED, + "The camera device has encountered a serious error"); + } + } + mDeviceHandler.post(mCallOnOpened); mDeviceHandler.post(mCallOnUnconfigured); } @@ -1962,4 +1984,28 @@ public class CameraDeviceImpl extends CameraDevice { return mCharacteristics; } + /** + * Listener for binder death. + * + * <p> Handle binder death for ICameraDeviceUser. Trigger onError.</p> + */ + public void binderDied() { + Log.w(TAG, "CameraDevice " + mCameraId + " died unexpectedly"); + + if (mRemoteDevice == null) { + return; // Camera already closed + } + + mInError = true; + Runnable r = new Runnable() { + @Override + public void run() { + if (!isClosed()) { + mDeviceCallback.onError(CameraDeviceImpl.this, + CameraDeviceCallbacks.ERROR_CAMERA_SERVICE); + } + } + }; + CameraDeviceImpl.this.mDeviceHandler.post(r); + } } |