Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e1a75447 authored by Android (Google) Code Review's avatar Android (Google) Code Review
Browse files

Merge change 5158 into donut

* changes:
  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
parents c8be159b bbbc7cb7
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -86,6 +86,14 @@ class Surface;
class Mutex;
class String8;

// ref-counted object for callbacks
class CameraListener: virtual public RefBase
{
public:
    virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2) = 0;
    virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr) = 0;
};

typedef void (*shutter_callback)(void *cookie);
typedef void (*frame_callback)(const sp<IMemory>& mem, void *cookie);
typedef void (*autofocus_callback)(bool focused, void *cookie);
@@ -152,6 +160,9 @@ public:
            void        setErrorCallback(error_callback cb, void *cookie);
            void        setAutoFocusCallback(autofocus_callback cb, void *cookie);

            void        setListener(const sp<CameraListener>& listener);
            void        setPreviewCallbackFlags(int preview_callback_flag);

    // ICameraClient interface
    virtual void        notifyCallback(int32_t msgType, int32_t ext, int32_t ext2);
    virtual void        dataCallback(int32_t msgType, const sp<IMemory>& dataPtr);
@@ -194,6 +205,8 @@ private:
            autofocus_callback  mAutoFocusCallback;
            void                *mAutoFocusCallbackCookie;

            sp<CameraListener>  mListener;

            friend class DeathNotifier;

            static  Mutex               mLock;
+33 −0
Original line number Diff line number Diff line
@@ -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);
    }