Camera: use wp for NotificationListener

Bug: 30737827
Change-Id: I01b8bee39fe329bf250b9179a84a8928d209a357
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index c0d6da6..ccd1e4d 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -104,7 +104,8 @@
         return res;
     }
 
-    res = mDevice->setNotifyCallback(this);
+    wp<CameraDeviceBase::NotificationListener> weakThis(this);
+    res = mDevice->setNotifyCallback(weakThis);
 
     return OK;
 }
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index 8707f2a..984d84b 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -190,7 +190,7 @@
     /**
      * Abstract class for HAL notification listeners
      */
-    class NotificationListener {
+    class NotificationListener : public virtual RefBase {
       public:
         // The set of notifications is a merge of the notifications required for
         // API1 and API2.
@@ -219,7 +219,7 @@
      * Connect HAL notifications to a listener. Overwrites previous
      * listener. Set to NULL to stop receiving notifications.
      */
-    virtual status_t setNotifyCallback(NotificationListener *listener) = 0;
+    virtual status_t setNotifyCallback(wp<NotificationListener> listener) = 0;
 
     /**
      * Whether the device supports calling notifyAutofocus, notifyAutoExposure,
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 40f8e75..5703934 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -256,7 +256,7 @@
     ATRACE_CALL();
     Mutex::Autolock il(mInterfaceLock);
 
-    ALOGV("%s: E", __FUNCTION__);
+    ALOGI("%s: E", __FUNCTION__);
 
     status_t res = OK;
 
@@ -333,7 +333,7 @@
         internalUpdateStatusLocked(STATUS_UNINITIALIZED);
     }
 
-    ALOGV("%s: X", __FUNCTION__);
+    ALOGI("%s: X", __FUNCTION__);
     return res;
 }
 
@@ -1479,7 +1479,7 @@
 }
 
 
-status_t Camera3Device::setNotifyCallback(NotificationListener *listener) {
+status_t Camera3Device::setNotifyCallback(wp<NotificationListener> listener) {
     ATRACE_CALL();
     Mutex::Autolock l(mOutputLock);
 
@@ -1612,15 +1612,9 @@
     ALOGV("%s: Camera %d: Flushing all requests", __FUNCTION__, mId);
     Mutex::Autolock il(mInterfaceLock);
 
-    NotificationListener* listener;
-    {
-        Mutex::Autolock l(mOutputLock);
-        listener = mListener;
-    }
-
     {
         Mutex::Autolock l(mLock);
-        mRequestThread->clear(listener, /*out*/frameNumber);
+        mRequestThread->clear(/*out*/frameNumber);
     }
 
     status_t res;
@@ -1746,10 +1740,11 @@
         // state changes
         if (mPauseStateNotify) return;
     }
