OSDN Git Service

Make video snapshot save images in the background.
authorAngus Kong <shkong@google.com>
Fri, 1 Feb 2013 02:22:44 +0000 (18:22 -0800)
committerAngus Kong <shkong@google.com>
Fri, 1 Feb 2013 02:30:27 +0000 (18:30 -0800)
bug:8114662
Change-Id: I4e96269bd7723dd9a82d2905a01f736c8982c4ed

src/com/android/camera/CameraActivity.java
src/com/android/camera/CameraModule.java
src/com/android/camera/MediaSaveService.java
src/com/android/camera/PanoramaModule.java
src/com/android/camera/PhotoModule.java
src/com/android/camera/VideoModule.java

index 9f9f1b6..bf1ec24 100644 (file)
@@ -20,10 +20,13 @@ import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
 import android.content.Context;
+import android.content.ComponentName;
 import android.content.Intent;
+import android.content.ServiceConnection;
 import android.content.res.Configuration;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
+import android.os.IBinder;
 import android.provider.MediaStore;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
@@ -59,6 +62,18 @@ public class CameraActivity extends ActivityBase
     // The degrees of the device rotated clockwise from its natural orientation.
     private int mLastRawOrientation = OrientationEventListener.ORIENTATION_UNKNOWN;
 
+    private MediaSaveService mMediaSaveService;
+    private ServiceConnection mConnection = new ServiceConnection() {
+            @Override
+            public void onServiceConnected(ComponentName className, IBinder b) {
+                mMediaSaveService = ((MediaSaveService.LocalBinder) b).getService();
+                mCurrentModule.onMediaSaveServiceConnected(mMediaSaveService);
+            }
+            @Override
+            public void onServiceDisconnected(ComponentName className) {
+                mMediaSaveService = null;
+            }};
+
     private static final String TAG = "CAM_activity";
 
     private static final int[] DRAW_IDS = {
@@ -89,6 +104,7 @@ public class CameraActivity extends ActivityBase
         mCurrentModule.init(this, mFrame, true);
         mSwitcher.setCurrentIndex(mCurrentModuleIndex);
         mOrientationListener = new MyOrientationEventListener(this);
+        bindMediaSaveService();
     }
 
     public void init() {
@@ -118,6 +134,12 @@ public class CameraActivity extends ActivityBase
         mSwitcher.setCurrentIndex(mCurrentModuleIndex);
     }
 
+    @Override
+    public void onDestroy() {
+        unbindMediaSaveService();
+        super.onDestroy();
+    }
+
     private class MyOrientationEventListener
             extends OrientationEventListener {
         public MyOrientationEventListener(Context context) {
@@ -184,6 +206,9 @@ public class CameraActivity extends ActivityBase
         }
         openModule(mCurrentModule, canReuse);
         mCurrentModule.onOrientationChanged(mLastRawOrientation);
+        if (mMediaSaveService != null) {
+            mCurrentModule.onMediaSaveServiceConnected(mMediaSaveService);
+        }
         getCameraScreenNail().setAlpha(0f);
         getCameraScreenNail().setOnFrameDrawnOneShot(mOnFrameDrawn);
     }
@@ -298,6 +323,18 @@ public class CameraActivity extends ActivityBase
         mCurrentModule.onResumeAfterSuper();
     }
 
