summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2021-04-29 18:13:37 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2021-04-29 18:13:37 +0000
commitd45b5950197f00dd394ddb3b348ad2922970e350 (patch)
treef7f45e1b6f0f715d2f4c5de4df26dde1869d39a6
parent94388cfc18059ff12456a89f07f2546917f4914d (diff)
parent58884f385b677b127a8727d9ac87b36ea86c0a0f (diff)
downloadCamera2-android12-qpr1-d-s1-release.tar.gz
Original change: https://android-review.googlesource.com/c/platform/packages/apps/Camera2/+/1690087 Change-Id: Iad85f7f2b7a84e640f5a6ec1599a32192ada910e
-rw-r--r--src/com/android/camera/MediaSaverImpl.java41
-rw-r--r--src/com/android/camera/VideoModule.java94
-rw-r--r--src/com/android/camera/app/MediaSaver.java6
3 files changed, 57 insertions, 84 deletions
diff --git a/src/com/android/camera/MediaSaverImpl.java b/src/com/android/camera/MediaSaverImpl.java
index a8e96ec97..781f7740b 100644
--- a/src/com/android/camera/MediaSaverImpl.java
+++ b/src/com/android/camera/MediaSaverImpl.java
@@ -22,6 +22,7 @@ import android.graphics.BitmapFactory;
import android.location.Location;
import android.net.Uri;
import android.os.AsyncTask;
+import android.provider.MediaStore;
import android.provider.MediaStore.Video;
import com.android.camera.app.MediaSaver;
@@ -37,7 +38,6 @@ import java.io.IOException;
*/
public class MediaSaverImpl implements MediaSaver {
private static final Log.Tag TAG = new Log.Tag("MediaSaverImpl");
- private static final String VIDEO_BASE_URI = "content://media/external/video/media";
/** The memory limit for unsaved image is 30MB. */
// TODO: Revert this back to 20 MB when CaptureSession API supports saving
@@ -107,10 +107,9 @@ public class MediaSaverImpl implements MediaSaver {
}
@Override
- public void addVideo(String path, ContentValues values, OnMediaSavedListener l) {
- // We don't set a queue limit for video saving because the file
- // is already in the storage. Only updating the database.
- new VideoSaveTask(path, values, l, mContentResolver).execute();
+ public void addVideo(Uri uri, ContentValues values, OnMediaSavedListener l) {
+ // This updates the content resolver for the final saving of the video file.
+ new VideoSaveTask(uri, values, l, mContentResolver).execute();
}
@Override
@@ -201,49 +200,35 @@ public class MediaSaverImpl implements MediaSaver {
}
}
- private class VideoSaveTask extends AsyncTask <Void, Void, Uri> {
- private String path;
+ private class VideoSaveTask extends AsyncTask <Void, Void, Void> {
+ private final Uri uri;
private final ContentValues values;
private final OnMediaSavedListener listener;
private final ContentResolver resolver;
- public VideoSaveTask(String path, ContentValues values, OnMediaSavedListener l,
+ public VideoSaveTask(Uri u, ContentValues values, OnMediaSavedListener l,
ContentResolver r) {
- this.path = path;
+ this.uri = u;
this.values = new ContentValues(values);
this.listener = l;
this.resolver = r;
}
@Override
- protected Uri doInBackground(Void... v) {
- Uri uri = null;
+ protected Void doInBackground(Void... v) {
try {
- Uri videoTable = Uri.parse(VIDEO_BASE_URI);
- uri = resolver.insert(videoTable, values);
-
- // Rename the video file to the final name. This avoids other
- // apps reading incomplete data. We need to do it after we are
- // certain that the previous insert to MediaProvider is completed.
- String finalName = values.getAsString(Video.Media.DATA);
- File finalFile = new File(finalName);
- if (new File(path).renameTo(finalFile)) {
- path = finalName;
- }
resolver.update(uri, values, null, null);
} catch (Exception e) {
- // We failed to insert into the database. This can happen if
- // the SD card is unmounted.
- Log.e(TAG, "failed to add video to media store", e);
- uri = null;
+ // We failed to update the database.
+ Log.e(TAG, "failed to update video to media store", e);
} finally {
Log.v(TAG, "Current video URI: " + uri);
+ return null;
}
- return uri;
}
@Override
- protected void onPostExecute(Uri uri) {
+ protected void onPostExecute(Void v) {
if (listener != null) {
listener.onMediaSaved(uri);
}
diff --git a/src/com/android/camera/VideoModule.java b/src/com/android/camera/VideoModule.java
index 6c9752e6e..17d9fe747 100644
--- a/src/com/android/camera/VideoModule.java
+++ b/src/com/android/camera/VideoModule.java
@@ -148,9 +148,6 @@ public class VideoModule extends CameraModule
private long mRecordingStartTime;
private boolean mRecordingTimeCountsDown = false;
private long mOnResumeTime;
- // The video file that the hardware camera is about to record into
- // (or is recording into.
- private String mVideoFilename;
private ParcelFileDescriptor mVideoFileDescriptor;
// The video file that has already been recorded, and that is being
@@ -1087,16 +1084,6 @@ public class VideoModule extends CameraModule
mActivity.finish();
}
- private void cleanupEmptyFile() {
- if (mVideoFilename != null) {
- File f = new File(mVideoFilename);
- if (f.length() == 0 && f.delete()) {
- Log.v(TAG, "Empty video file deleted: " + mVideoFilename);
- mVideoFilename = null;
- }
- }
- }
-
// Prepares media recorder.
private void initializeRecorder() {
Log.i(TAG, "initializeRecorder: " + Thread.currentThread());
@@ -1124,7 +1111,23 @@ public class VideoModule extends CameraModule
}
}
requestedSizeLimit = myExtras.getLong(MediaStore.EXTRA_SIZE_LIMIT);
+ } else {
+ generateVideoValues();
+ Uri videoTable = MediaStore.Video.Media.getContentUri(
+ MediaStore.VOLUME_EXTERNAL_PRIMARY);
+ Uri videoUri = mContentResolver.insert(videoTable, mCurrentVideoValues);
+
+ try {
+ mVideoFileDescriptor =
+ mContentResolver.openFileDescriptor(videoUri, "rw");
+ mCurrentVideoUri = videoUri;
+ } catch (java.io.FileNotFoundException ex) {
+ // invalid uri
+ mContentResolver.delete(videoUri, null, null);
+ Log.e(TAG, ex.toString());
+ }
}
+
mMediaRecorder = new MediaRecorder();
// Unlock the camera object before passing it to media recorder.
mCameraDevice.unlock();
@@ -1149,14 +1152,12 @@ public class VideoModule extends CameraModule
setRecordLocation();
- // Set output file.
- // Try Uri in the intent first. If it doesn't exist, use our own
- // instead.
+ // Set output file using video Uri.
if (mVideoFileDescriptor != null) {
mMediaRecorder.setOutputFile(mVideoFileDescriptor.getFileDescriptor());
} else {
- generateVideoFilename(mProfile.fileFormat);
- mMediaRecorder.setOutputFile(mVideoFilename);
+ releaseMediaRecorder();
+ throw new RuntimeException("No valid video file descriptor");
}
// Set maximum file size.
@@ -1185,7 +1186,7 @@ public class VideoModule extends CameraModule
try {
mMediaRecorder.prepare();
} catch (IOException e) {
- Log.e(TAG, "prepare failed for " + mVideoFilename, e);
+ Log.e(TAG, "prepare failed", e);
releaseMediaRecorder();
throw new RuntimeException(e);
}
@@ -1209,41 +1210,34 @@ public class VideoModule extends CameraModule
private void releaseMediaRecorder() {
Log.i(TAG, "Releasing media recorder.");
if (mMediaRecorder != null) {
- cleanupEmptyFile();
mMediaRecorder.reset();
mMediaRecorder.release();
mMediaRecorder = null;
}
- mVideoFilename = null;
}
- private void generateVideoFilename(int outputFileFormat) {
+ private void generateVideoValues() {
long dateTaken = System.currentTimeMillis();
String title = createName(dateTaken);
// Used when emailing.
- String filename = title + convertOutputFormatToFileExt(outputFileFormat);
- String mime = convertOutputFormatToMimeType(outputFileFormat);
- String path = Storage.instance().DIRECTORY + '/' + filename;
- String tmpPath = path + ".tmp";
+ String mime = convertOutputFormatToMimeType(mProfile.fileFormat);
mCurrentVideoValues = new ContentValues(9);
mCurrentVideoValues.put(Video.Media.TITLE, title);
- mCurrentVideoValues.put(Video.Media.DISPLAY_NAME, filename);
+ mCurrentVideoValues.put(Video.Media.DISPLAY_NAME, title);
mCurrentVideoValues.put(Video.Media.DATE_TAKEN, dateTaken);
mCurrentVideoValues.put(MediaColumns.DATE_MODIFIED, dateTaken / 1000);
mCurrentVideoValues.put(Video.Media.MIME_TYPE, mime);
- mCurrentVideoValues.put(Video.Media.DATA, path);
mCurrentVideoValues.put(Video.Media.WIDTH, mProfile.videoFrameWidth);
mCurrentVideoValues.put(Video.Media.HEIGHT, mProfile.videoFrameHeight);
mCurrentVideoValues.put(Video.Media.RESOLUTION,
Integer.toString(mProfile.videoFrameWidth) + "x" +
Integer.toString(mProfile.videoFrameHeight));
+ mCurrentVideoValues.put(Video.Media.IS_PENDING, 1);
Location loc = mLocationManager.getCurrentLocation();
if (loc != null) {
mCurrentVideoValues.put(Video.Media.LATITUDE, loc.getLatitude());
mCurrentVideoValues.put(Video.Media.LONGITUDE, loc.getLongitude());
}
- mVideoFilename = tmpPath;
- Log.v(TAG, "New video filename: " + mVideoFilename);
}
private void logVideoCapture(long duration) {
@@ -1253,26 +1247,25 @@ public class VideoModule extends CameraModule
boolean gridLinesOn = Keys.areGridLinesOn(mActivity.getSettingsManager());
int width = (Integer) mCurrentVideoValues.get(Video.Media.WIDTH);
int height = (Integer) mCurrentVideoValues.get(Video.Media.HEIGHT);
- long size = new File(mCurrentVideoFilename).length();
- String name = new File(mCurrentVideoValues.getAsString(Video.Media.DATA)).getName();
+ long size = (Long) mCurrentVideoValues.get(Video.Media.SIZE);
+ String name = (String) mCurrentVideoValues.get(Video.Media.DISPLAY_NAME);
UsageStatistics.instance().videoCaptureDoneEvent(name, duration, isCameraFrontFacing(),
currentZoomValue(), width, height, size, flashSetting, gridLinesOn);
}
private void saveVideo() {
- if (mVideoFileDescriptor == null) {
- long duration = SystemClock.uptimeMillis() - mRecordingStartTime;
- if (duration > 0) {
- //
- } else {
- Log.w(TAG, "Video duration <= 0 : " + duration);
- }
- mCurrentVideoValues.put(Video.Media.SIZE, new File(mCurrentVideoFilename).length());
- mCurrentVideoValues.put(Video.Media.DURATION, duration);
- getServices().getMediaSaver().addVideo(mCurrentVideoFilename,
- mCurrentVideoValues, mOnVideoSavedListener);
- logVideoCapture(duration);
- }
+ long duration = SystemClock.uptimeMillis() - mRecordingStartTime;
+ if (duration > 0) {
+ //
+ } else {
+ Log.w(TAG, "Video duration <= 0 : " + duration);
+ }
+ mCurrentVideoValues.put(Video.Media.SIZE, mVideoFileDescriptor.getStatSize());
+ mCurrentVideoValues.put(Video.Media.DURATION, duration);
+ mCurrentVideoValues.put(Video.Media.IS_PENDING, 0);
+ getServices().getMediaSaver().addVideo(mCurrentVideoUri,
+ mCurrentVideoValues, mOnVideoSavedListener);
+ logVideoCapture(duration);
mCurrentVideoValues = null;
}
@@ -1489,13 +1482,8 @@ public class VideoModule extends CameraModule
mMediaRecorder.setOnInfoListener(null);
mMediaRecorder.stop();
shouldAddToMediaStoreNow = true;
- mCurrentVideoFilename = mVideoFilename;
- Log.v(TAG, "stopVideoRecording: current video filename: " + mCurrentVideoFilename);
} catch (RuntimeException e) {
Log.e(TAG, "stop fail", e);
- if (mVideoFilename != null) {
- deleteVideoFile(mVideoFilename);
- }
fail = true;
}
mMediaRecorderRecording = false;
@@ -1517,11 +1505,11 @@ public class VideoModule extends CameraModule
mUI.setOrientationIndicator(0, true);
mActivity.enableKeepScreenOn(false);
if (shouldAddToMediaStoreNow && !fail) {
- if (mVideoFileDescriptor == null) {
- saveVideo();
- } else if (mIsVideoCaptureIntent) {
+ if (mIsVideoCaptureIntent) {
// if no file save is needed, we can show the post capture UI now
showCaptureResult();
+ } else {
+ saveVideo();
}
}
}
diff --git a/src/com/android/camera/app/MediaSaver.java b/src/com/android/camera/app/MediaSaver.java
index c96c55d20..2fca6cbd5 100644
--- a/src/com/android/camera/app/MediaSaver.java
+++ b/src/com/android/camera/app/MediaSaver.java
@@ -149,12 +149,12 @@ public interface MediaSaver {
/**
* Adds the video data into the {@link android.content.ContentResolver} in
* the background. Only the database is updated here. The file should
- * already be created by {@link android.media.MediaRecorder}.
- * @param path The path of the video file on the storage.
+ * already be created by the ContentResolver.insert called earlier..
+ * @param uri The Uri of the video file in the database.
* @param values The values to be stored in the database.
* @param l A callback object used when the saving is done.
*/
- void addVideo(String path, ContentValues values, OnMediaSavedListener l);
+ void addVideo(Uri uri, ContentValues values, OnMediaSavedListener l);
/**
* Sets the queue listener.