fix free space calculation / querying timing problem
also, be (a little) more agressive about updating
available storage space so app generally has the most
up-to-date space calculation more often
bug: 14275001
Change-Id: I1aa91419be017f1248bb4b3b0aa805bd4e1b05c6
diff --git a/src/com/android/camera/CameraActivity.java b/src/com/android/camera/CameraActivity.java
index a9a6526..bd27f75 100644
--- a/src/com/android/camera/CameraActivity.java
+++ b/src/com/android/camera/CameraActivity.java
@@ -1051,6 +1051,7 @@
@Override
public void notifyNewMedia(Uri uri) {
+ updateStorageSpaceAndHint(null);
ContentResolver cr = getContentResolver();
String mimeType = cr.getType(uri);
if (LocalDataUtil.isMimeTypeVideo(mimeType)) {
@@ -1480,6 +1481,7 @@
Log.v(TAG, "Build info: " + Build.DISPLAY);
mPaused = false;
+ updateStorageSpaceAndHint(null);
mLastLayoutOrientation = getResources().getConfiguration().orientation;
@@ -1770,27 +1772,42 @@
}
}
- protected void updateStorageSpaceAndHint() {
+ protected interface OnStorageUpdateDoneListener {
+ public void onStorageUpdateDone(long bytes);
+ }
+
+ protected void updateStorageSpaceAndHint(final OnStorageUpdateDoneListener callback) {
/*
* We execute disk operations on a background thread in order to
* free up the UI thread. Synchronizing on the lock below ensures
* that when getStorageSpaceBytes is called, the main thread waits
* until this method has completed.
+ *
+ * However, .execute() does not ensure this execution block will be
+ * run right away (.execute() schedules this AsyncTask for sometime
+ * in the future. executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR)
+ * tries to execute the task in parellel with other AsyncTasks, but
+ * there's still no guarantee).
+ * e.g. don't call this then immediately call getStorageSpaceBytes().
+ * Instead, pass in an OnStorageUpdateDoneListener.
*/
- (new AsyncTask<Void, Void, Void>() {
+ (new AsyncTask<Void, Void, Long>() {
@Override
- protected Void doInBackground(Void ... arg) {
+ protected Long doInBackground(Void ... arg) {
synchronized (mStorageSpaceLock) {
mStorageSpaceBytes = Storage.getAvailableSpace();
+ return mStorageSpaceBytes;
}
- return null;
}
@Override
- protected void onPostExecute(Void ignore) {
- updateStorageHint(getStorageSpaceBytes());
+ protected void onPostExecute(Long bytes) {
+ updateStorageHint(bytes);
+ if (callback != null) {
+ callback.onStorageUpdateDone(bytes);
+ }
}
- }).execute();
+ }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
protected void updateStorageHint(long storageSpace) {
diff --git a/src/com/android/camera/PhotoModule.java b/src/com/android/camera/PhotoModule.java
index c92dfb4..28ed27d 100644
--- a/src/com/android/camera/PhotoModule.java
+++ b/src/com/android/camera/PhotoModule.java
@@ -612,7 +612,7 @@
mFirstTimeInitialized = true;
addIdleHandler();
- mActivity.updateStorageSpaceAndHint();
+ mActivity.updateStorageSpaceAndHint(null);
}
// If the activity is paused and resumed, this method will be called in
@@ -832,7 +832,7 @@
// latency. It's true that someone else could write to the SD card
// in the mean time and fill it, but that could have happened
// between the shutter press and saving the JPEG too.
- mActivity.updateStorageSpaceAndHint();
+ mActivity.updateStorageSpaceAndHint(null);
long now = System.currentTimeMillis();
mJpegCallbackFinishTime = now - mJpegPictureCallbackTime;
diff --git a/src/com/android/camera/VideoModule.java b/src/com/android/camera/VideoModule.java
index 23a9f5b..70cc12e 100644
--- a/src/com/android/camera/VideoModule.java
+++ b/src/com/android/camera/VideoModule.java
@@ -329,6 +329,8 @@
SettingsManager settingsManager = mActivity.getSettingsManager();
mCameraId = Integer.parseInt(settingsManager.get(SettingsManager.SETTING_CAMERA_ID));
+ mActivity.updateStorageSpaceAndHint(null);
+
/*
* To reduce startup time, we start the preview in another thread.
* We make sure the preview is started at the end of onCreate.
@@ -352,7 +354,6 @@
mShutterIconId = CameraUtil.getCameraShutterIconId(
mAppController.getCurrentModuleIndex(), mAppController.getAndroidContext());
-
}
@Override
@@ -1192,7 +1193,7 @@
if (what == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) {
// We may have run out of space on the sdcard.
stopVideoRecording();
- mActivity.updateStorageSpaceAndHint();
+ mActivity.updateStorageSpaceAndHint(null);
}
}
@@ -1235,57 +1236,60 @@
mUI.showFocusUI(false);
mUI.showVideoRecordingHints(false);
- mActivity.updateStorageSpaceAndHint();
- if (mActivity.getStorageSpaceBytes() <= Storage.LOW_STORAGE_THRESHOLD_BYTES) {
- Log.w(TAG, "Storage issue, ignore the start request");
- return;
- }
+ mActivity.updateStorageSpaceAndHint(new CameraActivity.OnStorageUpdateDoneListener() {
+ @Override
+ public void onStorageUpdateDone(long bytes) {
+ if (bytes <= Storage.LOW_STORAGE_THRESHOLD_BYTES) {
+ Log.w(TAG, "Storage issue, ignore the start request");
+ } else {
+ //??
+ //if (!mCameraDevice.waitDone()) return;
+ mCurrentVideoUri = null;
- //??
- //if (!mCameraDevice.waitDone()) return;
- mCurrentVideoUri = null;
+ initializeRecorder();
+ if (mMediaRecorder == null) {
+ Log.e(TAG, "Fail to initialize media recorder");
+ return;
+ }
- initializeRecorder();
- if (mMediaRecorder == null) {
- Log.e(TAG, "Fail to initialize media recorder");
- return;
- }
+ pauseAudioPlayback();
- pauseAudioPlayback();
+ try {
+ mMediaRecorder.start(); // Recording is now started
+ } catch (RuntimeException e) {
+ Log.e(TAG, "Could not start media recorder. ", e);
+ releaseMediaRecorder();
+ // If start fails, frameworks will not lock the camera for us.
+ mCameraDevice.lock();
+ return;
+ }
+ mAppController.getCameraAppUI().setSwipeEnabled(false);
- try {
- mMediaRecorder.start(); // Recording is now started
- } catch (RuntimeException e) {
- Log.e(TAG, "Could not start media recorder. ", e);
- releaseMediaRecorder();
- // If start fails, frameworks will not lock the camera for us.
- mCameraDevice.lock();
- return;
- }
- mAppController.getCameraAppUI().setSwipeEnabled(false);
+ // The parameters might have been altered by MediaRecorder already.
+ // We need to force mCameraDevice to refresh before getting it.
+ mCameraDevice.refreshParameters();
+ // The parameters may have been changed by MediaRecorder upon starting
+ // recording. We need to alter the parameters if we support camcorder
+ // zoom. To reduce latency when setting the parameters during zoom, we
+ // update mParameters here once.
+ mParameters = mCameraDevice.getParameters();
- // The parameters might have been altered by MediaRecorder already.
- // We need to force mCameraDevice to refresh before getting it.
- mCameraDevice.refreshParameters();
- // The parameters may have been changed by MediaRecorder upon starting
- // recording. We need to alter the parameters if we support camcorder
- // zoom. To reduce latency when setting the parameters during zoom, we
- // update mParameters here once.
- mParameters = mCameraDevice.getParameters();
+ mMediaRecorderRecording = true;
+ mActivity.lockOrientation();
+ mRecordingStartTime = SystemClock.uptimeMillis();
- mMediaRecorderRecording = true;
- mActivity.lockOrientation();
- mRecordingStartTime = SystemClock.uptimeMillis();
+ // A special case of mode options closing: during capture it should
+ // not be possible to change mode state.
+ mAppController.getCameraAppUI().hideModeOptions();
+ mAppController.getCameraAppUI().animateBottomBarToVideoStop(R.drawable.ic_stop);
+ mUI.showRecordingUI(true);
- // A special case of mode options closing: during capture it should
- // not be possible to change mode state.
- mAppController.getCameraAppUI().hideModeOptions();
- mAppController.getCameraAppUI().animateBottomBarToVideoStop(R.drawable.ic_stop);
- mUI.showRecordingUI(true);
-
- setFocusParameters();
- updateRecordingTime();
- mActivity.enableKeepScreenOn(true);
+ setFocusParameters();
+ updateRecordingTime();
+ mActivity.enableKeepScreenOn(true);
+ }
+ }
+ });
}
private Bitmap getVideoThumbnail() {
@@ -1387,6 +1391,13 @@
// by MediaRecorder.
mParameters = mCameraDevice.getParameters();
}
+
+ // Check this in advance of each shot so we don't add to shutter
+ // latency. It's true that someone else could write to the SD card
+ // in the mean time and fill it, but that could have happened
+ // between the shutter press and saving the file too.
+ mActivity.updateStorageSpaceAndHint(null);
+
return fail;
}