Snap for 7325096 from d45b5950197f00dd394ddb3b348ad2922970e350 to sc-d1-release

Change-Id: I14d2cc0564a5276f9e8b207a521f60fc12b495b1
diff --git a/src/com/android/camera/MediaSaverImpl.java b/src/com/android/camera/MediaSaverImpl.java
index a8e96ec..781f774 100644
--- a/src/com/android/camera/MediaSaverImpl.java
+++ b/src/com/android/camera/MediaSaverImpl.java
@@ -22,6 +22,7 @@
 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 @@
  */
 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 @@
     }
 
     @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 @@
         }
     }
 
-    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 6c9752e..17d9fe7 100644
--- a/src/com/android/camera/VideoModule.java
+++ b/src/com/android/camera/VideoModule.java
@@ -148,9 +148,6 @@
     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 @@
         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 @@
                 }
             }
             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 @@
 
         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 @@
         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 @@
     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 @@
         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 @@
                 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 @@
             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 c96c55d..2fca6cb 100644
--- a/src/com/android/camera/app/MediaSaver.java
+++ b/src/com/android/camera/app/MediaSaver.java
@@ -149,12 +149,12 @@
     /**
      * 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.