From 6b39715d4861baff73dcb7c55b41ff298b39aa15 Mon Sep 17 00:00:00 2001 From: Ashok Raj Deenadayalan Date: Fri, 25 Oct 2013 18:48:22 +0530 Subject: Camera: Synchronising video functionality of errant usecase. When user switches to VideoModule and executes the capture, stops it immediately, after several such attempts the media recorder enters into illegal state, in such situation, if user still continues the same behaviour, app will be flooded with the onShutter events which will lead to ANR, and further similar trials will lead to crash. Here, we are synchronizing the behaviour(user events)by checking the entry/exit body of majorly hit functions so that app will not be flooded with user events. (cherrypicked from: I3e7768211855a31f1c573d0ed89abb5c6216cb1b) Change-Id: Ia65f39c24822ae09694b8247fa58ffb1770e74da CRs-fixed: 534762 (cherry picked from commit 615b8451f787aa8e34834847301fd151d7eb66d6) (cherry picked from commit cf6dfaf3aa65b46b74f3e54236b24638ad1249de) --- src/com/android/camera/VideoModule.java | 47 ++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/src/com/android/camera/VideoModule.java b/src/com/android/camera/VideoModule.java index 1caf4b3a7..56c2d2dd7 100644 --- a/src/com/android/camera/VideoModule.java +++ b/src/com/android/camera/VideoModule.java @@ -175,6 +175,12 @@ public class VideoModule implements CameraModule, private int mZoomValue; // The current zoom value. + private boolean mStartRecPending = false; + private boolean mStopRecPending = false; + private boolean mStartPrevPending = false; + private boolean mStopPrevPending = false; + + private final MediaSaveService.OnMediaSavedListener mOnVideoSavedListener = new MediaSaveService.OnMediaSavedListener() { @Override @@ -596,12 +602,32 @@ public class VideoModule implements CameraModule, // Consume clicks } + public boolean isPreviewReady() { + if ((mStartPrevPending == true || mStopPrevPending == true)) + return false; + else + return true; + } + + public boolean isRecorderReady() { + if ((mStartRecPending == true || mStopRecPending == true)) + return false; + else + return true; + } + @Override public void onShutterButtonClick() { if (mUI.collapseCameraControls() || mSwitchingCamera) return; boolean stop = mMediaRecorderRecording; + if (isPreviewReady() == false) + return; + + if (isRecorderReady() == false) + return; + if (stop) { onStopVideoRecording(); } else { @@ -858,10 +884,12 @@ public class VideoModule implements CameraModule, private void startPreview() { Log.v(TAG, "startPreview"); + mStartPrevPending = true; SurfaceTexture surfaceTexture = mUI.getSurfaceTexture(); if (!mPreferenceRead || surfaceTexture == null || mPaused == true || mCameraDevice == null) { + mStartPrevPending = false; return; } @@ -883,6 +911,7 @@ public class VideoModule implements CameraModule, closeCamera(); throw new RuntimeException("startPreview failed", ex); } + mStartPrevPending = false; } private void onPreviewStarted() { @@ -891,9 +920,15 @@ public class VideoModule implements CameraModule, @Override public void stopPreview() { - if (!mPreviewing) return; + mStopPrevPending = true; + + if (!mPreviewing) { + mStopPrevPending = false; + return; + } mCameraDevice.stopPreview(); mPreviewing = false; + mStopPrevPending = false; } private void closeCamera() { @@ -1328,18 +1363,21 @@ public class VideoModule implements CameraModule, private void startVideoRecording() { Log.v(TAG, "startVideoRecording"); + mStartRecPending = true; mUI.cancelAnimations(); mUI.setSwipingEnabled(false); mActivity.updateStorageSpaceAndHint(); if (mActivity.getStorageSpaceBytes() <= Storage.LOW_STORAGE_THRESHOLD_BYTES) { Log.v(TAG, "Storage issue, ignore the start request"); + mStartRecPending = false; return; } if( mUnsupportedHFRVideoSize == true) { Log.e(TAG, "Unsupported HFR and video size combinations"); Toast.makeText(mActivity,R.string.error_app_unsupported_hfr, Toast.LENGTH_SHORT).show(); + mStartRecPending = false; return; } @@ -1347,6 +1385,7 @@ public class VideoModule implements CameraModule, Log.e(TAG, "Unsupported HFR and video codec combinations"); Toast.makeText(mActivity, R.string.error_app_unsupported_hfr_codec, Toast.LENGTH_SHORT).show(); + mStartRecPending = false; return; } //?? @@ -1356,10 +1395,12 @@ public class VideoModule implements CameraModule, initializeRecorder(); if (mUnsupportedResolution == true) { Log.v(TAG, "Unsupported Resolution according to target"); + mStartRecPending = false; return; } if (mMediaRecorder == null) { Log.e(TAG, "Fail to initialize media recorder"); + mStartRecPending = false; return; } @@ -1372,6 +1413,7 @@ public class VideoModule implements CameraModule, releaseMediaRecorder(); // If start fails, frameworks will not lock the camera for us. mCameraDevice.lock(); + mStartRecPending = false; return; } @@ -1400,6 +1442,7 @@ public class VideoModule implements CameraModule, keepScreenOn(); UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA, UsageStatistics.ACTION_CAPTURE_START, "Video"); + mStartRecPending = false; } private Bitmap getVideoThumbnail() { @@ -1441,6 +1484,7 @@ public class VideoModule implements CameraModule, private boolean stopVideoRecording() { Log.v(TAG, "stopVideoRecording"); + mStopRecPending = true; mUI.setSwipingEnabled(true); if (!isVideoCaptureIntent()) { mUI.showSwitcher(); @@ -1510,6 +1554,7 @@ public class VideoModule implements CameraModule, fail ? UsageStatistics.ACTION_CAPTURE_FAIL : UsageStatistics.ACTION_CAPTURE_DONE, "Video", SystemClock.uptimeMillis() - mRecordingStartTime); + mStopRecPending = false; return fail; } -- cgit v1.2.3