QCamera2: HAL3: Restart daemon and mediaserver when buffer is lost.

When there are buffers not returned during closeCamera, restart
both daemon and mediaserver to reclaim leaked memory.

Bug: 25149843
Bug: 27529887
Change-Id: I5283d37e04ab6e7b0305db5821a38a83f3ae5126
diff --git a/camera/QCamera2/HAL3/QCamera3HWI.cpp b/camera/QCamera2/HAL3/QCamera3HWI.cpp
index 57cad30..1d86d19 100644
--- a/camera/QCamera2/HAL3/QCamera3HWI.cpp
+++ b/camera/QCamera2/HAL3/QCamera3HWI.cpp
@@ -297,6 +297,8 @@
     mEnableRawDump = atoi(prop);
     if (mEnableRawDump)
         CDBG("%s: Raw dump from Camera HAL enabled", __func__);
+
+    mPendingBuffersMap.num_buffers = 0;
 }
 
 /*===========================================================================
@@ -313,6 +315,7 @@
     CDBG("%s: E", __func__);
     /* We need to stop all streams before deleting any stream */
 
+    bool hasPendingBuffers = (mPendingBuffersMap.num_buffers > 0);
 
     if (mRawDumpChannel) {
         mRawDumpChannel->stop();
@@ -355,6 +358,19 @@
             delete mMetadataChannel;
             mMetadataChannel = NULL;
         }
+
+        memset(mParameters, 0, sizeof(parm_buffer_t));
+        // Check if there is still pending buffer not yet returned.
+        if (hasPendingBuffers) {
+            uint8_t restart = TRUE;
+            AddSetParmEntryToBatch(mParameters, CAM_INTF_META_DAEMON_RESTART,
+                    sizeof(restart), &restart);
+        }
+
+        int rc = mCameraHandle->ops->set_parms(mCameraHandle->camera_handle, mParameters);
+        if (rc < 0) {
+            ALOGE("%s: set_parms failed for unconfigure", __func__);
+        }
         deinitParameters();
     }
 
@@ -372,6 +388,11 @@
     pthread_cond_destroy(&mRequestCond);
 
     pthread_mutex_destroy(&mMutex);
+
+    if (hasPendingBuffers) {
+        ALOGE("%s: Not all buffers are returned. Aborting...", __func__);
+        abort();
+    }
     CDBG("%s: X", __func__);
 }
 
diff --git a/camera/QCamera2/stack/common/cam_intf.h b/camera/QCamera2/stack/common/cam_intf.h
index aad8b02..9b5fc7a 100644
--- a/camera/QCamera2/stack/common/cam_intf.h
+++ b/camera/QCamera2/stack/common/cam_intf.h
@@ -641,6 +641,7 @@
     INCLUDE(CAM_INTF_PARM_ROTATION,                     cam_rotation_info_t,         1);
     INCLUDE(CAM_INTF_META_EFFECTIVE_EXPOSURE_FACTOR,    float,                       1);
     INCLUDE(CAM_INTF_META_USE_AV_TIMER,                 uint8_t,                     1);
+    INCLUDE(CAM_INTF_META_DAEMON_RESTART,               uint8_t,                     1);
 } parm_data_t;
 
 typedef parm_data_t metadata_data_t;
diff --git a/camera/QCamera2/stack/common/cam_types.h b/camera/QCamera2/stack/common/cam_types.h
index 5a75d8f..ac0502e 100644
--- a/camera/QCamera2/stack/common/cam_types.h
+++ b/camera/QCamera2/stack/common/cam_types.h
@@ -1356,6 +1356,8 @@
     CAM_INTF_PARM_CAC,
     CAM_INTF_META_EFFECTIVE_EXPOSURE_FACTOR,
     CAM_INTF_META_USE_AV_TIMER,
+    /* Whether HAL has run into DRAIN error */
+    CAM_INTF_META_DAEMON_RESTART,
     CAM_INTF_PARM_MAX
 } cam_intf_parm_type_t;
 
diff --git a/camera/QCamera2/stack/mm-camera-interface/src/cam_intf.c b/camera/QCamera2/stack/mm-camera-interface/src/cam_intf.c
index 119c967..1676f75 100644
--- a/camera/QCamera2/stack/mm-camera-interface/src/cam_intf.c
+++ b/camera/QCamera2/stack/mm-camera-interface/src/cam_intf.c
@@ -343,6 +343,8 @@
           return POINTER_OF_META(CAM_INTF_PARM_ROTATION, metadata);
         case CAM_INTF_META_USE_AV_TIMER:
             return POINTER_OF_META(CAM_INTF_META_USE_AV_TIMER, metadata);
+        case CAM_INTF_META_DAEMON_RESTART:
+          return POINTER_OF_META(CAM_INTF_META_DAEMON_RESTART, metadata);
         default:
             return NULL;
     }
@@ -662,6 +664,8 @@
           return SIZE_OF_PARAM(CAM_INTF_PARM_ROTATION, metadata);
         case CAM_INTF_META_USE_AV_TIMER:
             return SIZE_OF_PARAM(CAM_INTF_META_USE_AV_TIMER, metadata);
+        case CAM_INTF_META_DAEMON_RESTART:
+          return SIZE_OF_PARAM(CAM_INTF_META_DAEMON_RESTART, metadata);
         default:
             return 0;
     }