diff options
-rw-r--r-- | res/drawable-hdpi/ic_pausing_indicator.png | bin | 0 -> 2882 bytes | |||
-rw-r--r-- | res/drawable-hdpi/video_continue.png | bin | 0 -> 4004 bytes | |||
-rw-r--r-- | res/drawable-hdpi/video_pause.png | bin | 0 -> 3737 bytes | |||
-rw-r--r-- | res/drawable-mdpi/ic_pausing_indicator.png | bin | 0 -> 2861 bytes | |||
-rw-r--r-- | res/drawable-mdpi/video_continue.png | bin | 0 -> 3592 bytes | |||
-rw-r--r-- | res/drawable-mdpi/video_pause.png | bin | 0 -> 3426 bytes | |||
-rw-r--r-- | res/drawable-xhdpi/ic_pausing_indicator.png | bin | 0 -> 2825 bytes | |||
-rw-r--r-- | res/drawable-xhdpi/video_continue.png | bin | 0 -> 4223 bytes | |||
-rw-r--r-- | res/drawable-xhdpi/video_pause.png | bin | 0 -> 3837 bytes | |||
-rw-r--r-- | res/drawable/btn_pause_recording.xml | 33 | ||||
-rw-r--r-- | res/layout/video_module.xml | 21 | ||||
-rw-r--r-- | res/values/styles.xml | 2 | ||||
-rw-r--r-- | src/com/android/camera/PauseButton.java | 82 | ||||
-rw-r--r-- | src/com/android/camera/VideoController.java | 3 | ||||
-rw-r--r-- | src/com/android/camera/VideoModule.java | 42 | ||||
-rw-r--r-- | src/com/android/camera/VideoUI.java | 33 |
16 files changed, 207 insertions, 9 deletions
diff --git a/res/drawable-hdpi/ic_pausing_indicator.png b/res/drawable-hdpi/ic_pausing_indicator.png Binary files differnew file mode 100644 index 000000000..b3e5cb797 --- /dev/null +++ b/res/drawable-hdpi/ic_pausing_indicator.png diff --git a/res/drawable-hdpi/video_continue.png b/res/drawable-hdpi/video_continue.png Binary files differnew file mode 100644 index 000000000..901a2f048 --- /dev/null +++ b/res/drawable-hdpi/video_continue.png diff --git a/res/drawable-hdpi/video_pause.png b/res/drawable-hdpi/video_pause.png Binary files differnew file mode 100644 index 000000000..c7880b781 --- /dev/null +++ b/res/drawable-hdpi/video_pause.png diff --git a/res/drawable-mdpi/ic_pausing_indicator.png b/res/drawable-mdpi/ic_pausing_indicator.png Binary files differnew file mode 100644 index 000000000..4fe853c16 --- /dev/null +++ b/res/drawable-mdpi/ic_pausing_indicator.png diff --git a/res/drawable-mdpi/video_continue.png b/res/drawable-mdpi/video_continue.png Binary files differnew file mode 100644 index 000000000..1342b59f1 --- /dev/null +++ b/res/drawable-mdpi/video_continue.png diff --git a/res/drawable-mdpi/video_pause.png b/res/drawable-mdpi/video_pause.png Binary files differnew file mode 100644 index 000000000..2bc7e6c0c --- /dev/null +++ b/res/drawable-mdpi/video_pause.png diff --git a/res/drawable-xhdpi/ic_pausing_indicator.png b/res/drawable-xhdpi/ic_pausing_indicator.png Binary files differnew file mode 100644 index 000000000..24cb933b7 --- /dev/null +++ b/res/drawable-xhdpi/ic_pausing_indicator.png diff --git a/res/drawable-xhdpi/video_continue.png b/res/drawable-xhdpi/video_continue.png Binary files differnew file mode 100644 index 000000000..bf4b54e9d --- /dev/null +++ b/res/drawable-xhdpi/video_continue.png diff --git a/res/drawable-xhdpi/video_pause.png b/res/drawable-xhdpi/video_pause.png Binary files differnew file mode 100644 index 000000000..0317a226e --- /dev/null +++ b/res/drawable-xhdpi/video_pause.png diff --git a/res/drawable/btn_pause_recording.xml b/res/drawable/btn_pause_recording.xml new file mode 100644 index 000000000..61609cbcf --- /dev/null +++ b/res/drawable/btn_pause_recording.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2013, The Linux Foundation. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_selected="true" android:drawable="@drawable/video_continue" /> + <item android:drawable="@drawable/video_pause" /> +</selector> diff --git a/res/layout/video_module.xml b/res/layout/video_module.xml index 198be8913..af839e774 100644 --- a/res/layout/video_module.xml +++ b/res/layout/video_module.xml @@ -49,9 +49,24 @@ android:id="@+id/render_overlay" android:layout_width="match_parent" android:layout_height="match_parent" /> - <com.android.camera.ui.RotateLayout android:id="@+id/recording_time_rect" - style="@style/ViewfinderLabelLayout"> - <include layout="@layout/viewfinder_labels_video" android:id="@+id/labels" /> + <com.android.camera.ui.RotateLayout + android:id="@+id/recording_time_rect" + android:layout_height="match_parent" + android:layout_width="match_parent"> + <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="horizontal" + android:layout_height="match_parent" + android:layout_width="match_parent"> + <com.android.camera.PauseButton android:id="@+id/video_pause" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:layout_marginLeft="50dp" + android:padding="23dp" + android:visibility="gone" + android:src="@drawable/btn_pause_recording"/> + <include layout="@layout/viewfinder_labels_video" + android:id="@+id/labels" /> + </LinearLayout> </com.android.camera.ui.RotateLayout> <ImageView android:id="@+id/review_image" android:layout_height="match_parent" diff --git a/res/values/styles.xml b/res/values/styles.xml index 0d6241588..ad32b0634 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -112,7 +112,7 @@ <item name="android:layout_width">wrap_content</item> <item name="android:layout_height">wrap_content</item> <item name="android:singleLine">true</item> - <item name="android:layout_margin">10dp</item> + <item name="android:layout_marginTop">23dp</item> <item name="android:paddingLeft">15dp</item> <item name="android:paddingRight">15dp</item> <item name="android:paddingTop">3dp</item> diff --git a/src/com/android/camera/PauseButton.java b/src/com/android/camera/PauseButton.java new file mode 100644 index 000000000..a785050fd --- /dev/null +++ b/src/com/android/camera/PauseButton.java @@ -0,0 +1,82 @@ +/* Copyright (c) 2013, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +package com.android.camera; + +import android.content.Context; +import android.util.AttributeSet; +import android.widget.ImageView; +import android.view.MotionEvent; +import android.view.View; +import android.util.Log; + +/** + * A button designed to be used for the on-screen recording + * pausing-continue button. + */ +public class PauseButton extends ImageView { + + public interface OnPauseButtonListener { + void onButtonPause(); + void onButtonContinue(); + } + + public PauseButton(Context context, AttributeSet attrs) { + super(context, attrs); + setClickable(true); + setSelected(false); + } + + public void setPaused(boolean paused) { + setSelected(paused); + } + + @Override + public boolean performClick() { + boolean result = super.performClick(); + if (isSelected()) { + setSelected(false); + if (mListener != null && getVisibility() == View.VISIBLE) { + mListener.onButtonContinue(); + } + } else { + setSelected(true); + if (mListener != null && getVisibility() == View.VISIBLE) { + mListener.onButtonPause(); + } + } + return result; + } + + public void setOnPauseButtonListener(OnPauseButtonListener listener) { + mListener = listener; + } + + private OnPauseButtonListener mListener; +} diff --git a/src/com/android/camera/VideoController.java b/src/com/android/camera/VideoController.java index e84654821..cf694a391 100644 --- a/src/com/android/camera/VideoController.java +++ b/src/com/android/camera/VideoController.java @@ -19,8 +19,9 @@ package com.android.camera; import android.view.View; import com.android.camera.ShutterButton.OnShutterButtonListener; +import com.android.camera.PauseButton.OnPauseButtonListener; -public interface VideoController extends OnShutterButtonListener { +public interface VideoController extends OnShutterButtonListener, OnPauseButtonListener { public void onReviewDoneClicked(View view); public void onReviewCancelClicked(View viwe); diff --git a/src/com/android/camera/VideoModule.java b/src/com/android/camera/VideoModule.java index a79bc2531..f2562b144 100644 --- a/src/com/android/camera/VideoModule.java +++ b/src/com/android/camera/VideoModule.java @@ -129,7 +129,9 @@ public class VideoModule implements CameraModule, private boolean mSwitchingCamera; private boolean mMediaRecorderRecording = false; + private boolean mMediaRecorderPausing = false; private long mRecordingStartTime; + private long mRecordingTotalTime; private boolean mRecordingTimeCountsDown = false; private long mOnResumeTime; // The video file that the hardware camera is about to record into @@ -460,6 +462,7 @@ public class VideoModule implements CameraModule, // Preview area is touched. Take a picture. @Override public void onSingleTapUp(View view, int x, int y) { + if (mMediaRecorderPausing) return; takeASnapshot(); } @@ -1329,7 +1332,7 @@ public class VideoModule implements CameraModule, private void saveVideo() { if (mVideoFileDescriptor == null) { - long duration = SystemClock.uptimeMillis() - mRecordingStartTime; + long duration = SystemClock.uptimeMillis() - mRecordingStartTime + mRecordingTotalTime; if (duration > 0) { if (mCaptureTimeLapse) { duration = getTimeLapseVideoLength(duration); @@ -1491,7 +1494,10 @@ public class VideoModule implements CameraModule, mUI.enableCameraControls(false); mMediaRecorderRecording = true; + mMediaRecorderPausing = false; + mUI.resetPauseButton(); mOrientationManager.lockOrientation(); + mRecordingTotalTime = 0L; mRecordingStartTime = SystemClock.uptimeMillis(); mUI.showRecordingUI(true); @@ -1539,6 +1545,21 @@ public class VideoModule implements CameraModule, mUI.showTimeLapseUI(false); } + private void pauseVideoRecording() { + Log.v(TAG, "pauseVideoRecording"); + mMediaRecorderPausing = true; + mRecordingTotalTime += SystemClock.uptimeMillis() - mRecordingStartTime; + mMediaRecorder.pause(); + } + + private void resumeVideoRecording() { + Log.v(TAG, "resumeVideoRecording"); + mMediaRecorderPausing = false; + mRecordingStartTime = SystemClock.uptimeMillis(); + updateRecordingTime(); + mMediaRecorder.start(); + } + private boolean stopVideoRecording() { Log.v(TAG, "stopVideoRecording"); mStopRecPending = true; @@ -1616,7 +1637,7 @@ public class VideoModule implements CameraModule, UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA, fail ? UsageStatistics.ACTION_CAPTURE_FAIL : UsageStatistics.ACTION_CAPTURE_DONE, "Video", - SystemClock.uptimeMillis() - mRecordingStartTime); + SystemClock.uptimeMillis() - mRecordingStartTime + mRecordingTotalTime); mStopRecPending = false; return fail; } @@ -1693,8 +1714,12 @@ public class VideoModule implements CameraModule, if (!mMediaRecorderRecording) { return; } + if (mMediaRecorderPausing) { + return; + } + long now = SystemClock.uptimeMillis(); - long delta = now - mRecordingStartTime; + long delta = now - mRecordingStartTime + mRecordingTotalTime; // Starting a minute before reaching the max duration // limit, we'll countdown the remaining time instead. @@ -2227,4 +2252,15 @@ public class VideoModule implements CameraModule, public void onPreviewUIDestroyed() { stopPreview(); } + + @Override + public void onButtonPause() { + pauseVideoRecording(); + } + + @Override + public void onButtonContinue() { + resumeVideoRecording(); + } + } diff --git a/src/com/android/camera/VideoUI.java b/src/com/android/camera/VideoUI.java index bb270b7f8..8ea709141 100644 --- a/src/com/android/camera/VideoUI.java +++ b/src/com/android/camera/VideoUI.java @@ -49,6 +49,7 @@ import com.android.camera.ui.ModuleSwitcher; import com.android.camera.ui.PieRenderer; import com.android.camera.ui.RenderOverlay; import com.android.camera.ui.RotateLayout; +import com.android.camera.PauseButton.OnPauseButtonListener; import com.android.camera.ui.ZoomRenderer; import com.android.camera.util.CameraUtil; import com.android.camera2.R; @@ -58,7 +59,8 @@ import java.util.List; public class VideoUI implements PieRenderer.PieListener, PreviewGestures.SingleTapListener, CameraRootView.MyDisplayListener, - SurfaceTextureListener, SurfaceHolder.Callback { + SurfaceTextureListener, SurfaceHolder.Callback, + PauseButton.OnPauseButtonListener { private static final String TAG = "CAM_VideoUI"; private static final int UPDATE_TRANSFORM_MATRIX = 1; // module fields @@ -72,6 +74,7 @@ public class VideoUI implements PieRenderer.PieListener, private View mReviewDoneButton; private View mReviewPlayButton; private ShutterButton mShutterButton; + private PauseButton mPauseButton; private ModuleSwitcher mSwitcher; private TextView mRecordingTimeView; private LinearLayout mLabelsLinearLayout; @@ -192,6 +195,7 @@ public class VideoUI implements PieRenderer.PieListener, initializeMiscControls(); initializeControlByIntent(); initializeOverlay(); + initializePauseButton(); mAnimationManager = new AnimationManager(); mOrientationResize = false; mPrevOrientationResize = false; @@ -514,6 +518,11 @@ public class VideoUI implements PieRenderer.PieListener, mLabelsLinearLayout = (LinearLayout) mRootView.findViewById(R.id.labels); } + private void initializePauseButton() { + mPauseButton = (PauseButton) mRootView.findViewById(R.id.video_pause); + mPauseButton.setOnPauseButtonListener(this); + } + public void updateOnScreenIndicators(Parameters param, ComboPreferences prefs) { mOnScreenIndicators.updateFlashOnScreenIndicator(param.getFlashMode()); boolean location = RecordLocationPreference.get( @@ -631,12 +640,14 @@ public class VideoUI implements PieRenderer.PieListener, hideSwitcher(); mRecordingTimeView.setText(""); mRecordingTimeView.setVisibility(View.VISIBLE); + mPauseButton.setVisibility(View.VISIBLE); } else { mShutterButton.setImageResource(R.drawable.btn_new_shutter_video); if (!mController.isVideoCaptureIntent()) { showSwitcher(); } mRecordingTimeView.setVisibility(View.GONE); + mPauseButton.setVisibility(View.GONE); } } @@ -811,4 +822,24 @@ public class VideoUI implements PieRenderer.PieListener, Log.v(TAG, "Surface destroyed"); mController.stopPreview(); } + + @Override + public void onButtonPause() { + mRecordingTimeView.setCompoundDrawablesWithIntrinsicBounds( + R.drawable.ic_pausing_indicator, 0, 0, 0); + mController.onButtonPause(); + } + + @Override + public void onButtonContinue() { + mRecordingTimeView.setCompoundDrawablesWithIntrinsicBounds( + R.drawable.ic_recording_indicator, 0, 0, 0); + mController.onButtonContinue(); + } + + public void resetPauseButton() { + mRecordingTimeView.setCompoundDrawablesWithIntrinsicBounds( + R.drawable.ic_recording_indicator, 0, 0, 0); + mPauseButton.setPaused(false); + } } |