OSDN Git Service

Fix crash in VideoModule - Method called after release()
authorSenpo Hu <senpo@google.com>
Sun, 28 Sep 2014 11:30:15 +0000 (04:30 -0700)
committerSenpo Hu <senpo@google.com>
Sun, 28 Sep 2014 11:30:15 +0000 (04:30 -0700)
Completely eliminate the runtime exception caused by monkey.
Sample stack trace:
java.lang.RuntimeException: Method called after release()
       at android.media.MediaRecorder.setCamera(Native Method)
       at com.android.camera.VideoModule.initializeRecorder(VideoModule.java:1101)
       at com.android.camera.VideoModule.access$2000(VideoModule.java:88)
       at com.android.camera.VideoModule$10.onStorageUpdateDone(VideoModule.java:1320)
       at com.android.camera.CameraActivity$20.onPostExecute(CameraActivity.java:2014)

Bug: 17313985
Change-Id: I7ecaf375c26ebd1608d7098599ab1528609287ce

src/com/android/camera/VideoModule.java

index 99e0501..f855d95 100644 (file)
@@ -1060,7 +1060,7 @@ public class VideoModule extends CameraModule
 
     // Prepares media recorder.
     private void initializeRecorder() {
-        Log.i(TAG, "initializeRecorder");
+        Log.i(TAG, "initializeRecorder: " + Thread.currentThread());
         // If the mCameraDevice is null, then this activity is going to finish
         if (mCameraDevice == null) {
             return;
@@ -1087,12 +1087,9 @@ public class VideoModule extends CameraModule
             requestedSizeLimit = myExtras.getLong(MediaStore.EXTRA_SIZE_LIMIT);
         }
         mMediaRecorder = new MediaRecorder();
-
         // Unlock the camera object before passing it to media recorder.
-        if (mCameraDevice != null) {
-            mCameraDevice.unlock();
-            mMediaRecorder.setCamera(mCameraDevice.getCamera());
-        }
+        mCameraDevice.unlock();
+        mMediaRecorder.setCamera(mCameraDevice.getCamera());
         mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
         mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
         mMediaRecorder.setProfile(mProfile);
@@ -1291,7 +1288,7 @@ public class VideoModule extends CameraModule
     }
 
     private void startVideoRecording() {
-        Log.i(TAG, "startVideoRecording");
+        Log.i(TAG, "startVideoRecording: " + Thread.currentThread());
         mUI.cancelAnimations();
         mUI.setSwipingEnabled(false);
         mUI.showFocusUI(false);
@@ -1311,6 +1308,15 @@ public class VideoModule extends CameraModule
                         Log.v(TAG, "in storage callback after module paused");
                         return;
                     }
+
+                    // Monkey is so fast so it could trigger startVideoRecording twice. To prevent
+                    // app crash (b/17313985), do nothing here for the second storage-checking
+                    // callback because recording is already started.
+                    if (mMediaRecorderRecording) {
+                        Log.v(TAG, "in storage callback after recording started");
+                        return;
+                    }
+
                     mCurrentVideoUri = null;
 
                     initializeRecorder();
@@ -1395,6 +1401,14 @@ public class VideoModule extends CameraModule
 
     private boolean stopVideoRecording() {
         Log.i(TAG, "stopVideoRecording");
+
+        // Do nothing if camera device is still capturing photo. Monkey test can trigger app crashes
+        // (b/17313985) without this check. Crash could also be reproduced by continuously tapping
+        // on shutter button and preview with two fingers.
+        if (mSnapshotInProgress) {
+            return true;
+        }
+
         mUI.setSwipingEnabled(true);
         mUI.showFocusUI(true);
         mUI.showVideoRecordingHints(true);