-    NotificationListener *listener;
+
+    sp<NotificationListener> listener;
     {
         Mutex::Autolock l(mOutputLock);
-        listener = mListener;
+        listener = mListener.promote();
     }
     if (idle && listener != NULL) {
         listener->notifyIdle();
@@ -2169,8 +2164,9 @@
     internalUpdateStatusLocked(STATUS_ERROR);
 
     // Notify upstream about a device error
-    if (mListener != NULL) {
-        mListener->notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE,
+    sp<NotificationListener> listener = mListener.promote();
+    if (listener != NULL) {
+        listener->notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE,
                 CaptureResultExtras());
     }
 
@@ -2563,10 +2559,10 @@
 
 void Camera3Device::notify(const camera3_notify_msg *msg) {
     ATRACE_CALL();
-    NotificationListener *listener;
+    sp<NotificationListener> listener;
     {
         Mutex::Autolock l(mOutputLock);
-        listener = mListener;
+        listener = mListener.promote();
     }
 
     if (msg == NULL) {
@@ -2590,7 +2586,7 @@
 }
 
 void Camera3Device::notifyError(const camera3_error_msg_t &msg,
-        NotificationListener *listener) {
+        sp<NotificationListener> listener) {
 
     // Map camera HAL error codes to ICameraDeviceCallback error codes
     // Index into this with the HAL error code
@@ -2661,7 +2657,7 @@
 }
 
 void Camera3Device::notifyShutter(const camera3_shutter_msg_t &msg,
-        NotificationListener *listener) {
+        sp<NotificationListener> listener) {
     ssize_t idx;
 
     // Set timestamp for the request in the in-flight tracking
@@ -2770,7 +2766,7 @@
 }
 
 void Camera3Device::RequestThread::setNotificationListener(
-        NotificationListener *listener) {
+        wp<NotificationListener> listener) {
     Mutex::Autolock l(mRequestLock);
     mListener = listener;
 }
@@ -2905,7 +2901,6 @@
 }
 
 status_t Camera3Device::RequestThread::clear(
-        NotificationListener *listener,
         /*out*/int64_t *lastFrameNumber) {
     Mutex::Autolock l(mRequestLock);
     ALOGV("RequestThread::%s:", __FUNCTION__);
@@ -2914,6 +2909,7 @@
 
     // Send errors for all requests pending in the request queue, including
     // pending repeating requests
+    sp<NotificationListener> listener = mListener.promote();
     if (listener != NULL) {
         for (RequestList::iterator it = mRequestQueue.begin();
                  it != mRequestQueue.end(); ++it) {
@@ -3053,6 +3049,7 @@
 void Camera3Device::RequestThread::checkAndStopRepeatingRequest() {
     bool surfaceAbandoned = false;
     int64_t lastFrameNumber = 0;
+    sp<NotificationListener> listener;
     {
         Mutex::Autolock l(mRequestLock);
         // Check all streams needed by repeating requests are still valid. Otherwise, stop
@@ -3069,9 +3066,11 @@
                 break;
             }
         }
+        listener = mListener.promote();
     }
-    if (surfaceAbandoned) {
-        mListener->notifyRepeatingRequestError(lastFrameNumber);
+
+    if (listener != NULL && surfaceAbandoned) {
+        listener->notifyRepeatingRequestError(lastFrameNumber);
     }
 }
 
@@ -3414,8 +3413,9 @@
 
         if (sendRequestError) {
             Mutex::Autolock l(mRequestLock);
-            if (mListener != NULL) {
-                mListener->notifyError(
+            sp<NotificationListener> listener = mListener.promote();
+            if (listener != NULL) {
+                listener->notifyError(
                         hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
                         captureRequest->mResultExtras);
             }
@@ -3554,8 +3554,10 @@
                 // error
                 ALOGE("%s: Can't get input buffer, skipping request:"
                         " %s (%d)", __FUNCTION__, strerror(-res), res);
-                if (mListener != NULL) {
-                    mListener->notifyError(
+
+                sp<NotificationListener> listener = mListener.promote();
+                if (listener != NULL) {
+                    listener->notifyError(
                             hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
                             nextRequest->mResultExtras);
                 }
@@ -3835,13 +3837,14 @@
     status_t res;
 
     Mutex::Autolock l(mLock);
+    sp<NotificationListener> listener = mListener.promote();
 
     res = stream->startPrepare(maxCount);
     if (res == OK) {
         // No preparation needed, fire listener right off
         ALOGV("%s: Stream %d already prepared", __FUNCTION__, stream->getId());
-        if (mListener) {
-            mListener->notifyPrepared(stream->getId());
+        if (listener != NULL) {
+            listener->notifyPrepared(stream->getId());
         }
         return OK;
     } else if (res != NOT_ENOUGH_DATA) {
@@ -3856,8 +3859,8 @@
         res = Thread::run("C3PrepThread", PRIORITY_BACKGROUND);
         if (res != OK) {
             ALOGE("%s: Unable to start preparer stream: %d (%s)", __FUNCTION__, res, strerror(-res));
-            if (mListener) {
-                mListener->notifyPrepared(stream->getId());
+            if (listener != NULL) {
+                listener->notifyPrepared(stream->getId());
             }
             return res;
         }
@@ -3885,7 +3888,7 @@
     return OK;
 }
 
-void Camera3Device::PreparerThread::setNotificationListener(NotificationListener *listener) {
+void Camera3Device::PreparerThread::setNotificationListener(wp<NotificationListener> listener) {
     Mutex::Autolock l(mLock);
     mListener = listener;
 }
@@ -3932,10 +3935,11 @@
 
     // This stream has finished, notify listener
     Mutex::Autolock l(mLock);
-    if (mListener) {
+    sp<NotificationListener> listener = mListener.promote();
+    if (listener != NULL) {
         ALOGV("%s: Stream %d prepare done, signaling listener", __FUNCTION__,
                 mCurrentStream->getId());
-        mListener->notifyPrepared(mCurrentStream->getId());
+        listener->notifyPrepared(mCurrentStream->getId());
     }
 
     ATRACE_ASYNC_END("stream prepare", mCurrentStream->getId());
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 430ee6c..3244258 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -132,7 +132,7 @@
     // Transitions to the idle state on success
     virtual status_t waitUntilDrained();
 
-    virtual status_t setNotifyCallback(NotificationListener *listener);
+    virtual status_t setNotifyCallback(wp<NotificationListener> listener);
     virtual bool     willNotify3A();
     virtual status_t waitForNextFrame(nsecs_t timeout);
     virtual status_t getNextResult(CaptureResult *frame);
@@ -460,7 +460,7 @@
                 camera3_device_t *hal3Device,
                 bool aeLockAvailable);
 
-        void     setNotificationListener(NotificationListener *listener);
+        void     setNotificationListener(wp<NotificationListener> listener);
 
         /**
          * Call after stream (re)-configuration is completed.
@@ -485,9 +485,7 @@
         /**
          * Remove all queued and repeating requests, and pending triggers
          */
-        status_t clear(NotificationListener *listener,
-                       /*out*/
-                       int64_t *lastFrameNumber = NULL);
+        status_t clear(/*out*/int64_t *lastFrameNumber = NULL);
 
         /**
          * Flush all pending requests in HAL.
@@ -603,7 +601,7 @@
         wp<camera3::StatusTracker>  mStatusTracker;
         camera3_device_t  *mHal3Device;
 
-        NotificationListener *mListener;
+        wp<NotificationListener> mListener;
 
         const int          mId;       // The camera ID
         int                mStatusId; // The RequestThread's component ID for
@@ -759,7 +757,7 @@
         PreparerThread();
         ~PreparerThread();
 
-        void setNotificationListener(NotificationListener *listener);
+        void setNotificationListener(wp<NotificationListener> listener);
 
         /**
          * Queue up a stream to be prepared. Streams are processed by a background thread in FIFO
@@ -780,7 +778,7 @@
 
         // Guarded by mLock
 
-        NotificationListener *mListener;
+        wp<NotificationListener> mListener;
         List<sp<camera3::Camera3StreamInterface> > mPendingStreams;
         bool mActive;
         bool mCancelNow;
@@ -809,7 +807,7 @@
     uint32_t               mNextReprocessShutterFrameNumber;
     List<CaptureResult>   mResultQueue;
     Condition              mResultSignal;
-    NotificationListener  *mListener;
+    wp<NotificationListener>  mListener;
 
     /**** End scope for mOutputLock ****/
 
@@ -822,9 +820,9 @@
 
     // Specific notify handlers
     void notifyError(const camera3_error_msg_t &msg,
-            NotificationListener *listener);
+            sp<NotificationListener> listener);
     void notifyShutter(const camera3_shutter_msg_t &msg,
-            NotificationListener *listener);
+            sp<NotificationListener> listener);
 
     // helper function to return the output buffers to the streams.
     void returnOutputBuffers(const camera3_stream_buffer_t *outputBuffers,