Merge "Update error message"
diff --git a/camera/photography/ICameraDeviceUser.cpp b/camera/photography/ICameraDeviceUser.cpp
index 325f94d..95609da 100644
--- a/camera/photography/ICameraDeviceUser.cpp
+++ b/camera/photography/ICameraDeviceUser.cpp
@@ -40,6 +40,7 @@
     CREATE_STREAM,
     CREATE_DEFAULT_REQUEST,
     GET_CAMERA_INFO,
+    WAIT_UNTIL_IDLE,
 };
 
 class BpCameraDeviceUser : public BpInterface<ICameraDeviceUser>
@@ -172,6 +173,15 @@
         return result;
     }
 
+    virtual status_t waitUntilIdle()
+    {
+        ALOGV("waitUntilIdle");
+        Parcel data, reply;
+        data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
+        remote()->transact(WAIT_UNTIL_IDLE, data, &reply);
+        reply.readExceptionCode();
+        return reply.readInt32();
+    }
 
 private:
 
@@ -296,6 +306,12 @@
 
             return NO_ERROR;
         } break;
+        case WAIT_UNTIL_IDLE: {
+            CHECK_INTERFACE(ICameraDeviceUser, data, reply);
+            reply->writeNoException();
+            reply->writeInt32(waitUntilIdle());
+            return NO_ERROR;
+        } break;
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/drm/common/IDrmManagerService.cpp b/drm/common/IDrmManagerService.cpp
index 91fd91e..db41e0b 100644
--- a/drm/common/IDrmManagerService.cpp
+++ b/drm/common/IDrmManagerService.cpp
@@ -153,18 +153,6 @@
     return reply.readInt32();
 }
 
-status_t BpDrmManagerService::installDrmEngine(int uniqueId, const String8& drmEngineFile) {
-    ALOGV("Install DRM Engine");
-    Parcel data, reply;
-
-    data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
-    data.writeInt32(uniqueId);
-    data.writeString8(drmEngineFile);
-
-    remote()->transact(INSTALL_DRM_ENGINE, data, &reply);
-    return reply.readInt32();
-}
-
 DrmConstraints* BpDrmManagerService::getConstraints(
             int uniqueId, const String8* path, const int action) {
     ALOGV("Get Constraints");
@@ -855,19 +843,6 @@
         return DRM_NO_ERROR;
     }
 
-    case INSTALL_DRM_ENGINE:
-    {
-        ALOGV("BnDrmManagerService::onTransact :INSTALL_DRM_ENGINE");
-        CHECK_INTERFACE(IDrmManagerService, data, reply);
-
-        const int uniqueId = data.readInt32();
-        const String8 engineFile = data.readString8();
-        status_t status = installDrmEngine(uniqueId, engineFile);
-
-        reply->writeInt32(status);
-        return DRM_NO_ERROR;
-    }
-
     case GET_CONSTRAINTS_FROM_CONTENT:
     {
         ALOGV("BnDrmManagerService::onTransact :GET_CONSTRAINTS_FROM_CONTENT");
diff --git a/drm/drmserver/DrmManager.cpp b/drm/drmserver/DrmManager.cpp
index bfaf4bc..dccd23d 100644
--- a/drm/drmserver/DrmManager.cpp
+++ b/drm/drmserver/DrmManager.cpp
@@ -175,21 +175,6 @@
     return NULL;
 }
 
-status_t DrmManager::installDrmEngine(int uniqueId, const String8& absolutePath) {
-    Mutex::Autolock _l(mLock);
-    mPlugInManager.loadPlugIn(absolutePath);
-
-    IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(absolutePath);
-    rDrmEngine.initialize(uniqueId);
-    rDrmEngine.setOnInfoListener(uniqueId, this);
-
-    DrmSupportInfo* info = rDrmEngine.getSupportInfo(0);
-    mSupportInfoToPlugInIdMap.add(*info, absolutePath);
-    delete info;
-
-    return DRM_NO_ERROR;
-}
-
 bool DrmManager::canHandle(int uniqueId, const String8& path, const String8& mimeType) {
     Mutex::Autolock _l(mLock);
     const String8 plugInId = getSupportedPlugInId(mimeType);
diff --git a/drm/drmserver/DrmManagerService.cpp b/drm/drmserver/DrmManagerService.cpp
index bbd3b7f..2b71904 100644
--- a/drm/drmserver/DrmManagerService.cpp
+++ b/drm/drmserver/DrmManagerService.cpp
@@ -87,11 +87,6 @@
     return DRM_NO_ERROR;
 }
 