+    private void bindMediaSaveService() {
+        Intent intent = new Intent(this, MediaSaveService.class);
+        startService(intent);  // start service before binding it so the
+                               // service won't be killed if we unbind it.
+        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
+    }
+
+    private void unbindMediaSaveService() {
+        mMediaSaveService.setListener(null);
+        unbindService(mConnection);
+    }
+
     @Override
     protected void onFullScreenChanged(boolean full) {
         if (full) {
@@ -481,4 +518,8 @@ public class CameraActivity extends ActivityBase
     public CameraScreenNail getCameraScreenNail() {
         return (CameraScreenNail) mCameraScreenNail;
     }
+
+    public MediaSaveService getMediaSaveService() {
+        return mMediaSaveService;
+    }
 }
index 8e022d6..37eabd0 100644 (file)
@@ -72,4 +72,5 @@ public interface CameraModule {
 
     public void onShowSwitcherPopup();
 
+    public void onMediaSaveServiceConnected(MediaSaveService s);
 }
index f871975..d0e02f1 100644 (file)
@@ -26,8 +26,9 @@ import android.os.Binder;
 import android.os.IBinder;
 import android.util.Log;
 
-import java.util.ArrayList;
-
+/*
+ * Service for saving images in the background thread.
+ */
 public class MediaSaveService extends Service {
     private static final int SAVE_TASK_LIMIT = 3;
     private static final String TAG = MediaSaveService.class.getSimpleName();
index 1829087..6302158 100644 (file)
@@ -1309,4 +1309,9 @@ public class PanoramaModule implements CameraModule,
     @Override
     public void onShowSwitcherPopup() {
     }
+
+    @Override
+    public void onMediaSaveServiceConnected(MediaSaveService s) {
+        // do nothing.
+    }
 }
index 14477b7..ec6dcab 100644 (file)
@@ -19,13 +19,10 @@ package com.android.camera;
 import android.annotation.TargetApi;
 import android.app.Activity;
 import android.app.AlertDialog;
-import android.content.ComponentName;
 import android.content.ContentProviderClient;
 import android.content.ContentResolver;
-import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
-import android.content.ServiceConnection;
 import android.content.SharedPreferences.Editor;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
@@ -42,7 +39,6 @@ import android.net.Uri;
 import android.os.Bundle;
 import android.os.ConditionVariable;
 import android.os.Handler;
-import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
 import android.os.MessageQueue;
@@ -204,19 +200,6 @@ public class PhotoModule
     // A view group that contains all the small indicators.
     private View mOnScreenIndicators;
 
-    // We use MediaSaveService to do the work of saving images in background. This
-    // reduces the shot-to-shot time.
-    private MediaSaveService mMediaSaveService;
-    private ServiceConnection mConnection = new ServiceConnection() {
-            @Override
-            public void onServiceConnected(ComponentName className, IBinder b) {
-                mMediaSaveService = ((MediaSaveService.LocalBinder) b).getService();
-                mMediaSaveService.setListener(PhotoModule.this);
-            }
-            @Override
-            public void onServiceDisconnected(ComponentName className) {
-                mMediaSaveService = null;
-            }};
     // We use a queue to generated names of the images to be used later
     // when the image is ready to be saved.
     private NamedImages mNamedImages;
@@ -657,14 +640,13 @@ public class PhotoModule
         mShutterButton = mActivity.getShutterButton();
         mShutterButton.setImageResource(R.drawable.btn_new_shutter);
         mShutterButton.setOnShutterButtonListener(this);
-        if (mMediaSaveService != null) {
-            if (mMediaSaveService.isQueueFull()) {
-                mShutterButton.enableTouch(false);
-            } else {
-                mShutterButton.enableTouch(true);
-            }
-        }
         mShutterButton.setVisibility(View.VISIBLE);
+        MediaSaveService s = mActivity.getMediaSaveService();
+        // We set the listener only when both service and shutterbutton
+        // are initialized.
+        if (s != null) {
+            s.setListener(this);
+        }
 
         mNamedImages = new NamedImages();
 
@@ -703,6 +685,10 @@ public class PhotoModule
                 mPreferences, mContentResolver);
         mLocationManager.recordLocation(recordLocation);
 
+        MediaSaveService s = mActivity.getMediaSaveService();
+        if (s != null) {
+            s.setListener(this);
+        }
         mNamedImages = new NamedImages();
         initializeZoom();
         keepMediaProviderInstance();
@@ -1008,7 +994,8 @@ public class PhotoModule
                     Log.e(TAG, "Unbalanced name/data pair");
                 } else {
                     if (date == -1) date = mCaptureStartTime;
-                    mMediaSaveService.addImage(jpegData, title, date, mLocation, width, height,
+                    mActivity.getMediaSaveService().addImage(
+                            jpegData, title, date, mLocation, width, height,
                             orientation, mOnMediaSavedListener, mContentResolver);
                 }
             } else {
@@ -1131,7 +1118,8 @@ public class PhotoModule
         // If we are already in the middle of taking a snapshot or the image save request
         // is full then ignore.
         if (mCameraDevice == null || mCameraState == SNAPSHOT_IN_PROGRESS
-                || mCameraState == SWITCHING_CAMERA || mMediaSaveService.isQueueFull()) {
+                || mCameraState == SWITCHING_CAMERA
+                || mActivity.getMediaSaveService().isQueueFull()) {
             return false;
         }
         mCaptureStartTime = System.currentTimeMillis();
@@ -1531,7 +1519,6 @@ public class PhotoModule
             mCameraStartUpThread.start();
         }
 
