Close all camera resources when camera error happens.

Also add more logs to better track still observed camera
open/close failures.

R=magjed@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/48109004

Cr-Commit-Position: refs/heads/master@{#9020}
diff --git a/talk/app/webrtc/java/src/org/webrtc/VideoCapturerAndroid.java b/talk/app/webrtc/java/src/org/webrtc/VideoCapturerAndroid.java
index 22d03a7..0039000 100644
--- a/talk/app/webrtc/java/src/org/webrtc/VideoCapturerAndroid.java
+++ b/talk/app/webrtc/java/src/org/webrtc/VideoCapturerAndroid.java
@@ -216,7 +216,7 @@
   // starts a thread to be used for capturing.
   // If deviceName is empty, the first available device is used in order to be
   // compatible with the generic VideoCapturer class.
-  boolean init(String deviceName) {
+  synchronized boolean init(String deviceName) {
     Log.d(TAG, "init " + deviceName);
     if (deviceName == null || !initStatics())
       return false;
@@ -241,6 +241,7 @@
     if (supportedFormats != null)
       return true;
     try {
+      Log.d(TAG, "Get supported formats.");
       supportedFormats =
           new ArrayList<List<CaptureFormat>>(Camera.getNumberOfCameras());
       for (int i = 0; i < Camera.getNumberOfCameras(); ++i) {
@@ -322,10 +323,10 @@
             range[Camera.Parameters.PREVIEW_FPS_MIN_INDEX],
             range[Camera.Parameters.PREVIEW_FPS_MAX_INDEX]));
       }
-      camera.release();
     } catch (Exception e) {
       Log.e(TAG, "getSupportedFormats failed on id " + id, e);
     }
+    camera.release();
     return formatList;
   }
 
@@ -387,8 +388,8 @@
     this.applicationContext = applicationContext;
     this.frameObserver = frameObserver;
     try {
-      this.camera = Camera.open(id);
-      this.info = new Camera.CameraInfo();
+      camera = Camera.open(id);
+      info = new Camera.CameraInfo();
       Camera.getCameraInfo(id, info);
       // No local renderer (we only care about onPreviewFrame() buffers, not a
       // directly-displayed UI element).  Camera won't capture without
@@ -417,6 +418,7 @@
 
         camera.setPreviewTexture(cameraSurfaceTexture);
       } catch (IOException e) {
+        Log.e(TAG, "setPreviewTexture failed", error);
         throw new RuntimeException(e);
       }
 
@@ -457,9 +459,8 @@
       error = e;
     }
     Log.e(TAG, "startCapture failed", error);
-    if (camera != null) {
-      stopCaptureOnCameraThread();
-    }
+    stopCaptureOnCameraThread();
+    cameraThreadHandler = null;
     frameObserver.OnCapturerStarted(false);
     return;
   }
@@ -467,7 +468,8 @@
   // Called by native code.  Returns true when camera is known to be stopped.
   synchronized void stopCapture() throws InterruptedException {
     if (cameraThreadHandler == null) {
-      throw new RuntimeException("Calling stopCapture() for already stopped camera.");
+      Log.e(TAG, "Calling stopCapture() for already stopped camera.");
+      return;
     }
     Log.d(TAG, "stopCapture");
     cameraThreadHandler.post(new Runnable() {
@@ -488,7 +490,11 @@
   }
 
   private void doStopCaptureOnCamerathread() {
+    if (camera == null) {
+      return;
+    }
     try {
+      Log.d(TAG, "Stop preview.");
       camera.stopPreview();
       camera.setPreviewCallbackWithBuffer(null);
       videoBuffers.stopReturnBuffersToCamera();
@@ -500,6 +506,7 @@
         cameraGlTextures = null;
       }
 
+      Log.d(TAG, "Release camera.");
       camera.release();
       camera = null;
     } catch (IOException e) {