-status_t DrmManagerService::installDrmEngine(int uniqueId, const String8& drmEngineFile) {
-    ALOGV("Entering installDrmEngine");
-    return mDrmManager->installDrmEngine(uniqueId, drmEngineFile);
-}
-
 DrmConstraints* DrmManagerService::getConstraints(
             int uniqueId, const String8* path, const int action) {
     ALOGV("Entering getConstraints from content");
diff --git a/drm/libdrmframework/DrmManagerClientImpl.cpp b/drm/libdrmframework/DrmManagerClientImpl.cpp
index a970035..ffefd74 100644
--- a/drm/libdrmframework/DrmManagerClientImpl.cpp
+++ b/drm/libdrmframework/DrmManagerClientImpl.cpp
@@ -86,15 +86,6 @@
             (NULL != infoListener.get()) ? this : NULL);
 }
 
-status_t DrmManagerClientImpl::installDrmEngine(
-        int uniqueId, const String8& drmEngineFile) {
-    status_t status = DRM_ERROR_UNKNOWN;
-    if (EMPTY_STRING != drmEngineFile) {
-        status = getDrmManagerService()->installDrmEngine(uniqueId, drmEngineFile);
-    }
-    return status;
-}
-
 DrmConstraints* DrmManagerClientImpl::getConstraints(
         int uniqueId, const String8* path, const int action) {
     DrmConstraints *drmConstraints = NULL;
diff --git a/drm/libdrmframework/include/DrmManager.h b/drm/libdrmframework/include/DrmManager.h
index 8ab693f..e7cdd36 100644
--- a/drm/libdrmframework/include/DrmManager.h
+++ b/drm/libdrmframework/include/DrmManager.h
@@ -70,8 +70,6 @@
     status_t setDrmServiceListener(
             int uniqueId, const sp<IDrmServiceListener>& drmServiceListener);
 
-    status_t installDrmEngine(int uniqueId, const String8& drmEngineFile);
-
     DrmConstraints* getConstraints(int uniqueId, const String8* path, const int action);
 
     DrmMetadata* getMetadata(int uniqueId, const String8* path);
diff --git a/drm/libdrmframework/include/DrmManagerClientImpl.h b/drm/libdrmframework/include/DrmManagerClientImpl.h
index 9b4c9ae..3400cb1 100644
--- a/drm/libdrmframework/include/DrmManagerClientImpl.h
+++ b/drm/libdrmframework/include/DrmManagerClientImpl.h
@@ -410,17 +410,6 @@
     status_t notify(const DrmInfoEvent& event);
 
 private:
-    /**
-     * Install new DRM Engine Plug-in at the runtime
-     *
-     * @param[in] uniqueId Unique identifier for a session
-     * @param[in] drmEngine Shared Object(so) File in which DRM Engine defined
-     * @return status_t
-     *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
-     */
-    status_t installDrmEngine(int uniqueId, const String8& drmEngineFile);
-
-private:
     Mutex mLock;
     sp<DrmManagerClient::OnInfoListener> mOnInfoListener;
 
diff --git a/drm/libdrmframework/include/DrmManagerService.h b/drm/libdrmframework/include/DrmManagerService.h
index 0dfdca6..8bc59b4 100644
--- a/drm/libdrmframework/include/DrmManagerService.h
+++ b/drm/libdrmframework/include/DrmManagerService.h
@@ -57,8 +57,6 @@
     status_t setDrmServiceListener(
             int uniqueId, const sp<IDrmServiceListener>& drmServiceListener);
 
-    status_t installDrmEngine(int uniqueId, const String8& drmEngineFile);
-
     DrmConstraints* getConstraints(int uniqueId, const String8* path, const int action);
 
     DrmMetadata* getMetadata(int uniqueId, const String8* path);
diff --git a/drm/libdrmframework/include/IDrmManagerService.h b/drm/libdrmframework/include/IDrmManagerService.h
index 5a4d70a..fe55650 100644
--- a/drm/libdrmframework/include/IDrmManagerService.h
+++ b/drm/libdrmframework/include/IDrmManagerService.h
@@ -93,8 +93,6 @@
     virtual status_t setDrmServiceListener(
             int uniqueId, const sp<IDrmServiceListener>& infoListener) = 0;
 
-    virtual status_t installDrmEngine(int uniqueId, const String8& drmEngineFile) = 0;
-
     virtual DrmConstraints* getConstraints(
             int uniqueId, const String8* path, const int action) = 0;
 
@@ -185,8 +183,6 @@
     virtual status_t setDrmServiceListener(
             int uniqueId, const sp<IDrmServiceListener>& infoListener);
 
-    virtual status_t installDrmEngine(int uniqueId, const String8& drmEngineFile);
-
     virtual DrmConstraints* getConstraints(int uniqueId, const String8* path, const int action);
 
     virtual DrmMetadata* getMetadata(int uniqueId, const String8* path);
diff --git a/include/camera/photography/ICameraDeviceUser.h b/include/camera/photography/ICameraDeviceUser.h
index 3ea49f4..45988d0 100644
--- a/include/camera/photography/ICameraDeviceUser.h
+++ b/include/camera/photography/ICameraDeviceUser.h
@@ -61,6 +61,8 @@
     virtual status_t        getCameraInfo(/*out*/
                                           CameraMetadata* info) = 0;
 
+    // Wait until all the submitted requests have finished processing
+    virtual status_t        waitUntilIdle() =  0;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/services/camera/libcameraservice/camera3/Camera3OutputStream.cpp b/services/camera/libcameraservice/camera3/Camera3OutputStream.cpp
index f085443..0ec2b05 100644
--- a/services/camera/libcameraservice/camera3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/camera3/Camera3OutputStream.cpp
@@ -304,7 +304,7 @@
     ALOGV("%s: Consumer wants %d buffers, HAL wants %d", __FUNCTION__,
             maxConsumerBuffers, camera3_stream::max_buffers);
     if (camera3_stream::max_buffers == 0) {
-        ALOGE("%s: Camera HAL requested no max_buffers, requires at least 1",
+        ALOGE("%s: Camera HAL requested max_buffer count: %d, requires at least 1",
                 __FUNCTION__, camera3_stream::max_buffers);
         return INVALID_OPERATION;
     }
diff --git a/services/camera/libcameraservice/photography/CameraDeviceClient.cpp b/services/camera/libcameraservice/photography/CameraDeviceClient.cpp
index e1c7e79..dd845f6 100644
--- a/services/camera/libcameraservice/photography/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/photography/CameraDeviceClient.cpp
@@ -412,6 +412,30 @@
     return res;
 }
 
+status_t CameraDeviceClient::waitUntilIdle()
+{
+    ATRACE_CALL();
+    ALOGV("%s", __FUNCTION__);
+
+    status_t res = OK;
+    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
+
+    Mutex::Autolock icl(mBinderSerializationLock);
+
+    if (!mDevice.get()) return DEAD_OBJECT;
+
+    // FIXME: Also need check repeating burst.
+    if (!mStreamingRequestList.isEmpty()) {
+        ALOGE("%s: Camera %d: Try to waitUntilIdle when there are active streaming requests",
+              __FUNCTION__, mCameraId);
+        return INVALID_OPERATION;
+    }
+    res = mDevice->waitUntilDrained();
+    ALOGV("%s Done", __FUNCTION__);
+
+    return res;
+}
+
 status_t CameraDeviceClient::dump(int fd, const Vector<String16>& args) {
     String8 result;
     result.appendFormat("CameraDeviceClient[%d] (%p) PID: %d, dump:\n",
diff --git a/services/camera/libcameraservice/photography/CameraDeviceClient.h b/services/camera/libcameraservice/photography/CameraDeviceClient.h
index c6c241a..bb2949c 100644
--- a/services/camera/libcameraservice/photography/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/photography/CameraDeviceClient.h
@@ -87,6 +87,8 @@
     // -- Caller owns the newly allocated metadata
     virtual status_t      getCameraInfo(/*out*/CameraMetadata* info);
 
+    // Wait until all the submitted requests have finished processing
+    virtual status_t      waitUntilIdle();
     /**
      * Interface used by CameraService
      */