Camera2: Clean up startup/shutdown sequences.

- Close camera device on startup errors

- Make sure all threads are shut down and the device is closed before
  returning from ICamera::disconnect.

Bug: 7172680
Change-Id: I98611448ec5f2311e6604fa8ee5f9dde7bfdd988
diff --git a/services/camera/libcameraservice/Camera2Client.cpp b/services/camera/libcameraservice/Camera2Client.cpp
index 4fad83e..495feda 100644
--- a/services/camera/libcameraservice/Camera2Client.cpp
+++ b/services/camera/libcameraservice/Camera2Client.cpp
@@ -137,7 +137,6 @@
 
 Camera2Client::~Camera2Client() {
     ATRACE_CALL();
-    ALOGV("Camera %d: Shutting down", mCameraId);
 
     mDestructionStarted = true;
 
@@ -145,12 +144,6 @@
     mClientPid = getCallingPid();
     disconnect();
 
-    mFrameProcessor->requestExit();
-    mCaptureSequencer->requestExit();
-    mJpegProcessor->requestExit();
-    mZslProcessor->requestExit();
-    mCallbackProcessor->requestExit();
-
     ALOGI("Camera %d: Closed", mCameraId);
 }
 
@@ -365,15 +358,21 @@
 
 void Camera2Client::disconnect() {
     ATRACE_CALL();
-    ALOGV("%s: E", __FUNCTION__);
     Mutex::Autolock icl(mICameraLock);
     status_t res;
     if ( (res = checkPid(__FUNCTION__) ) != OK) return;
 
     if (mDevice == 0) return;
 
+    ALOGV("Camera %d: Shutting down", mCameraId);
+
     stopPreviewL();
 
+    {
+        SharedParameters::Lock l(mParameters);
+        l.mParameters.state = Parameters::DISCONNECTED;
+    }
+
     if (mPreviewStreamId != NO_STREAM) {
         mDevice->deleteStream(mPreviewStreamId);
         mPreviewStreamId = NO_STREAM;
@@ -390,9 +389,25 @@
 
     mZslProcessor->deleteStream();
 
+    mFrameProcessor->requestExit();
+    mCaptureSequencer->requestExit();
+    mJpegProcessor->requestExit();
+    mZslProcessor->requestExit();
+    mCallbackProcessor->requestExit();
+
+    ALOGV("Camera %d: Waiting for threads", mCameraId);
+
+    mFrameProcessor->join();
+    mCaptureSequencer->join();
+    mJpegProcessor->join();
+    mZslProcessor->join();
+    mCallbackProcessor->join();
+
+    ALOGV("Camera %d: Disconnecting device", mCameraId);
+
+    mDevice->disconnect();
+
     mDevice.clear();
-    SharedParameters::Lock l(mParameters);
-    l.mParameters.state = Parameters::DISCONNECTED;
 
     CameraService::Client::disconnect();
 }