VideoCamera.java revision 101d528d59f447847d5c6b7578642132c2b76f4f
1b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project/*
2b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project *
4b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * you may not use this file except in compliance with the License.
6b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * You may obtain a copy of the License at
7b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project *
8b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project *
10b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * See the License for the specific language governing permissions and
14b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * limitations under the License.
15b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project */
16b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
17b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectpackage com.android.camera;
18b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
19101d528d59f447847d5c6b7578642132c2b76f4fOwen Linimport com.android.camera.gallery.IImage;
20101d528d59f447847d5c6b7578642132c2b76f4fOwen Linimport com.android.camera.gallery.IImageList;
21101d528d59f447847d5c6b7578642132c2b76f4fOwen Linimport com.android.camera.gallery.Util;
22101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin
23b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.io.File;
24b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.io.FileDescriptor;
25b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.io.IOException;
26b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.text.SimpleDateFormat;
27b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.util.ArrayList;
28b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.util.Date;
29b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
30b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.app.Activity;
31b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.BroadcastReceiver;
32b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.ContentResolver;
33b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.ContentValues;
34b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.Context;
35b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.Intent;
36b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.IntentFilter;
37b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.SharedPreferences;
38095afa19556bf550262e3cccb9edacc04e6f726aOwen Linimport android.database.Cursor;
39b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.graphics.Bitmap;
40b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.graphics.drawable.Drawable;
41b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.location.LocationManager;
42b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.media.MediaRecorder;
43b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.net.Uri;
44b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Bundle;
45b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Environment;
46b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Handler;
47b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Message;
48b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.StatFs;
49b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.SystemClock;
50b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.preference.PreferenceManager;
51b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.provider.MediaStore;
52b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.provider.MediaStore.Video;
53b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.text.format.DateFormat;
54b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.util.Log;
55b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.KeyEvent;
56b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.Menu;
57b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.MenuItem;
58b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.SurfaceHolder;
59b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.View;
60b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.Window;
61b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.WindowManager;
62b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.MenuItem.OnMenuItemClickListener;
63b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.animation.AlphaAnimation;
64b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.animation.Animation;
65b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.widget.ImageView;
66b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.widget.TextView;
67b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.widget.Toast;
68b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
69b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectpublic class VideoCamera extends Activity implements View.OnClickListener,
708d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project    ShutterButton.OnShutterButtonListener, SurfaceHolder.Callback, MediaRecorder.OnErrorListener, MediaRecorder.OnInfoListener {
71b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
72b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final String TAG = "videocamera";
73b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
74b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final boolean DEBUG = true;
75b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final boolean DEBUG_SUPPRESS_AUDIO_RECORDING = DEBUG && false;
76b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
77b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final int CLEAR_SCREEN_DELAY = 4;
78b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final int UPDATE_RECORD_TIME = 5;
79b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
80b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final int SCREEN_DELAY = 2 * 60 * 1000;
81b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
82b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final long NO_STORAGE_ERROR = -1L;
83b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final long CANNOT_STAT_ERROR = -2L;
84b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final long LOW_STORAGE_THRESHOLD = 512L * 1024L;
85e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project    private static final long SHARE_FILE_LENGTH_LIMIT = 3L * 1024L * 1024L;
86b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
879a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project    private static final int STORAGE_STATUS_OK = 0;
889a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project    private static final int STORAGE_STATUS_LOW = 1;
899a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project    private static final int STORAGE_STATUS_NONE = 2;
909a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project
91b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_SETTINGS = 6;
92b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_GALLERY_PHOTOS = 7;
93b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_GALLERY_VIDEOS = 8;
94b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_SAVE_GALLERY_PHOTO = 34;
95b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_SAVE_PLAY_VIDEO = 35;
96b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_SAVE_SELECT_VIDEO = 36;
97b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_SAVE_NEW_VIDEO = 37;
98b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
99b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    SharedPreferences mPreferences;
100b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
101b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final float VIDEO_ASPECT_RATIO = 176.0f / 144.0f;
102b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    VideoPreview mVideoPreview;
103b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    SurfaceHolder mSurfaceHolder = null;
104b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    ImageView mVideoFrame;
1059bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang
1069bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private boolean mIsVideoCaptureIntent;
1079bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    // mLastPictureButton and mThumbController
1089bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    // are non-null only if isVideoCaptureIntent() is true;
109de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project    private ImageView mLastPictureButton;
1109bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private ThumbnailController mThumbController;
111b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1128d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project    private static final int MAX_RECORDING_DURATION_MS = 10 * 60 * 1000;
1138d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project
1149a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project    private int mStorageStatus = STORAGE_STATUS_OK;
1159a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project
116b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private MediaRecorder mMediaRecorder;
117b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private boolean mMediaRecorderRecording = false;
118b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private long mRecordingStartTime;
119b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    // The video file that the hardware camera is about to record into
120b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    // (or is recording into.)
121b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private String mCameraVideoFilename;
122b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private FileDescriptor mCameraVideoFileDescriptor;
123b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
124b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    // The video file that has already been recorded, and that is being
125b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    // examined by the user.
126b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private String mCurrentVideoFilename;
1278d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project    private long mCurrentVideoFileLength = 0L;
128b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private Uri mCurrentVideoUri;
129b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private ContentValues mCurrentVideoValues;
130b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
131b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    boolean mPausing = false;
132b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
133b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    static ContentResolver mContentResolver;
134b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
135b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    int mCurrentZoomIndex = 0;
136b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
137b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private ShutterButton mShutterButton;
138b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private TextView mRecordingTimeView;
1398d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project    private boolean mRecordingTimeCountsDown = false;
140b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
141b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    ArrayList<MenuItem> mGalleryItems = new ArrayList<MenuItem>();
142b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
143b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    View mPostPictureAlert;
144b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    LocationManager mLocationManager = null;
145b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
146b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private Handler mHandler = new MainHandler();
147b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
148b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    /** This Handler is used to post message back onto the main thread of the application */
149b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private class MainHandler extends Handler {
150b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        @Override
151b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        public void handleMessage(Message msg) {
152b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            switch (msg.what) {
153b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
154b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                case CLEAR_SCREEN_DELAY: {
155b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    clearScreenOnFlag();
156b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    break;
157b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
158b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
159b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                case UPDATE_RECORD_TIME: {
160b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    if (mMediaRecorderRecording) {
161b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        long now = SystemClock.uptimeMillis();
162b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        long delta = now - mRecordingStartTime;
1638d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project
1648d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                        // Starting a minute before reaching the max duration
1658d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                        // limit, we'll countdown the remaining time instead.
1668d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                        boolean countdown_remaining_time =
1678d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                            (delta >= MAX_RECORDING_DURATION_MS - 60000);
1688d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project
1698d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                        if (countdown_remaining_time) {
1708d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                            delta = Math.max(0, MAX_RECORDING_DURATION_MS - delta);
1718d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                        }
1728d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project
1738d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                        long seconds = (delta + 500) / 1000;  // round to nearest
174b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        long minutes = seconds / 60;
175b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        long hours = minutes / 60;
176b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        long remainderMinutes = minutes - (hours * 60);
177b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        long remainderSeconds = seconds - (minutes * 60);
178b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
179b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        String secondsString = Long.toString(remainderSeconds);
180b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        if (secondsString.length() < 2) {
181b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            secondsString = "0" + secondsString;
182b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        }
183b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        String minutesString = Long.toString(remainderMinutes);
184b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        if (minutesString.length() < 2) {
185b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            minutesString = "0" + minutesString;
186b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        }
187b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        String text = minutesString + ":" + secondsString;
188b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        if (hours > 0) {
189b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            String hoursString = Long.toString(hours);
190b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            if (hoursString.length() < 2) {
191b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                                hoursString = "0" + hoursString;
192b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            }
193b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            text = hoursString + ":" + text;
194b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        }
195b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        mRecordingTimeView.setText(text);
1968d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project
1978d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                        if (mRecordingTimeCountsDown != countdown_remaining_time) {
1988d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                            // Avoid setting the color on every update, do it only
1998d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                            // when it needs changing.
2008d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project
2018d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                            mRecordingTimeCountsDown = countdown_remaining_time;
2028d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project
2038d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                            int color = getResources().getColor(
2048d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                                    countdown_remaining_time ? R.color.recording_time_remaining_text
2058d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                                                             : R.color.recording_time_elapsed_text);
2068d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project
2078d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                            mRecordingTimeView.setTextColor(color);
2088d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                        }
2098d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project
210b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        // Work around a limitation of the T-Mobile G1: The T-Mobile
211b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        // hardware blitter can't pixel-accurately scale and clip at the same time,
212b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        // and the SurfaceFlinger doesn't attempt to work around this limitation.
213b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        // In order to avoid visual corruption we must manually refresh the entire
214b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        // surface view when changing any overlapping view's contents.
215b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        mVideoPreview.invalidate();
216b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        mHandler.sendEmptyMessageDelayed(UPDATE_RECORD_TIME, 1000);
217b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    }
218b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    break;
219b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
220b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
221b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                default:
222b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    Log.v(TAG, "Unhandled message: " + msg.what);
223b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                  break;
224b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
225b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
226b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    };
227b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
228b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
229b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        @Override
230b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        public void onReceive(Context context, Intent intent) {
231b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            String action = intent.getAction();
232b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (action.equals(Intent.ACTION_MEDIA_EJECT)) {
2339a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project                updateAndShowStorageHint(false);
234b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                stopVideoRecording();
235b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                initializeVideo();
236b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } else if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) {
2379a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project                updateAndShowStorageHint(true);
238b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                initializeVideo();
239b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } else if (action.equals(Intent.ACTION_MEDIA_UNMOUNTED)) {
240b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                // SD card unavailable
2419a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project                // handled in ACTION_MEDIA_EJECT
242b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_STARTED)) {
243b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                Toast.makeText(VideoCamera.this, getResources().getString(R.string.wait), 5000);
244b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) {
2459a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project                updateAndShowStorageHint(true);
246b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
247b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
248b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    };
249b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
250b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    static private String createName(long dateTaken) {
251b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return DateFormat.format("yyyy-MM-dd kk.mm.ss", dateTaken).toString();
252b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
253b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
254b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    /** Called with the activity is first created. */
255b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
256b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void onCreate(Bundle icicle) {
257b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        super.onCreate(icicle);
258b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
259b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
260b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
261b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mPreferences = PreferenceManager.getDefaultSharedPreferences(this);
262b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mContentResolver = getContentResolver();
263b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
264b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        //setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT);
265b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        requestWindowFeature(Window.FEATURE_PROGRESS);
266b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        setContentView(R.layout.video_camera);
267b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
268b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mVideoPreview = (VideoPreview) findViewById(R.id.camera_preview);
269b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mVideoPreview.setAspectRatio(VIDEO_ASPECT_RATIO);
270b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
271b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // don't set mSurfaceHolder here. We have it set ONLY within
272b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // surfaceCreated / surfaceDestroyed, other parts of the code
273b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // assume that when it is set, the surface is also set.
274b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        SurfaceHolder holder = mVideoPreview.getHolder();
275b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        holder.addCallback(this);
276b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
277b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
278b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mPostPictureAlert = findViewById(R.id.post_picture_panel);
279b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
280b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        int[] ids = new int[]{R.id.play, R.id.share, R.id.discard,
281b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                R.id.cancel, R.id.attach};
282b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        for (int id : ids) {
283b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            findViewById(id).setOnClickListener(this);
284b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
285b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
286b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mShutterButton = (ShutterButton) findViewById(R.id.shutter_button);
287b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mShutterButton.setOnShutterButtonListener(this);
288b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mRecordingTimeView = (TextView) findViewById(R.id.recording_time);
289b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mVideoFrame = (ImageView) findViewById(R.id.video_frame);
2909bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        mIsVideoCaptureIntent = isVideoCaptureIntent();
2919bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (!mIsVideoCaptureIntent) {
2929bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mLastPictureButton = (ImageView) findViewById(R.id.last_picture_button);
2939bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mLastPictureButton.setOnClickListener(this);
2949bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            Drawable frame = getResources().getDrawable(R.drawable.frame_thumbnail);
2959bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mThumbController = new ThumbnailController(mLastPictureButton,
2969bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                    frame, mContentResolver);
2979bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mThumbController.loadData(ImageManager.getLastVideoThumbPath());
2989bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        }
299b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
300b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
301e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project    private void startShareVideoActivity() {
3028d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project        if (mCurrentVideoFileLength > SHARE_FILE_LENGTH_LIMIT) {
303e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project            Toast.makeText(VideoCamera.this,
304e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project                    R.string.too_large_to_attach, Toast.LENGTH_LONG).show();
305e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project            return;
306e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project        }
307e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project        Intent intent = new Intent();
308e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project        intent.setAction(Intent.ACTION_SEND);
309e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project        intent.setType("video/3gpp");
310e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project        intent.putExtra(Intent.EXTRA_STREAM, mCurrentVideoUri);
311e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project        try {
312e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project            startActivity(Intent.createChooser(intent, getText(R.string.sendVideo)));
313e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project        } catch (android.content.ActivityNotFoundException ex) {
314e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project            Toast.makeText(VideoCamera.this, R.string.no_way_to_share_video, Toast.LENGTH_SHORT).show();
315e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project        }
316e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project    }
317e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project
318b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void onClick(View v) {
319b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        switch (v.getId()) {
320b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
321b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case R.id.gallery:
322b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                MenuHelper.gotoCameraVideoGallery(this);
323b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
324b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
325b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case R.id.attach:
326b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                doReturnToCaller(true);
327b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
328b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
329b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case R.id.cancel:
330b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                doReturnToCaller(false);
331b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
332b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
333b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case R.id.discard: {
3347638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen                Runnable deleteCallback = new Runnable() {
3357638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen                    public void run() {
3367638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen                        discardCurrentVideoAndStartPreview();
3377638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen                    }
3387638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen                };
3397638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen                MenuHelper.deleteVideo(this, deleteCallback);
340b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
341b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
342b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
343b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case R.id.share: {
344e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project                startShareVideoActivity();
345b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
346b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
347b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
348b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case R.id.play: {
349b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                doPlayCurrentVideo();
350b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
351b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
352de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
353de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            case R.id.last_picture_button: {
3549bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                stopVideoRecordingAndShowAlert();
355de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                break;
356de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            }
357b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
358b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
359b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
360b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void onShutterButtonFocus(ShutterButton button, boolean pressed) {
361de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        // Do nothing (everything happens in onShutterButtonClick).
362de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project    }
363de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
364de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project    public void onShutterButtonClick(ShutterButton button) {
365b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        switch (button.getId()) {
366b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case R.id.shutter_button:
367de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                if (mMediaRecorderRecording) {
3689bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                    if (mIsVideoCaptureIntent) {
369de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                        stopVideoRecordingAndShowAlert();
370b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    } else {
3719bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                        stopVideoRecordingAndGetThumbnail();
3729bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                        initializeVideo();
3739bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                    }
3749bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                } else if (isAlertVisible()) {
3759bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                    if (mIsVideoCaptureIntent) {
3769bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                        discardCurrentVideoAndStartPreview();
3779bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                    } else {
3789bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                        hideAlertAndStartVideoRecording();
379b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    }
380de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                } else {
381de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                    startVideoRecording();
382b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
383b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
384b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
385b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
386b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
387b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void doPlayCurrentVideo() {
388b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Log.e(TAG, "Playing current video: " + mCurrentVideoUri);
389b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Intent intent = new Intent(Intent.ACTION_VIEW, mCurrentVideoUri);
390b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        try {
391b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            startActivity(intent);
392b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } catch (android.content.ActivityNotFoundException ex) {
393b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Log.e(TAG, "Couldn't view video " + mCurrentVideoUri, ex);
394b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
395b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
396b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
397b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void discardCurrentVideoAndStartPreview() {
398b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        deleteCurrentVideo();
3999bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        hideAlertAndStartPreview();
400b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
401b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
402b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private OnScreenHint mStorageHint;
403b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
4049a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project    private void updateAndShowStorageHint(boolean mayHaveSd) {
4059a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        mStorageStatus = getStorageStatus(mayHaveSd);
4069a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        showStorageHint();
4079a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project    }
4089a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project
4099a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project    private void showStorageHint() {
410b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        String errorMessage = null;
4119a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        switch (mStorageStatus) {
4129a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        case STORAGE_STATUS_NONE:
413b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            errorMessage = getString(R.string.no_storage);
4149a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project            break;
4159a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        case STORAGE_STATUS_LOW:
416b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            errorMessage = getString(R.string.spaceIsLow_content);
417b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
418b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (errorMessage != null) {
419b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (mStorageHint == null) {
420b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mStorageHint = OnScreenHint.makeText(this, errorMessage);
421b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } else {
422b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mStorageHint.setText(errorMessage);
423b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
424b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mStorageHint.show();
425b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } else if (mStorageHint != null) {
426b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mStorageHint.cancel();
427b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mStorageHint = null;
428b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
429b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
430b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
4319a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project    private int getStorageStatus(boolean mayHaveSd) {
4329a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        long remaining = mayHaveSd ? getAvailableStorage() : NO_STORAGE_ERROR;
4339a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        if (remaining == NO_STORAGE_ERROR) {
4349a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project            return STORAGE_STATUS_NONE;
4359a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        }
4369a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        return remaining < LOW_STORAGE_THRESHOLD
4379a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project                ? STORAGE_STATUS_LOW : STORAGE_STATUS_OK;
4389a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project    }
4399a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project
440b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
441b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void onResume() {
442b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        super.onResume();
443b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
444b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        setScreenTimeoutLong();
445b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
446b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mPausing = false;
447b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
448b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // install an intent filter to receive SD card related events.
449b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED);
450b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        intentFilter.addAction(Intent.ACTION_MEDIA_EJECT);
451b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
452b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED);
453b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
454b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        intentFilter.addDataScheme("file");
455b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        registerReceiver(mReceiver, intentFilter);
4569a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        mStorageStatus = getStorageStatus(true);
4579a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project
4589a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        mHandler.postDelayed(new Runnable() {
4599a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project            public void run() {
4609a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project                showStorageHint();
4619a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project            }
4629a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        }, 200);
463b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
4649bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        initializeVideo();
465b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
466b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
467b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
468b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void onStop() {
469b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        setScreenTimeoutSystemDefault();
470b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        super.onStop();
471b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
472b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
473b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
474b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    protected void onPause() {
475b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        super.onPause();
476b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
4779bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        // This is similar to what mShutterButton.performClick() does,
4789bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        // but not quite the same.
4799bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (mMediaRecorderRecording) {
4809bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            if (mIsVideoCaptureIntent) {
4819bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                stopVideoRecordingAndShowAlert();
4829bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            } else {
4839bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                stopVideoRecordingAndGetThumbnail();
4849bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            }
4859bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        } else {
4869bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            stopVideoRecording();
4879bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        }
488b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
489b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mPausing = true;
490b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
4919c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project        unregisterReceiver(mReceiver);
492b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        setScreenTimeoutSystemDefault();
493b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
4949bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (!mIsVideoCaptureIntent) {
4959bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mThumbController.storeData(ImageManager.getLastVideoThumbPath());
4969bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        }
497095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin
498b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mStorageHint != null) {
499b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mStorageHint.cancel();
500b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mStorageHint = null;
501b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
502b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
503b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
504b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
505b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public boolean onKeyDown(int keyCode, KeyEvent event) {
506b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        setScreenTimeoutLong();
507b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
508b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        switch (keyCode) {
509b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case KeyEvent.KEYCODE_BACK:
510b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                if (mMediaRecorderRecording) {
511de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                    mShutterButton.performClick();
512b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    return true;
5139bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                } else if(isAlertVisible()) {
5149bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                    hideAlertAndStartPreview();
515b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    return true;
516b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
517b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
518b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case KeyEvent.KEYCODE_CAMERA:
519b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                if (event.getRepeatCount() == 0) {
520de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                    mShutterButton.performClick();
521b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    return true;
522b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
523de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                break;
524b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case KeyEvent.KEYCODE_DPAD_CENTER:
525b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                if (event.getRepeatCount() == 0) {
526de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                    mShutterButton.performClick();
527de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                    return true;
528b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
529b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
530b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case KeyEvent.KEYCODE_MENU:
531b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                if (mMediaRecorderRecording) {
532de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                    mShutterButton.performClick();
533b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    return true;
534b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
535b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
536b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
537b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
538b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return super.onKeyDown(keyCode, event);
539b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
540b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
541b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
542b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public boolean onKeyUp(int keyCode, KeyEvent event) {
543b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        switch(keyCode) {
544b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        case KeyEvent.KEYCODE_CAMERA:
545b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mShutterButton.setPressed(false);
546b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            return true;
547b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
548b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return super.onKeyUp(keyCode, event);
549b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
550b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
551b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
552314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber        if (mPausing) {
553314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber            // We're pausing, the screen is off and we already stopped
554314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber            // video recording. We don't want to start the camera again
555314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber            // in this case in order to conserve power.
556314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber            // The fact that surfaceChanged is called _after_ an onPause appears
557314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber            // to be legitimate since in that case the lockscreen always returns
558314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber            // to portrait orientation possibly triggering the notification.
559314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber            return;
560314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber        }
561314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber
562b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        stopVideoRecording();
563b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        initializeVideo();
564b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
565b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
566b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void surfaceCreated(SurfaceHolder holder) {
567b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mSurfaceHolder = holder;
568b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
569b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
570b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void surfaceDestroyed(SurfaceHolder holder) {
571b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mSurfaceHolder = null;
572b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
573b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
574b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    void gotoGallery() {
575b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        MenuHelper.gotoCameraVideoGallery(this);
576b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
577b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
578b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
579b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public boolean onPrepareOptionsMenu(Menu menu) {
580b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        super.onPrepareOptionsMenu(menu);
581b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
582b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        for (int i = 1; i <= MenuHelper.MENU_ITEM_MAX; i++) {
583b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (i != MenuHelper.GENERIC_ITEM) {
584b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                menu.setGroupVisible(i, false);
585b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
586b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
587b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
588b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        menu.setGroupVisible(MenuHelper.VIDEO_MODE_ITEM, true);
589b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return true;
590b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
591b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
592b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
593b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public boolean onCreateOptionsMenu(Menu menu) {
594b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        super.onCreateOptionsMenu(menu);
595b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
5969bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (mIsVideoCaptureIntent) {
597b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // No options menu for attach mode.
598b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            return false;
599b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } else {
600b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            addBaseMenuItems(menu);
601095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin            int menuFlags = MenuHelper.INCLUDE_ALL & ~MenuHelper.INCLUDE_ROTATE_MENU
602095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin                    & ~MenuHelper.INCLUDE_DETAILS_MENU;
603b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            MenuHelper.addImageMenuItems(
604b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    menu,
605095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin                    menuFlags,
606b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    false,
607b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    VideoCamera.this,
608b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    mHandler,
609b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
610b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    // Handler for deletion
611b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    new Runnable() {
612b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        public void run() {
613b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            // What do we do here?
614b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            // mContentResolver.delete(uri, null, null);
615b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        }
616b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    },
617b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    new MenuHelper.MenuInvoker() {
618b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        public void run(final MenuHelper.MenuCallback cb) {
619b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        }
620b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    });
621b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
622b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            MenuItem gallery = menu.add(MenuHelper.IMAGE_SAVING_ITEM, MENU_SAVE_GALLERY_PHOTO, 0,
623b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    R.string.camera_gallery_photos_text).setOnMenuItemClickListener(
624b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            new MenuItem.OnMenuItemClickListener() {
625b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                public boolean onMenuItemClick(MenuItem item) {
626b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    gotoGallery();
627b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    return true;
628b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
629b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            });
630b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            gallery.setIcon(android.R.drawable.ic_menu_gallery);
631b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
632b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return true;
633b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
634b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
635b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private boolean isVideoCaptureIntent() {
636b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        String action = getIntent().getAction();
637b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return (MediaStore.ACTION_VIDEO_CAPTURE.equals(action));
638b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
639b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
640b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void doReturnToCaller(boolean success) {
641b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Intent resultIntent = new Intent();
642b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        int resultCode;
643b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (success) {
644b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            resultCode = RESULT_OK;
645b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            resultIntent.setData(mCurrentVideoUri);
646b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } else {
647b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            resultCode = RESULT_CANCELED;
648b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
649b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        setResult(resultCode, resultIntent);
650b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        finish();
651b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
652b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
653b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    /**
654b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project     * Returns
655b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project     * @return number of bytes available, or an ERROR code.
656b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project     */
657b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static long getAvailableStorage() {
658b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        try {
659b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (!ImageManager.hasStorage()) {
660b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                return NO_STORAGE_ERROR;
661b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } else {
662b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                String storageDirectory = Environment.getExternalStorageDirectory().toString();
663b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                StatFs stat = new StatFs(storageDirectory);
664b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                return ((long)stat.getAvailableBlocks() * (long)stat.getBlockSize());
665b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
666b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } catch (Exception ex) {
667b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // if we can't stat the filesystem then we don't know how many
668b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // free bytes exist.  It might be zero but just leave it
669b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // blank since we really don't know.
670b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            return CANNOT_STAT_ERROR;
671b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
672b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
673b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
674b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void cleanupEmptyFile() {
675b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mCameraVideoFilename != null) {
676b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            File f = new File(mCameraVideoFilename);
677b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (f.length() == 0 && f.delete()) {
678b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project              Log.v(TAG, "Empty video file deleted: " + mCameraVideoFilename);
679b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project              mCameraVideoFilename = null;
680b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
681b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
682b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
683b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
6849bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    // initializeVideo() starts preview and prepare media recorder.
685b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    // Returns false if initializeVideo fails
686b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private boolean initializeVideo() {
687b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Log.v(TAG, "initializeVideo");
6889bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang
6899bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        // We will call initializeVideo() again when the alert is hidden.
6909bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (isAlertVisible()) return false;
6919bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang
692b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Intent intent = getIntent();
693b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Bundle myExtras = intent.getExtras();
694b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
6959bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (mIsVideoCaptureIntent && myExtras != null) {
696b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Uri saveUri = (Uri) myExtras.getParcelable(MediaStore.EXTRA_OUTPUT);
697b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (saveUri != null) {
698b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                try {
699b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    mCameraVideoFileDescriptor = mContentResolver.
700b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        openFileDescriptor(saveUri, "rw").getFileDescriptor();
701b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    mCurrentVideoUri = saveUri;
702b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
703b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                catch (java.io.FileNotFoundException ex) {
704b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    // invalid uri
705b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    Log.e(TAG, ex.toString());
706b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
707b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
708b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
709b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        releaseMediaRecorder();
710b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
711b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mSurfaceHolder == null) {
712b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Log.v(TAG, "SurfaceHolder is null");
713b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            return false;
714b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
715b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
716b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mMediaRecorder = new MediaRecorder();
717b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
718b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (DEBUG_SUPPRESS_AUDIO_RECORDING) {
719b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Log.v(TAG, "DEBUG_SUPPRESS_AUDIO_RECORDING is true.");
720b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } else {
721b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
722b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
723b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
724b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
725b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
7268d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project        mMediaRecorder.setMaxDuration(MAX_RECORDING_DURATION_MS);
7278d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project
7289a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        if (mStorageStatus != STORAGE_STATUS_OK) {
729b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mMediaRecorder.setOutputFile("/dev/null");
730b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } else {
731b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // We try Uri in intent first. If it doesn't work, use our own instead.
732b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (mCameraVideoFileDescriptor != null) {
733b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mMediaRecorder.setOutputFile(mCameraVideoFileDescriptor);
734b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } else {
735b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                createVideoPath();
736b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mMediaRecorder.setOutputFile(mCameraVideoFilename);
737b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
738b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
739b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
740b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        boolean videoQualityHigh = getBooleanPreference(CameraSettings.KEY_VIDEO_QUALITY,
741b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                CameraSettings.DEFAULT_VIDEO_QUALITY_VALUE);
742b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
743b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (intent.hasExtra(MediaStore.EXTRA_VIDEO_QUALITY)) {
744b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            int extraVideoQuality = intent.getIntExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0);
745b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            videoQualityHigh = (extraVideoQuality > 0);
746b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
747b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
748b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // Use the same frame rate for both, since internally
749b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // if the frame rate is too large, it can cause camera to become
750b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // unstable. We need to fix the MediaRecorder to disable the support
751b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // of setting frame rate for now.
752b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mMediaRecorder.setVideoFrameRate(20);
753b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (videoQualityHigh) {
754b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mMediaRecorder.setVideoSize(352,288);
755b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } else {
756b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mMediaRecorder.setVideoSize(176,144);
757b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
758b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
759b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (!DEBUG_SUPPRESS_AUDIO_RECORDING) {
760b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
761b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
762b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
763de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
764de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        long remaining = getAvailableStorage();
765de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        // remaining >= LOW_STORAGE_THRESHOLD at this point, reserve a quarter
766de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        // of that to make it more likely that recording can complete successfully.
767de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        try {
768de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            mMediaRecorder.setMaxFileSize(remaining - LOW_STORAGE_THRESHOLD / 4);
769de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        } catch (RuntimeException exception) {
770de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            // We are going to ignore failure of setMaxFileSize here, as
771de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            // a) The composer selected may simply not support it, or
772de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            // b) The underlying media framework may not handle 64-bit range
773de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            //    on the size restriction.
774de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        }
775de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
776b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        try {
777b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mMediaRecorder.prepare();
778b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } catch (IOException exception) {
779b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Log.e(TAG, "prepare failed for " + mCameraVideoFilename);
780b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            releaseMediaRecorder();
781b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // TODO: add more exception handling logic here
782b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            return false;
783b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
784b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mMediaRecorderRecording = false;
7859bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang
7869bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (!mIsVideoCaptureIntent && !mThumbController.isUriValid()) {
7879bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            updateLastVideo();
7889bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        }
7899bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang
7909bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (!mIsVideoCaptureIntent) {
7919bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mThumbController.updateDisplayIfNeeded();
7929bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        }
7939bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang
794b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return true;
795b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
796b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
797b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void releaseMediaRecorder() {
798b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Log.v(TAG, "Releasing media recorder.");
799b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mMediaRecorder != null) {
800b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            cleanupEmptyFile();
801b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mMediaRecorder.reset();
802b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mMediaRecorder.release();
803b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mMediaRecorder = null;
804b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
805b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
806b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
807b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private int getIntPreference(String key, int defaultValue) {
808b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        String s = mPreferences.getString(key, "");
809b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        int result = defaultValue;
810b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        try {
811b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            result = Integer.parseInt(s);
812b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } catch (NumberFormatException e) {
813b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // Ignore, result is already the default value.
814b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
815b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return result;
816b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
817b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
818b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private boolean getBooleanPreference(String key, boolean defaultValue) {
819b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return getIntPreference(key, defaultValue ? 1 : 0) != 0;
820b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
821b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
822b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void createVideoPath() {
823b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        long dateTaken = System.currentTimeMillis();
824b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        String title = createName(dateTaken);
825b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        String displayName = title + ".3gp"; // Used when emailing.
826b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        String cameraDirPath = ImageManager.CAMERA_IMAGE_BUCKET_NAME;
827b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        File cameraDir = new File(cameraDirPath);
828b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        cameraDir.mkdirs();
829b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        SimpleDateFormat dateFormat = new SimpleDateFormat(
830b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                getString(R.string.video_file_name_format));
831b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Date date = new Date(dateTaken);
832b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        String filepart = dateFormat.format(date);
833b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        String filename = cameraDirPath + "/" + filepart + ".3gp";
834b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        ContentValues values = new ContentValues(7);
835b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        values.put(Video.Media.TITLE, title);
836b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        values.put(Video.Media.DISPLAY_NAME, displayName);
837b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        values.put(Video.Media.DESCRIPTION, "");
838b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        values.put(Video.Media.DATE_TAKEN, dateTaken);
839b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        values.put(Video.Media.MIME_TYPE, "video/3gpp");
840b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        values.put(Video.Media.DATA, filename);
841b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mCameraVideoFilename = filename;
842b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Log.v(TAG, "Current camera video filename: " + mCameraVideoFilename);
843b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mCurrentVideoValues = values;
844b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
845b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
846b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void registerVideo() {
847b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mCameraVideoFileDescriptor == null) {
848b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Uri videoTable = Uri.parse("content://media/external/video/media");
849b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mCurrentVideoUri = mContentResolver.insert(videoTable,
850b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    mCurrentVideoValues);
851b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Log.v(TAG, "Current video URI: " + mCurrentVideoUri);
852b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
853b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mCurrentVideoValues = null;
854b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
855b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
856b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void deleteCurrentVideo() {
857b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mCurrentVideoFilename != null) {
858b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            deleteVideoFile(mCurrentVideoFilename);
859b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mCurrentVideoFilename = null;
860b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
861b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mCurrentVideoUri != null) {
862b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mContentResolver.delete(mCurrentVideoUri, null, null);
863b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mCurrentVideoUri = null;
864b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
865de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        updateAndShowStorageHint(true);
866b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
867b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
868b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void deleteVideoFile(String fileName) {
869b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Log.v(TAG, "Deleting video " + fileName);
870b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        File f = new File(fileName);
871b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (! f.delete()) {
872b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Log.v(TAG, "Could not delete " + fileName);
873b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
874b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
875b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
876b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void addBaseMenuItems(Menu menu) {
877b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        MenuHelper.addSwitchModeMenuItem(menu, this, false);
878b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        {
879b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            MenuItem gallery = menu.add(MenuHelper.IMAGE_MODE_ITEM, MENU_GALLERY_PHOTOS, 0, R.string.camera_gallery_photos_text).setOnMenuItemClickListener(new OnMenuItemClickListener() {
880b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                public boolean onMenuItemClick(MenuItem item) {
881b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    gotoGallery();
882b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    return true;
883b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
884b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            });
885b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            gallery.setIcon(android.R.drawable.ic_menu_gallery);
886b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mGalleryItems.add(gallery);
887b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
888b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        {
889b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            MenuItem gallery = menu.add(MenuHelper.VIDEO_MODE_ITEM, MENU_GALLERY_VIDEOS, 0, R.string.camera_gallery_photos_text).setOnMenuItemClickListener(new OnMenuItemClickListener() {
890b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                public boolean onMenuItemClick(MenuItem item) {
891b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    gotoGallery();
892b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    return true;
893b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
894b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            });
895b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            gallery.setIcon(android.R.drawable.ic_menu_gallery);
896b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mGalleryItems.add(gallery);
897b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
898b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
899b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        MenuItem item = menu.add(MenuHelper.GENERIC_ITEM, MENU_SETTINGS, 0, R.string.settings).setOnMenuItemClickListener(new OnMenuItemClickListener() {
900b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            public boolean onMenuItemClick(MenuItem item) {
901b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                Intent intent = new Intent();
902b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                intent.setClass(VideoCamera.this, CameraSettings.class);
903b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                startActivity(intent);
904b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                return true;
905b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
906b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        });
907b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        item.setIcon(android.R.drawable.ic_menu_preferences);
908b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
909b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
910b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    // from MediaRecorder.OnErrorListener
911b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void onError(MediaRecorder mr, int what, int extra) {
912b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (what == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) {
913b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // We may have run out of space on the sdcard.
914b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            stopVideoRecording();
9159a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project            updateAndShowStorageHint(true);
916b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
917b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
918b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
9198d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project    // from MediaRecorder.OnInfoListener
9208d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project    public void onInfo(MediaRecorder mr, int what, int extra) {
9218d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project        if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
922de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            mShutterButton.performClick();
923de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        } else if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED) {
924de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            mShutterButton.performClick();
925de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            updateAndShowStorageHint(true);
9268d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project        }
9278d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project    }
9288d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project
9299c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project    /*
9309c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project     * Make sure we're not recording music playing in the background, ask
9319c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project     * the MediaPlaybackService to pause playback.
9329c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project     */
9339c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project    private void pauseAudioPlayback() {
9349c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project        // Shamelessly copied from MediaPlaybackService.java, which
9359c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project        // should be public, but isn't.
9369c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project        Intent i = new Intent("com.android.music.musicservicecommand");
9379c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project        i.putExtra("command", "pause");
9389c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project
9399c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project        sendBroadcast(i);
9409c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project    }
9419c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project
942b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void startVideoRecording() {
943b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Log.v(TAG, "startVideoRecording");
944b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (!mMediaRecorderRecording) {
945b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
9469a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project            if (mStorageStatus != STORAGE_STATUS_OK) {
947b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                Log.v(TAG, "Storage issue, ignore the start request");
948b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                return;
949b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
950b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
951b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // Check mMediaRecorder to see whether it is initialized or not.
952b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (mMediaRecorder == null && initializeVideo() == false ) {
953b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                Log.e(TAG, "Initialize video (MediaRecorder) failed.");
954b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                return;
955b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
956b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
9579c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project            pauseAudioPlayback();
9589c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project
959b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            try {
960b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mMediaRecorder.setOnErrorListener(this);
9618d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                mMediaRecorder.setOnInfoListener(this);
962b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mMediaRecorder.start();   // Recording is now started
963b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } catch (RuntimeException e) {
964b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                Log.e(TAG, "Could not start media recorder. ", e);
965b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                return;
966b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
967b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mMediaRecorderRecording = true;
968b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mRecordingStartTime = SystemClock.uptimeMillis();
969b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            updateRecordingIndicator(true);
970b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mRecordingTimeView.setText("");
971b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mRecordingTimeView.setVisibility(View.VISIBLE);
972b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mHandler.sendEmptyMessage(UPDATE_RECORD_TIME);
973b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            setScreenTimeoutInfinite();
974de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            hideLastPictureButton();
975b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
976b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
977b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
978b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void updateRecordingIndicator(boolean showRecording) {
979b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        int drawableId = showRecording ? R.drawable.ic_camera_bar_indicator_record
980b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            : R.drawable.ic_camera_indicator_video;
981b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Drawable drawable = getResources().getDrawable(drawableId);
982b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mShutterButton.setImageDrawable(drawable);
983b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
984b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
9859bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private void stopVideoRecordingAndGetThumbnail() {
9869bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        stopVideoRecording();
9879bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        acquireVideoThumb();
988b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
989b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
990de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project    private void stopVideoRecordingAndShowAlert() {
991de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        stopVideoRecording();
9929bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        showAlert();
993de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project    }
994de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
9959bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private void showAlert() {
996b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        int[] pickIds = {R.id.attach, R.id.cancel};
997b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        int[] normalIds = {R.id.gallery, R.id.share, R.id.discard};
998b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        int[] alwaysOnIds = {R.id.play};
999b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        int[] hideIds = pickIds;
1000b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        int[] connectIds = normalIds;
10019bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (mIsVideoCaptureIntent) {
1002b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            hideIds = normalIds;
1003b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            connectIds = pickIds;
1004b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1005b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        for(int id : hideIds) {
1006b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mPostPictureAlert.findViewById(id).setVisibility(View.GONE);
1007b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
10088d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project        ActionMenuButton shareButton =
10098d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                (ActionMenuButton) mPostPictureAlert.findViewById(R.id.share);
10108d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project        shareButton.setRestricted(
10118d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                mCurrentVideoFileLength > SHARE_FILE_LENGTH_LIMIT);
1012b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        connectAndFadeIn(connectIds);
1013b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        connectAndFadeIn(alwaysOnIds);
1014de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        hideLastPictureButton();
1015b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mPostPictureAlert.setVisibility(View.VISIBLE);
10169bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang
10179bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        // There are two cases we are here:
10189bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        // (1) We are in a capture video intent, and we are reviewing the video
1019095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin        //     we just taken.
10209bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        // (2) The thumbnail button is clicked: we review the video associated
10219bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        //     with the thumbnail.
10229bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        // For the second case, we copy the associated URI and filename to
10239bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        // mCurrentVideoUri and mCurrentVideoFilename, so the video frame shown
10249bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        // and the target for actions (play, delete, ...) will be correct.
10259bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang
10269bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (!mIsVideoCaptureIntent) {
10279bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mCurrentVideoUri = mThumbController.getUri();
10289bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mCurrentVideoFilename = getDataPath(mCurrentVideoUri);
10299bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        }
10309bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang
10319bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        String path = mCurrentVideoFilename;
10329bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (path != null) {
1033101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin            Bitmap videoFrame = Util.createVideoThumbnail(path);
10349bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mVideoFrame.setImageBitmap(videoFrame);
10359bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mVideoFrame.setVisibility(View.VISIBLE);
10369bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        }
1037b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1038b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
10399bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private void hideAlert() {
1040de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        mVideoFrame.setVisibility(View.INVISIBLE);
1041de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        mPostPictureAlert.setVisibility(View.INVISIBLE);
1042de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        showLastPictureButton();
1043de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project    }
1044de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
1045b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void connectAndFadeIn(int[] connectIds) {
1046b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        for(int id : connectIds) {
1047b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            View view = mPostPictureAlert.findViewById(id);
1048b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            view.setOnClickListener(this);
1049b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Animation animation = new AlphaAnimation(0F, 1F);
1050b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            animation.setDuration(500);
10519bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            view.startAnimation(animation);
1052b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1053b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1054b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
10559bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private boolean isAlertVisible() {
1056b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return mPostPictureAlert.getVisibility() == View.VISIBLE;
1057b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1058b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1059b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void stopVideoRecording() {
1060b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Log.v(TAG, "stopVideoRecording");
1061b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        boolean needToRegisterRecording = false;
1062b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mMediaRecorderRecording || mMediaRecorder != null) {
1063b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (mMediaRecorderRecording && mMediaRecorder != null) {
1064b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                try {
1065b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    mMediaRecorder.setOnErrorListener(null);
10668d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                    mMediaRecorder.setOnInfoListener(null);
1067b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    mMediaRecorder.stop();
1068b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                } catch (RuntimeException e) {
1069b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    Log.e(TAG, "stop fail: " + e.getMessage());
1070b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
10718d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project
1072b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mCurrentVideoFilename = mCameraVideoFilename;
10738d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                try {
10748d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                    mCurrentVideoFileLength = new File(mCurrentVideoFilename).length();
10758d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                } catch (RuntimeException e) {
10768d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                    Log.e(TAG, "get file length fail: " + e.getMessage());
10778d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                    mCurrentVideoFileLength = 0;
10788d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                }
1079b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                Log.v(TAG, "Setting current video filename: " + mCurrentVideoFilename);
1080b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                needToRegisterRecording = true;
1081b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mMediaRecorderRecording = false;
1082b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
1083b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            releaseMediaRecorder();
1084b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            updateRecordingIndicator(false);
1085b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mRecordingTimeView.setVisibility(View.GONE);
1086b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            setScreenTimeoutLong();
1087b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
10889a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        if (needToRegisterRecording && mStorageStatus == STORAGE_STATUS_OK) {
10899a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project            registerVideo();
10909a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        }
1091b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1092b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mCameraVideoFilename = null;
1093b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mCameraVideoFileDescriptor = null;
1094b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1095b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1096b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void setScreenTimeoutSystemDefault() {
1097b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mHandler.removeMessages(CLEAR_SCREEN_DELAY);
1098b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        clearScreenOnFlag();
1099b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1100b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1101b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void setScreenTimeoutLong() {
1102b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mHandler.removeMessages(CLEAR_SCREEN_DELAY);
1103b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        setScreenOnFlag();
1104b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mHandler.sendEmptyMessageDelayed(CLEAR_SCREEN_DELAY, SCREEN_DELAY);
1105b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1106b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1107b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void setScreenTimeoutInfinite() {
1108b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mHandler.removeMessages(CLEAR_SCREEN_DELAY);
1109b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        setScreenOnFlag();
1110b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1111b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1112b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void clearScreenOnFlag() {
1113b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Window w = getWindow();
1114b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        final int keepScreenOnFlag = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
1115b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if ((w.getAttributes().flags & keepScreenOnFlag) != 0) {
1116b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            w.clearFlags(keepScreenOnFlag);
1117b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1118b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1119b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1120b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void setScreenOnFlag() {
1121b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Window w = getWindow();
1122b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        final int keepScreenOnFlag = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
1123b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if ((w.getAttributes().flags & keepScreenOnFlag) == 0) {
1124b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            w.addFlags(keepScreenOnFlag);
1125b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1126b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1127b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
11289bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private void hideAlertAndStartPreview() {
11299bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        hideAlert();
11309bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        initializeVideo();
1131b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1132b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
11339bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private void hideAlertAndStartVideoRecording() {
11349bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        hideAlert();
11359bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        startVideoRecording();
1136b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1137b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
11389bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private void acquireVideoThumb() {
1139101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin        Bitmap videoFrame = Util.createVideoThumbnail(mCurrentVideoFilename);
11409bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        mThumbController.setData(mCurrentVideoUri, videoFrame);
1141de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project    }
1142de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
11439bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private void showLastPictureButton() {
11449bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (!mIsVideoCaptureIntent) {
11459bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mLastPictureButton.setVisibility(View.VISIBLE);
1146de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        }
11479bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    }
1148de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
11499bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private void hideLastPictureButton() {
11509bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (!mIsVideoCaptureIntent) {
11519bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mLastPictureButton.setVisibility(View.INVISIBLE);
11529bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        }
1153de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project    }
1154de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
11559bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private static ImageManager.DataLocation dataLocation() {
11569bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        return ImageManager.DataLocation.EXTERNAL;
1157de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project    }
1158de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
11599bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private void updateLastVideo() {
1160101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin        IImageList list = ImageManager.instance().allImages(
11619bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            this,
11629bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mContentResolver,
11639bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            dataLocation(),
11649bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            ImageManager.INCLUDE_VIDEOS,
11659bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            ImageManager.SORT_ASCENDING,
11669bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            ImageManager.CAMERA_IMAGE_BUCKET_ID);
11679bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        int count = list.getCount();
11689bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (count > 0) {
1169101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin            IImage image = list.getImageAt(count-1);
11709bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            Uri uri = image.fullSizeImageUri();
11719bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mThumbController.setData(uri, image.miniThumbBitmap());
11729bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        } else {
11739bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mThumbController.setData(null, null);
11749bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        }
11759bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        list.deactivate();
1176b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1177b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
11789bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private static final String[] DATA_PATH_PROJECTION = new String[] {
11799bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        "_data"
11809bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    };
11819bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang
11829bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private String getDataPath(Uri uri) {
11839bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        Cursor c = null;
11849bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        try {
11859bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            c = mContentResolver.query(uri, DATA_PATH_PROJECTION, null, null, null);
11869bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            if (c != null && c.moveToFirst()) {
11879bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                return c.getString(0);
11889bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            } else {
11899bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                return null;
11909bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            }
11919bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        } finally {
11929bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            if (c != null) c.close();
1193b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1194b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1195b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project}
1196