summaryrefslogtreecommitdiff
path: root/libs/ui/Camera.cpp
diff options
context:
space:
mode:
author Dave Sparks <davidsparks@android.com> 2009-06-23 17:30:11 -0700
committer Dave Sparks <davidsparks@android.com> 2009-06-24 07:58:27 -0700
commitbbbc7cb77efba3dd46e9d13fc22e81cff17c35d2 (patch)
treead5f5dd2ecdc50bed94d205d4ee05b006551a84e /libs/ui/Camera.cpp
parentc8be159ba67931ae38c552fc7b9da6084ca5a60a (diff)
Use a ref-counted callback interface for Camera.
This allows the camera service to hang onto the callback interface until all callbacks have been processed. This prevents problems where pending callbacks in binder worker threads are processed after the Java camera object and its associated native resources have been released. Bug 1884362
Diffstat (limited to 'libs/ui/Camera.cpp')
-rw-r--r--libs/ui/Camera.cpp33
1 files changed, 33 insertions, 0 deletions
diff --git a/libs/ui/Camera.cpp b/libs/ui/Camera.cpp
index 661370040e..1aa5245202 100644
--- a/libs/ui/Camera.cpp
+++ b/libs/ui/Camera.cpp
@@ -337,9 +337,32 @@ void Camera::setErrorCallback(error_callback cb, void *cookie)
mErrorCallbackCookie = cookie;
}
+void Camera::setListener(const sp<CameraListener>& listener)
+{
+ Mutex::Autolock _l(mLock);
+ mListener = listener;
+}
+
+void Camera::setPreviewCallbackFlags(int flag)
+{
+ LOGV("setPreviewCallbackFlags");
+ sp <ICamera> c = mCamera;
+ if (c == 0) return;
+ mCamera->setPreviewCallbackFlag(flag);
+}
+
// callback from camera service
void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
{
+ sp<CameraListener> listener;
+ {
+ Mutex::Autolock _l(mLock);
+ listener = mListener;
+ }
+ if (listener != NULL) {
+ listener->notify(msgType, ext1, ext2);
+ }
+
switch(msgType) {
case CAMERA_MSG_ERROR:
LOGV("errorCallback");
@@ -368,6 +391,15 @@ void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
// callback from camera service when frame or image is ready
void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr)
{
+ sp<CameraListener> listener;
+ {
+ Mutex::Autolock _l(mLock);
+ listener = mListener;
+ }
+ if (listener != NULL) {
+ listener->postData(msgType, dataPtr);
+ }
+
switch(msgType) {
case CAMERA_MSG_PREVIEW_FRAME:
LOGV("previewCallback");
@@ -401,6 +433,7 @@ void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr)
void Camera::binderDied(const wp<IBinder>& who) {
LOGW("ICamera died");
+ notifyCallback(CAMERA_MSG_ERROR, DEAD_OBJECT, 0);
if (mErrorCallback) {
mErrorCallback(DEAD_OBJECT, mErrorCallbackCookie);
}