-        bindMediaSaveService();
         // If first time initialization is not finished, put it in the
         // message queue.
         if (!mFirstTimeInitialized) {
@@ -1545,18 +1532,6 @@ public class PhotoModule
         PopupManager.getInstance(mActivity).notifyShowPopup(null);
     }
 
-    private void bindMediaSaveService() {
-        Intent intent = new Intent(mActivity, MediaSaveService.class);
-        mActivity.startService(intent);  // start service before binding it so the
-                                         // service won't be killed if we unbind it.
-        mActivity.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
-    }
-
-    private void unbindMediaSaveService() {
-        mMediaSaveService.setListener(null);
-        mActivity.unbindService(mConnection);
-    }
-
     void waitCameraStartUpThread() {
         try {
             if (mCameraStartUpThread != null) {
@@ -1603,7 +1578,6 @@ public class PhotoModule
             mSurfaceTexture = null;
         }
         resetScreenOn();
-        unbindMediaSaveService();
 
         // Clear UI.
         collapseCameraControls();
@@ -1630,6 +1604,10 @@ public class PhotoModule
 
         mPendingSwitchCameraId = -1;
         if (mFocusManager != null) mFocusManager.removeMessages();
+        MediaSaveService s = mActivity.getMediaSaveService();
+        if (s != null) {
+            s.setListener(null);
+        }
     }
 
     private void initializeControlByIntent() {
@@ -2509,4 +2487,11 @@ public class PhotoModule
     public void onQueueFull() {
         if (mShutterButton != null) mShutterButton.enableTouch(false);
     }
+
+    @Override
+    public void onMediaSaveServiceConnected(MediaSaveService s) {
+        // We set the listener only when both service and shutterbutton
+        // are initialized.
+        if (mShutterButton != null) s.setListener(this);
+    }
 }
index d32234a..8d84e00 100644 (file)
@@ -237,6 +237,17 @@ public class VideoModule implements CameraModule,
     private boolean mRestoreFlash;  // This is used to check if we need to restore the flash
                                     // status when going back from gallery.
 
+    private MediaSaveService.OnMediaSavedListener mOnMediaSavedListener =
+            new MediaSaveService.OnMediaSavedListener() {
+                @Override
+                public void onMediaSaved(Uri uri) {
+                    if (uri != null) {
+                        Util.broadcastNewPicture(mActivity, uri);
+                    }
+                }
+            };
+
+
     protected class CameraOpenThread extends Thread {
         @Override
         public void run() {
@@ -2165,6 +2176,7 @@ public class VideoModule implements CameraModule,
         mShutterButton.setImageResource(R.drawable.btn_new_shutter_video);
         mShutterButton.setOnShutterButtonListener(this);
         mShutterButton.requestFocus();
+        mShutterButton.enableTouch(true);
 
         // Disable the shutter button if effects are ON since it might take
         // a little more time for the effects preview to be ready. We do not
@@ -2465,7 +2477,8 @@ public class VideoModule implements CameraModule,
             return;
         }
 
-        if (mPaused || mSnapshotInProgress || effectsActive()) {
+        MediaSaveService s = mActivity.getMediaSaveService();
+        if (mPaused || mSnapshotInProgress || effectsActive() || s == null || s.isQueueFull()) {
             return;
         }
 
@@ -2568,11 +2581,9 @@ public class VideoModule implements CameraModule,
         String title = Util.createJpegName(dateTaken);
         int orientation = Exif.getOrientation(data);
         Size s = mParameters.getPictureSize();
-        Uri uri = Storage.addImage(mContentResolver, title, dateTaken, loc, orientation, data,
-                s.width, s.height);
-        if (uri != null) {
-            Util.broadcastNewPicture(mActivity, uri);
-        }
+        mActivity.getMediaSaveService().addImage(
+                data, title, dateTaken, loc, s.width, s.height,
+                orientation, mOnMediaSavedListener, mContentResolver);
     }
 
     private boolean resetEffect() {
@@ -2813,4 +2824,9 @@ public class VideoModule implements CameraModule,
             mPieRenderer.hide();
         }
     }
+
+    @Override
+    public void onMediaSaveServiceConnected(MediaSaveService s) {
+        // do nothing.
+    }
 }