Camera2: Improve error checking and debug logs.

Bug: 6243944
Change-Id: Ie61d89b733af7d1f653443bf64b767456127a455
diff --git a/services/camera/libcameraservice/Camera2Client.cpp b/services/camera/libcameraservice/Camera2Client.cpp
index 05a54b7..7f28c67 100644
--- a/services/camera/libcameraservice/Camera2Client.cpp
+++ b/services/camera/libcameraservice/Camera2Client.cpp
@@ -94,6 +94,8 @@
 
 Camera2Client::~Camera2Client() {
     ATRACE_CALL();
+    ALOGV("%s: Camera %d: Shutting down", __FUNCTION__, mCameraId);
+
     mDestructionStarted = true;
 
     disconnect();
@@ -109,17 +111,9 @@
     result.append("  State: ");
 #define CASE_APPEND_ENUM(x) case x: result.append(#x "\n"); break;
 
-    switch (mState) {
-        CASE_APPEND_ENUM(NOT_INITIALIZED)
-        CASE_APPEND_ENUM(STOPPED)
-        CASE_APPEND_ENUM(WAITING_FOR_PREVIEW_WINDOW)
-        CASE_APPEND_ENUM(PREVIEW)
-        CASE_APPEND_ENUM(RECORD)
-        CASE_APPEND_ENUM(STILL_CAPTURE)
-        default: result.append("UNKNOWN\n"); break;
-    }
+    result.append(getStateName(mState));
 
-    result.append("  Current parameters:\n");
+    result.append("\n  Current parameters:\n");
     result.appendFormat("    Preview size: %d x %d\n",
             mParameters.previewWidth, mParameters.previewHeight);
     result.appendFormat("    Preview FPS range: %d - %d\n",
@@ -272,6 +266,23 @@
     return NO_ERROR;
 }
 
+const char* Camera2Client::getStateName(State state) {
+#define CASE_ENUM_TO_CHAR(x) case x: return(#x); break;
+    switch(state) {
+        CASE_ENUM_TO_CHAR(NOT_INITIALIZED)
+        CASE_ENUM_TO_CHAR(STOPPED)
+        CASE_ENUM_TO_CHAR(WAITING_FOR_PREVIEW_WINDOW)
+        CASE_ENUM_TO_CHAR(PREVIEW)
+        CASE_ENUM_TO_CHAR(RECORD)
+        CASE_ENUM_TO_CHAR(STILL_CAPTURE)
+        CASE_ENUM_TO_CHAR(VIDEO_SNAPSHOT)
+        default:
+            return "Unknown state!";
+            break;
+    }
+#undef CASE_ENUM_TO_CHAR
+}
+
 // ICamera interface
 
 void Camera2Client::disconnect() {
@@ -399,7 +410,11 @@
 status_t Camera2Client::startPreviewLocked() {
     ATRACE_CALL();
     status_t res;
-    if (mState >= PREVIEW) return INVALID_OPERATION;
+    if (mState >= PREVIEW) {
+        ALOGE("%s: Can't start preview in state %s",
+                __FUNCTION__, getStateName(mState));
+        return INVALID_OPERATION;
+    }
 
     if (mPreviewStreamId == NO_STREAM) {
         mState = WAITING_FOR_PREVIEW_WINDOW;
@@ -549,9 +564,19 @@
     Mutex::Autolock pl(mParamsLock);
 
     res = updateCaptureStream();
+    if (res != OK) {
+        ALOGE("%s: Can't set up still image stream: %s (%d)",
+                __FUNCTION__, strerror(-res), res);
+        return res;
+    }
 
     if (mCaptureRequest == NULL) {
-        updateCaptureRequest();
+        res = updateCaptureRequest();
+        if (res != OK) {
+            ALOGE("%s: Can't set up still image capture request: %s (%d)",
+                    __FUNCTION__, strerror(-res), res);
+            return res;
+        }
     }
 
     // TODO: For video snapshot, need 3 streams here
diff --git a/services/camera/libcameraservice/Camera2Client.h b/services/camera/libcameraservice/Camera2Client.h
index 5457343..791c5e1 100644
--- a/services/camera/libcameraservice/Camera2Client.h
+++ b/services/camera/libcameraservice/Camera2Client.h
@@ -70,7 +70,7 @@
     virtual status_t dump(int fd, const Vector<String16>& args);
 
 private:
-    enum {
+    enum State {
         NOT_INITIALIZED,
         STOPPED,
         WAITING_FOR_PREVIEW_WINDOW,
@@ -80,6 +80,8 @@
         VIDEO_SNAPSHOT
     } mState;
 
+    static const char *getStateName(State state);
+
     /** ICamera interface-related private members */
 
     // Mutex that must be locked by methods implementing the ICamera interface.
diff --git a/services/camera/libcameraservice/Camera2Device.cpp b/services/camera/libcameraservice/Camera2Device.cpp
index 8cb872a..7db04ff 100644
--- a/services/camera/libcameraservice/Camera2Device.cpp
+++ b/services/camera/libcameraservice/Camera2Device.cpp
@@ -174,11 +174,16 @@
 
 status_t Camera2Device::deleteStream(int id) {
     ALOGV("%s: E", __FUNCTION__);
-
     bool found = false;
     for (StreamList::iterator streamI = mStreams.begin();
          streamI != mStreams.end(); streamI++) {
         if ((*streamI)->getId() == id) {
+            status_t res = (*streamI)->disconnect();
+            if (res != OK) {
+                ALOGE("%s: Unable to disconnect stream %d from HAL device: "
+                        "%s (%d)", __FUNCTION__, id, strerror(-res), res);
+                return res;
+            }
             mStreams.erase(streamI);
             found = true;
             break;