VideoCamera.java revision 095afa19556bf550262e3cccb9edacc04e6f726a
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
19b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.io.File;
20b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.io.FileDescriptor;
21b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.io.IOException;
22b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.text.SimpleDateFormat;
23b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.util.ArrayList;
24b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.util.Date;
25b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
26b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.app.Activity;
27b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.BroadcastReceiver;
28b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.ContentResolver;
29b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.ContentValues;
30b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.Context;
31b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.Intent;
32b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.IntentFilter;
33b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.SharedPreferences;
34095afa19556bf550262e3cccb9edacc04e6f726aOwen Linimport android.database.Cursor;
35b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.graphics.Bitmap;
36b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.graphics.drawable.Drawable;
37b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.location.LocationManager;
38b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.media.MediaRecorder;
39b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.net.Uri;
40b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Bundle;
41b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Environment;
42b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Handler;
43b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Message;
44b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.StatFs;
45b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.SystemClock;
46b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.preference.PreferenceManager;
47b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.provider.MediaStore;
48b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.provider.MediaStore.Video;
49b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.text.format.DateFormat;
50b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.util.Log;
51b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.KeyEvent;
52b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.Menu;
53b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.MenuItem;
54b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.SurfaceHolder;
55b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.View;
56b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.Window;
57b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.WindowManager;
58b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.MenuItem.OnMenuItemClickListener;
59b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.animation.AlphaAnimation;
60b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.animation.Animation;
61b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.widget.ImageView;
62b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.widget.TextView;
63b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.widget.Toast;
64b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
65b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectpublic class VideoCamera extends Activity implements View.OnClickListener,
668d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project    ShutterButton.OnShutterButtonListener, SurfaceHolder.Callback, MediaRecorder.OnErrorListener, MediaRecorder.OnInfoListener {
67b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
68b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final String TAG = "videocamera";
69b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
70b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final boolean DEBUG = true;
71b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final boolean DEBUG_SUPPRESS_AUDIO_RECORDING = DEBUG && false;
72b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
73b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final int CLEAR_SCREEN_DELAY = 4;
74b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final int UPDATE_RECORD_TIME = 5;
75b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
76b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final int SCREEN_DELAY = 2 * 60 * 1000;
77b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
78b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final long NO_STORAGE_ERROR = -1L;
79b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final long CANNOT_STAT_ERROR = -2L;
80b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final long LOW_STORAGE_THRESHOLD = 512L * 1024L;
81e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project    private static final long SHARE_FILE_LENGTH_LIMIT = 3L * 1024L * 1024L;
82b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
839a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project    private static final int STORAGE_STATUS_OK = 0;
849a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project    private static final int STORAGE_STATUS_LOW = 1;
859a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project    private static final int STORAGE_STATUS_NONE = 2;
869a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project
87b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_SETTINGS = 6;
88b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_GALLERY_PHOTOS = 7;
89b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_GALLERY_VIDEOS = 8;
90b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_SAVE_GALLERY_PHOTO = 34;
91b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_SAVE_PLAY_VIDEO = 35;
92b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_SAVE_SELECT_VIDEO = 36;
93b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_SAVE_NEW_VIDEO = 37;
94b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
95b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    SharedPreferences mPreferences;
96b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
97b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final float VIDEO_ASPECT_RATIO = 176.0f / 144.0f;
98b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    VideoPreview mVideoPreview;
99b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    SurfaceHolder mSurfaceHolder = null;
100b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    ImageView mVideoFrame;
1019bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang
1029bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private boolean mIsVideoCaptureIntent;
1039bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    // mLastPictureButton and mThumbController
1049bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    // are non-null only if isVideoCaptureIntent() is true;
105de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project    private ImageView mLastPictureButton;
1069bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private ThumbnailController mThumbController;
107b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1088d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project    private static final int MAX_RECORDING_DURATION_MS = 10 * 60 * 1000;
1098d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project
1109a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project    private int mStorageStatus = STORAGE_STATUS_OK;
1119a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project
112b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private MediaRecorder mMediaRecorder;
113b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private boolean mMediaRecorderRecording = false;
114b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private long mRecordingStartTime;
115b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    // The video file that the hardware camera is about to record into
116b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    // (or is recording into.)
117b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private String mCameraVideoFilename;
118b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private FileDescriptor mCameraVideoFileDescriptor;
119b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
120b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    // The video file that has already been recorded, and that is being
121b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    // examined by the user.
122b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private String mCurrentVideoFilename;
1238d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project    private long mCurrentVideoFileLength = 0L;
124b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private Uri mCurrentVideoUri;
125b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private ContentValues mCurrentVideoValues;
126b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
127b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    boolean mPausing = false;
128b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
129b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    static ContentResolver mContentResolver;
130b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
131b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    int mCurrentZoomIndex = 0;
132b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
133b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private ShutterButton mShutterButton;
134b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private TextView mRecordingTimeView;
1358d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project    private boolean mRecordingTimeCountsDown = false;
136b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
137b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    ArrayList<MenuItem> mGalleryItems = new ArrayList<MenuItem>();
138b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
139b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    View mPostPictureAlert;
140b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    LocationManager mLocationManager = null;
141b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
142b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private Handler mHandler = new MainHandler();
143b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
144b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    /** This Handler is used to post message back onto the main thread of the application */
145b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private class MainHandler extends Handler {
146b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        @Override
147b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        public void handleMessage(Message msg) {
148b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            switch (msg.what) {
149b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
150b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                case CLEAR_SCREEN_DELAY: {
151b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    clearScreenOnFlag();
152b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    break;
153b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
154b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
155b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                case UPDATE_RECORD_TIME: {
156b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    if (mMediaRecorderRecording) {
157b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        long now = SystemClock.uptimeMillis();
158b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        long delta = now - mRecordingStartTime;
1598d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project
1608d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                        // Starting a minute before reaching the max duration
1618d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                        // limit, we'll countdown the remaining time instead.
1628d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                        boolean countdown_remaining_time =
1638d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                            (delta >= MAX_RECORDING_DURATION_MS - 60000);
1648d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project
1658d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                        if (countdown_remaining_time) {
1668d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                            delta = Math.max(0, MAX_RECORDING_DURATION_MS - delta);
1678d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                        }
1688d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project
1698d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                        long seconds = (delta + 500) / 1000;  // round to nearest
170b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        long minutes = seconds / 60;
171b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        long hours = minutes / 60;
172b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        long remainderMinutes = minutes - (hours * 60);
173b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        long remainderSeconds = seconds - (minutes * 60);
174b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
175b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        String secondsString = Long.toString(remainderSeconds);
176b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        if (secondsString.length() < 2) {
177b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            secondsString = "0" + secondsString;
178b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        }
179b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        String minutesString = Long.toString(remainderMinutes);
180b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        if (minutesString.length() < 2) {
181b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            minutesString = "0" + minutesString;
182b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        }
183b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        String text = minutesString + ":" + secondsString;
184b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        if (hours > 0) {
185b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            String hoursString = Long.toString(hours);
186b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            if (hoursString.length() < 2) {
187b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                                hoursString = "0" + hoursString;
188b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            }
189b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            text = hoursString + ":" + text;
190b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        }
191b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        mRecordingTimeView.setText(text);
1928d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project
1938d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                        if (mRecordingTimeCountsDown != countdown_remaining_time) {
1948d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                            // Avoid setting the color on every update, do it only
1958d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                            // when it needs changing.
1968d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project
1978d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                            mRecordingTimeCountsDown = countdown_remaining_time;
1988d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project
1998d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                            int color = getResources().getColor(
2008d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                                    countdown_remaining_time ? R.color.recording_time_remaining_text
2018d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                                                             : R.color.recording_time_elapsed_text);
2028d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project
2038d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                            mRecordingTimeView.setTextColor(color);
2048d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                        }
2058d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project
206b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        // Work around a limitation of the T-Mobile G1: The T-Mobile
207b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        // hardware blitter can't pixel-accurately scale and clip at the same time,
208b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        // and the SurfaceFlinger doesn't attempt to work around this limitation.
209b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        // In order to avoid visual corruption we must manually refresh the entire
210b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        // surface view when changing any overlapping view's contents.
211b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        mVideoPreview.invalidate();
212b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        mHandler.sendEmptyMessageDelayed(UPDATE_RECORD_TIME, 1000);
213b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    }
214b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    break;
215b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
216b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
217b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                default:
218b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    Log.v(TAG, "Unhandled message: " + msg.what);
219b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                  break;
220b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
221b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
222b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    };
223b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
224b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
225b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        @Override
226b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        public void onReceive(Context context, Intent intent) {
227b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            String action = intent.getAction();
228b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (action.equals(Intent.ACTION_MEDIA_EJECT)) {
2299a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project                updateAndShowStorageHint(false);
230b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                stopVideoRecording();
231b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                initializeVideo();
232b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } else if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) {
2339a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project                updateAndShowStorageHint(true);
234b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                initializeVideo();
235b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } else if (action.equals(Intent.ACTION_MEDIA_UNMOUNTED)) {
236b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                // SD card unavailable
2379a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project                // handled in ACTION_MEDIA_EJECT
238b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_STARTED)) {
239b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                Toast.makeText(VideoCamera.this, getResources().getString(R.string.wait), 5000);
240b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) {
2419a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project                updateAndShowStorageHint(true);
242b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
243b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
244b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    };
245b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
246b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    static private String createName(long dateTaken) {
247b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return DateFormat.format("yyyy-MM-dd kk.mm.ss", dateTaken).toString();
248b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
249b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
250b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    /** Called with the activity is first created. */
251b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
252b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void onCreate(Bundle icicle) {
253b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        super.onCreate(icicle);
254b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
255b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
256b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
257b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mPreferences = PreferenceManager.getDefaultSharedPreferences(this);
258b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mContentResolver = getContentResolver();
259b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
260b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        //setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT);
261b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        requestWindowFeature(Window.FEATURE_PROGRESS);
262b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        setContentView(R.layout.video_camera);
263b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
264b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mVideoPreview = (VideoPreview) findViewById(R.id.camera_preview);
265b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mVideoPreview.setAspectRatio(VIDEO_ASPECT_RATIO);
266b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
267b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // don't set mSurfaceHolder here. We have it set ONLY within
268b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // surfaceCreated / surfaceDestroyed, other parts of the code
269b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // assume that when it is set, the surface is also set.
270b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        SurfaceHolder holder = mVideoPreview.getHolder();
271b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        holder.addCallback(this);
272b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
273b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
274b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mPostPictureAlert = findViewById(R.id.post_picture_panel);
275b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
276b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        int[] ids = new int[]{R.id.play, R.id.share, R.id.discard,
277b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                R.id.cancel, R.id.attach};
278b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        for (int id : ids) {
279b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            findViewById(id).setOnClickListener(this);
280b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
281b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
282b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mShutterButton = (ShutterButton) findViewById(R.id.shutter_button);
283b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mShutterButton.setOnShutterButtonListener(this);
284b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mRecordingTimeView = (TextView) findViewById(R.id.recording_time);
285b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mVideoFrame = (ImageView) findViewById(R.id.video_frame);
2869bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        mIsVideoCaptureIntent = isVideoCaptureIntent();
2879bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (!mIsVideoCaptureIntent) {
2889bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mLastPictureButton = (ImageView) findViewById(R.id.last_picture_button);
2899bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mLastPictureButton.setOnClickListener(this);
2909bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            Drawable frame = getResources().getDrawable(R.drawable.frame_thumbnail);
2919bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mThumbController = new ThumbnailController(mLastPictureButton,
2929bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                    frame, mContentResolver);
2939bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mThumbController.loadData(ImageManager.getLastVideoThumbPath());
2949bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        }
295b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
296b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
297e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project    private void startShareVideoActivity() {
2988d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project        if (mCurrentVideoFileLength > SHARE_FILE_LENGTH_LIMIT) {
299e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project            Toast.makeText(VideoCamera.this,
300e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project                    R.string.too_large_to_attach, Toast.LENGTH_LONG).show();
301e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project            return;
302e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project        }
303e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project        Intent intent = new Intent();
304e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project        intent.setAction(Intent.ACTION_SEND);
305e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project        intent.setType("video/3gpp");
306e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project        intent.putExtra(Intent.EXTRA_STREAM, mCurrentVideoUri);
307e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project        try {
308e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project            startActivity(Intent.createChooser(intent, getText(R.string.sendVideo)));
309e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project        } catch (android.content.ActivityNotFoundException ex) {
310e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project            Toast.makeText(VideoCamera.this, R.string.no_way_to_share_video, Toast.LENGTH_SHORT).show();
311e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project        }
312e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project    }
313e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project
314b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void onClick(View v) {
315b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        switch (v.getId()) {
316b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
317b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case R.id.gallery:
318b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                MenuHelper.gotoCameraVideoGallery(this);
319b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
320b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
321b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case R.id.attach:
322b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                doReturnToCaller(true);
323b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
324b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
325b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case R.id.cancel:
326b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                doReturnToCaller(false);
327b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
328b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
329b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case R.id.discard: {
3307638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen                Runnable deleteCallback = new Runnable() {
3317638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen                    public void run() {
3327638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen                        discardCurrentVideoAndStartPreview();
3337638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen                    }
3347638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen                };
3357638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen                MenuHelper.deleteVideo(this, deleteCallback);
336b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
337b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
338b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
339b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case R.id.share: {
340e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project                startShareVideoActivity();
341b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
342b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
343b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
344b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case R.id.play: {
345b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                doPlayCurrentVideo();
346b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
347b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
348de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
349de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            case R.id.last_picture_button: {
3509bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                stopVideoRecordingAndShowAlert();
351de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                break;
352de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            }
353b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
354b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
355b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
356b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void onShutterButtonFocus(ShutterButton button, boolean pressed) {
357de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        // Do nothing (everything happens in onShutterButtonClick).
358de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project    }
359de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
360de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project    public void onShutterButtonClick(ShutterButton button) {
361b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        switch (button.getId()) {
362b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case R.id.shutter_button:
363de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                if (mMediaRecorderRecording) {
3649bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                    if (mIsVideoCaptureIntent) {
365de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                        stopVideoRecordingAndShowAlert();
366b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    } else {
3679bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                        stopVideoRecordingAndGetThumbnail();
3689bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                        initializeVideo();
3699bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                    }
3709bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                } else if (isAlertVisible()) {
3719bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                    if (mIsVideoCaptureIntent) {
3729bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                        discardCurrentVideoAndStartPreview();
3739bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                    } else {
3749bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                        hideAlertAndStartVideoRecording();
375b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    }
376de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                } else {
377de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                    startVideoRecording();
378b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
379b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
380b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
381b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
382b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
383b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void doPlayCurrentVideo() {
384b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Log.e(TAG, "Playing current video: " + mCurrentVideoUri);
385b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Intent intent = new Intent(Intent.ACTION_VIEW, mCurrentVideoUri);
386b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        try {
387b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            startActivity(intent);
388b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } catch (android.content.ActivityNotFoundException ex) {
389b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Log.e(TAG, "Couldn't view video " + mCurrentVideoUri, ex);
390b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
391b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
392b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
393b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void discardCurrentVideoAndStartPreview() {
394b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        deleteCurrentVideo();
3959bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        hideAlertAndStartPreview();
396b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
397b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
398b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private OnScreenHint mStorageHint;
399b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
4009a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project    private void updateAndShowStorageHint(boolean mayHaveSd) {
4019a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        mStorageStatus = getStorageStatus(mayHaveSd);
4029a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        showStorageHint();
4039a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project    }
4049a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project
4059a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project    private void showStorageHint() {
406b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        String errorMessage = null;
4079a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        switch (mStorageStatus) {
4089a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        case STORAGE_STATUS_NONE:
409b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            errorMessage = getString(R.string.no_storage);
4109a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project            break;
4119a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        case STORAGE_STATUS_LOW:
412b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            errorMessage = getString(R.string.spaceIsLow_content);
413b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
414b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (errorMessage != null) {
415b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (mStorageHint == null) {
416b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mStorageHint = OnScreenHint.makeText(this, errorMessage);
417b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } else {
418b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mStorageHint.setText(errorMessage);
419b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
420b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mStorageHint.show();
421b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } else if (mStorageHint != null) {
422b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mStorageHint.cancel();
423b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mStorageHint = null;
424b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
425b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
426b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
4279a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project    private int getStorageStatus(boolean mayHaveSd) {
4289a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        long remaining = mayHaveSd ? getAvailableStorage() : NO_STORAGE_ERROR;
4299a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        if (remaining == NO_STORAGE_ERROR) {
4309a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project            return STORAGE_STATUS_NONE;
4319a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        }
4329a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        return remaining < LOW_STORAGE_THRESHOLD
4339a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project                ? STORAGE_STATUS_LOW : STORAGE_STATUS_OK;
4349a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project    }
4359a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project
436b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
437b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void onResume() {
438b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        super.onResume();
439b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
440b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        setScreenTimeoutLong();
441b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
442b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mPausing = false;
443b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
444b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // install an intent filter to receive SD card related events.
445b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED);
446b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        intentFilter.addAction(Intent.ACTION_MEDIA_EJECT);
447b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
448b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED);
449b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
450b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        intentFilter.addDataScheme("file");
451b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        registerReceiver(mReceiver, intentFilter);
4529a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        mStorageStatus = getStorageStatus(true);
4539a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project
4549a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        mHandler.postDelayed(new Runnable() {
4559a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project            public void run() {
4569a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project                showStorageHint();
4579a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project            }
4589a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        }, 200);
459b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
4609bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        initializeVideo();
461b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
462b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
463b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
464b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void onStop() {
465b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        setScreenTimeoutSystemDefault();
466b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        super.onStop();
467b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
468b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
469b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
470b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    protected void onPause() {
471b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        super.onPause();
472b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
4739bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        // This is similar to what mShutterButton.performClick() does,
4749bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        // but not quite the same.
4759bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (mMediaRecorderRecording) {
4769bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            if (mIsVideoCaptureIntent) {
4779bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                stopVideoRecordingAndShowAlert();
4789bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            } else {
4799bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                stopVideoRecordingAndGetThumbnail();
4809bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            }
4819bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        } else {
4829bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            stopVideoRecording();
4839bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        }
484b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
485b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mPausing = true;
486b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
4879c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project        unregisterReceiver(mReceiver);
488b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        setScreenTimeoutSystemDefault();
489b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
4909bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (!mIsVideoCaptureIntent) {
4919bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mThumbController.storeData(ImageManager.getLastVideoThumbPath());
4929bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        }
493095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin
494b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mStorageHint != null) {
495b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mStorageHint.cancel();
496b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mStorageHint = null;
497b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
498b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
499b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
500b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
501b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public boolean onKeyDown(int keyCode, KeyEvent event) {
502b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        setScreenTimeoutLong();
503b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
504b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        switch (keyCode) {
505b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case KeyEvent.KEYCODE_BACK:
506b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                if (mMediaRecorderRecording) {
507de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                    mShutterButton.performClick();
508b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    return true;
5099bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                } else if(isAlertVisible()) {
5109bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                    hideAlertAndStartPreview();
511b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    return true;
512b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
513b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
514b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case KeyEvent.KEYCODE_CAMERA:
515b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                if (event.getRepeatCount() == 0) {
516de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                    mShutterButton.performClick();
517b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    return true;
518b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
519de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                break;
520b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case KeyEvent.KEYCODE_DPAD_CENTER:
521b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                if (event.getRepeatCount() == 0) {
522de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                    mShutterButton.performClick();
523de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                    return true;
524b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
525b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
526b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case KeyEvent.KEYCODE_MENU:
527b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                if (mMediaRecorderRecording) {
528de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                    mShutterButton.performClick();
529b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    return true;
530b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
531b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
532b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
533b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
534b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return super.onKeyDown(keyCode, event);
535b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
536b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
537b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
538b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public boolean onKeyUp(int keyCode, KeyEvent event) {
539b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        switch(keyCode) {
540b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        case KeyEvent.KEYCODE_CAMERA:
541b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mShutterButton.setPressed(false);
542b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            return true;
543b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
544b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return super.onKeyUp(keyCode, event);
545b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
546b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
547b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
548314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber        if (mPausing) {
549314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber            // We're pausing, the screen is off and we already stopped
550314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber            // video recording. We don't want to start the camera again
551314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber            // in this case in order to conserve power.
552314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber            // The fact that surfaceChanged is called _after_ an onPause appears
553314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber            // to be legitimate since in that case the lockscreen always returns
554314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber            // to portrait orientation possibly triggering the notification.
555314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber            return;
556314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber        }
557314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber
558b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        stopVideoRecording();
559b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        initializeVideo();
560b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
561b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
562b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void surfaceCreated(SurfaceHolder holder) {
563b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mSurfaceHolder = holder;
564b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
565b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
566b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void surfaceDestroyed(SurfaceHolder holder) {
567b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mSurfaceHolder = null;
568b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
569b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
570b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    void gotoGallery() {
571b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        MenuHelper.gotoCameraVideoGallery(this);
572b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
573b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
574b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
575b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public boolean onPrepareOptionsMenu(Menu menu) {
576b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        super.onPrepareOptionsMenu(menu);
577b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
578b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        for (int i = 1; i <= MenuHelper.MENU_ITEM_MAX; i++) {
579b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (i != MenuHelper.GENERIC_ITEM) {
580b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                menu.setGroupVisible(i, false);
581b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
582b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
583b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
584b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        menu.setGroupVisible(MenuHelper.VIDEO_MODE_ITEM, true);
585b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return true;
586b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
587b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
588b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
589b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public boolean onCreateOptionsMenu(Menu menu) {
590b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        super.onCreateOptionsMenu(menu);
591b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
5929bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (mIsVideoCaptureIntent) {
593b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // No options menu for attach mode.
594b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            return false;
595b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } else {
596b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            addBaseMenuItems(menu);
597095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin            int menuFlags = MenuHelper.INCLUDE_ALL & ~MenuHelper.INCLUDE_ROTATE_MENU
598095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin                    & ~MenuHelper.INCLUDE_DETAILS_MENU;
599b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            MenuHelper.addImageMenuItems(
600b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    menu,
601095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin                    menuFlags,
602b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    false,
603b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    VideoCamera.this,
604b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    mHandler,
605b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
606b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    // Handler for deletion
607b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    new Runnable() {
608b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        public void run() {
609b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            // What do we do here?
610b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            // mContentResolver.delete(uri, null, null);
611b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        }
612b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    },
613b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    new MenuHelper.MenuInvoker() {
614b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        public void run(final MenuHelper.MenuCallback cb) {
615b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        }
616b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    });
617b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
618b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            MenuItem gallery = menu.add(MenuHelper.IMAGE_SAVING_ITEM, MENU_SAVE_GALLERY_PHOTO, 0,
619b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    R.string.camera_gallery_photos_text).setOnMenuItemClickListener(
620b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            new MenuItem.OnMenuItemClickListener() {
621b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                public boolean onMenuItemClick(MenuItem item) {
622b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    gotoGallery();
623b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    return true;
624b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
625b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            });
626b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            gallery.setIcon(android.R.drawable.ic_menu_gallery);
627b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
628b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return true;
629b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
630b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
631b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private boolean isVideoCaptureIntent() {
632b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        String action = getIntent().getAction();
633b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return (MediaStore.ACTION_VIDEO_CAPTURE.equals(action));
634b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
635b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
636b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void doReturnToCaller(boolean success) {
637b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Intent resultIntent = new Intent();
638b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        int resultCode;
639b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (success) {
640b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            resultCode = RESULT_OK;
641b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            resultIntent.setData(mCurrentVideoUri);
642b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } else {
643b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            resultCode = RESULT_CANCELED;
644b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
645b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        setResult(resultCode, resultIntent);
646b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        finish();
647b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
648b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
649b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    /**
650b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project     * Returns
651b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project     * @return number of bytes available, or an ERROR code.
652b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project     */
653b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static long getAvailableStorage() {
654b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        try {
655b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (!ImageManager.hasStorage()) {
656b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                return NO_STORAGE_ERROR;
657b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } else {
658b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                String storageDirectory = Environment.getExternalStorageDirectory().toString();
659b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                StatFs stat = new StatFs(storageDirectory);
660b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                return ((long)stat.getAvailableBlocks() * (long)stat.getBlockSize());
661b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
662b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } catch (Exception ex) {
663b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // if we can't stat the filesystem then we don't know how many
664b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // free bytes exist.  It might be zero but just leave it
665b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // blank since we really don't know.
666b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            return CANNOT_STAT_ERROR;
667b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
668b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
669b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
670b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void cleanupEmptyFile() {
671b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mCameraVideoFilename != null) {
672b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            File f = new File(mCameraVideoFilename);
673b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (f.length() == 0 && f.delete()) {
674b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project              Log.v(TAG, "Empty video file deleted: " + mCameraVideoFilename);
675b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project              mCameraVideoFilename = null;
676b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
677b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
678b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
679b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
6809bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    // initializeVideo() starts preview and prepare media recorder.
681b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    // Returns false if initializeVideo fails
682b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private boolean initializeVideo() {
683b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Log.v(TAG, "initializeVideo");
6849bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang
6859bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        // We will call initializeVideo() again when the alert is hidden.
6869bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (isAlertVisible()) return false;
6879bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang
688b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Intent intent = getIntent();
689b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Bundle myExtras = intent.getExtras();
690b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
6919bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (mIsVideoCaptureIntent && myExtras != null) {
692b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Uri saveUri = (Uri) myExtras.getParcelable(MediaStore.EXTRA_OUTPUT);
693b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (saveUri != null) {
694b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                try {
695b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    mCameraVideoFileDescriptor = mContentResolver.
696b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        openFileDescriptor(saveUri, "rw").getFileDescriptor();
697b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    mCurrentVideoUri = saveUri;
698b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
699b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                catch (java.io.FileNotFoundException ex) {
700b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    // invalid uri
701b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    Log.e(TAG, ex.toString());
702b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
703b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
704b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
705b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        releaseMediaRecorder();
706b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
707b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mSurfaceHolder == null) {
708b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Log.v(TAG, "SurfaceHolder is null");
709b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            return false;
710b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
711b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
712b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mMediaRecorder = new MediaRecorder();
713b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
714b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (DEBUG_SUPPRESS_AUDIO_RECORDING) {
715b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Log.v(TAG, "DEBUG_SUPPRESS_AUDIO_RECORDING is true.");
716b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } else {
717b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
718b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
719b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
720b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
721b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
7228d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project        mMediaRecorder.setMaxDuration(MAX_RECORDING_DURATION_MS);
7238d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project
7249a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        if (mStorageStatus != STORAGE_STATUS_OK) {
725b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mMediaRecorder.setOutputFile("/dev/null");
726b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } else {
727b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // We try Uri in intent first. If it doesn't work, use our own instead.
728b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (mCameraVideoFileDescriptor != null) {
729b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mMediaRecorder.setOutputFile(mCameraVideoFileDescriptor);
730b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } else {
731b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                createVideoPath();
732b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mMediaRecorder.setOutputFile(mCameraVideoFilename);
733b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
734b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
735b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
736b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        boolean videoQualityHigh = getBooleanPreference(CameraSettings.KEY_VIDEO_QUALITY,
737b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                CameraSettings.DEFAULT_VIDEO_QUALITY_VALUE);
738b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
739b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (intent.hasExtra(MediaStore.EXTRA_VIDEO_QUALITY)) {
740b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            int extraVideoQuality = intent.getIntExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0);
741b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            videoQualityHigh = (extraVideoQuality > 0);
742b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
743b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
744b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // Use the same frame rate for both, since internally
745b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // if the frame rate is too large, it can cause camera to become
746b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // unstable. We need to fix the MediaRecorder to disable the support
747b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // of setting frame rate for now.
748b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mMediaRecorder.setVideoFrameRate(20);
749b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (videoQualityHigh) {
750b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mMediaRecorder.setVideoSize(352,288);
751b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } else {
752b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mMediaRecorder.setVideoSize(176,144);
753b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
754b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
755b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (!DEBUG_SUPPRESS_AUDIO_RECORDING) {
756b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
757b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
758b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
759de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
760de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        long remaining = getAvailableStorage();
761de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        // remaining >= LOW_STORAGE_THRESHOLD at this point, reserve a quarter
762de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        // of that to make it more likely that recording can complete successfully.
763de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        try {
764de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            mMediaRecorder.setMaxFileSize(remaining - LOW_STORAGE_THRESHOLD / 4);
765de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        } catch (RuntimeException exception) {
766de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            // We are going to ignore failure of setMaxFileSize here, as
767de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            // a) The composer selected may simply not support it, or
768de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            // b) The underlying media framework may not handle 64-bit range
769de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            //    on the size restriction.
770de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        }
771de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
772b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        try {
773b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mMediaRecorder.prepare();
774b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } catch (IOException exception) {
775b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Log.e(TAG, "prepare failed for " + mCameraVideoFilename);
776b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            releaseMediaRecorder();
777b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // TODO: add more exception handling logic here
778b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            return false;
779b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
780b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mMediaRecorderRecording = false;
7819bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang
7829bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (!mIsVideoCaptureIntent && !mThumbController.isUriValid()) {
7839bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            updateLastVideo();
7849bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        }
7859bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang
7869bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (!mIsVideoCaptureIntent) {
7879bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mThumbController.updateDisplayIfNeeded();
7889bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        }
7899bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang
790b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return true;
791b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
792b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
793b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void releaseMediaRecorder() {
794b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Log.v(TAG, "Releasing media recorder.");
795b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mMediaRecorder != null) {
796b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            cleanupEmptyFile();
797b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mMediaRecorder.reset();
798b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mMediaRecorder.release();
799b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mMediaRecorder = null;
800b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
801b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
802b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
803b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private int getIntPreference(String key, int defaultValue) {
804b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        String s = mPreferences.getString(key, "");
805b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        int result = defaultValue;
806b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        try {
807b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            result = Integer.parseInt(s);
808b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } catch (NumberFormatException e) {
809b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // Ignore, result is already the default value.
810b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
811b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return result;
812b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
813b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
814b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private boolean getBooleanPreference(String key, boolean defaultValue) {
815b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return getIntPreference(key, defaultValue ? 1 : 0) != 0;
816b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
817b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
818b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void createVideoPath() {
819b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        long dateTaken = System.currentTimeMillis();
820b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        String title = createName(dateTaken);
821b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        String displayName = title + ".3gp"; // Used when emailing.
822b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        String cameraDirPath = ImageManager.CAMERA_IMAGE_BUCKET_NAME;
823b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        File cameraDir = new File(cameraDirPath);
824b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        cameraDir.mkdirs();
825b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        SimpleDateFormat dateFormat = new SimpleDateFormat(
826b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                getString(R.string.video_file_name_format));
827b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Date date = new Date(dateTaken);
828b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        String filepart = dateFormat.format(date);
829b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        String filename = cameraDirPath + "/" + filepart + ".3gp";
830b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        ContentValues values = new ContentValues(7);
831b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        values.put(Video.Media.TITLE, title);
832b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        values.put(Video.Media.DISPLAY_NAME, displayName);
833b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        values.put(Video.Media.DESCRIPTION, "");
834b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        values.put(Video.Media.DATE_TAKEN, dateTaken);
835b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        values.put(Video.Media.MIME_TYPE, "video/3gpp");
836b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        values.put(Video.Media.DATA, filename);
837b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mCameraVideoFilename = filename;
838b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Log.v(TAG, "Current camera video filename: " + mCameraVideoFilename);
839b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mCurrentVideoValues = values;
840b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
841b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
842b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void registerVideo() {
843b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mCameraVideoFileDescriptor == null) {
844b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Uri videoTable = Uri.parse("content://media/external/video/media");
845b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mCurrentVideoUri = mContentResolver.insert(videoTable,
846b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    mCurrentVideoValues);
847b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Log.v(TAG, "Current video URI: " + mCurrentVideoUri);
848b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
849b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mCurrentVideoValues = null;
850b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
851b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
852b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void deleteCurrentVideo() {
853b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mCurrentVideoFilename != null) {
854b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            deleteVideoFile(mCurrentVideoFilename);
855b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mCurrentVideoFilename = null;
856b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
857b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mCurrentVideoUri != null) {
858b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mContentResolver.delete(mCurrentVideoUri, null, null);
859b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mCurrentVideoUri = null;
860b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
861de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        updateAndShowStorageHint(true);
862b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
863b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
864b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void deleteVideoFile(String fileName) {
865b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Log.v(TAG, "Deleting video " + fileName);
866b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        File f = new File(fileName);
867b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (! f.delete()) {
868b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Log.v(TAG, "Could not delete " + fileName);
869b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
870b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
871b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
872b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void addBaseMenuItems(Menu menu) {
873b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        MenuHelper.addSwitchModeMenuItem(menu, this, false);
874b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        {
875b64d345c9d51cabce43b5191532a0c185d2a70a5The 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() {
876b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                public boolean onMenuItemClick(MenuItem item) {
877b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    gotoGallery();
878b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    return true;
879b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
880b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            });
881b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            gallery.setIcon(android.R.drawable.ic_menu_gallery);
882b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mGalleryItems.add(gallery);
883b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
884b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        {
885b64d345c9d51cabce43b5191532a0c185d2a70a5The 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() {
886b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                public boolean onMenuItemClick(MenuItem item) {
887b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    gotoGallery();
888b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    return true;
889b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
890b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            });
891b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            gallery.setIcon(android.R.drawable.ic_menu_gallery);
892b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mGalleryItems.add(gallery);
893b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
894b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
895b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        MenuItem item = menu.add(MenuHelper.GENERIC_ITEM, MENU_SETTINGS, 0, R.string.settings).setOnMenuItemClickListener(new OnMenuItemClickListener() {
896b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            public boolean onMenuItemClick(MenuItem item) {
897b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                Intent intent = new Intent();
898b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                intent.setClass(VideoCamera.this, CameraSettings.class);
899b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                startActivity(intent);
900b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                return true;
901b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
902b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        });
903b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        item.setIcon(android.R.drawable.ic_menu_preferences);
904b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
905b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
906b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    // from MediaRecorder.OnErrorListener
907b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void onError(MediaRecorder mr, int what, int extra) {
908b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (what == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) {
909b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // We may have run out of space on the sdcard.
910b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            stopVideoRecording();
9119a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project            updateAndShowStorageHint(true);
912b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
913b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
914b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
9158d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project    // from MediaRecorder.OnInfoListener
9168d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project    public void onInfo(MediaRecorder mr, int what, int extra) {
9178d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project        if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
918de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            mShutterButton.performClick();
919de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        } else if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED) {
920de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            mShutterButton.performClick();
921de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            updateAndShowStorageHint(true);
9228d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project        }
9238d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project    }
9248d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project
9259c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project    /*
9269c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project     * Make sure we're not recording music playing in the background, ask
9279c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project     * the MediaPlaybackService to pause playback.
9289c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project     */
9299c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project    private void pauseAudioPlayback() {
9309c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project        // Shamelessly copied from MediaPlaybackService.java, which
9319c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project        // should be public, but isn't.
9329c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project        Intent i = new Intent("com.android.music.musicservicecommand");
9339c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project        i.putExtra("command", "pause");
9349c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project
9359c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project        sendBroadcast(i);
9369c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project    }
9379c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project
938b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void startVideoRecording() {
939b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Log.v(TAG, "startVideoRecording");
940b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (!mMediaRecorderRecording) {
941b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
9429a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project            if (mStorageStatus != STORAGE_STATUS_OK) {
943b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                Log.v(TAG, "Storage issue, ignore the start request");
944b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                return;
945b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
946b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
947b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // Check mMediaRecorder to see whether it is initialized or not.
948b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (mMediaRecorder == null && initializeVideo() == false ) {
949b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                Log.e(TAG, "Initialize video (MediaRecorder) failed.");
950b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                return;
951b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
952b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
9539c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project            pauseAudioPlayback();
9549c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project
955b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            try {
956b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mMediaRecorder.setOnErrorListener(this);
9578d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                mMediaRecorder.setOnInfoListener(this);
958b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mMediaRecorder.start();   // Recording is now started
959b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } catch (RuntimeException e) {
960b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                Log.e(TAG, "Could not start media recorder. ", e);
961b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                return;
962b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
963b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mMediaRecorderRecording = true;
964b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mRecordingStartTime = SystemClock.uptimeMillis();
965b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            updateRecordingIndicator(true);
966b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mRecordingTimeView.setText("");
967b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mRecordingTimeView.setVisibility(View.VISIBLE);
968b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mHandler.sendEmptyMessage(UPDATE_RECORD_TIME);
969b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            setScreenTimeoutInfinite();
970de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            hideLastPictureButton();
971b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
972b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
973b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
974b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void updateRecordingIndicator(boolean showRecording) {
975b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        int drawableId = showRecording ? R.drawable.ic_camera_bar_indicator_record
976b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            : R.drawable.ic_camera_indicator_video;
977b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Drawable drawable = getResources().getDrawable(drawableId);
978b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mShutterButton.setImageDrawable(drawable);
979b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
980b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
9819bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private void stopVideoRecordingAndGetThumbnail() {
9829bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        stopVideoRecording();
9839bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        acquireVideoThumb();
984b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
985b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
986de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project    private void stopVideoRecordingAndShowAlert() {
987de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        stopVideoRecording();
9889bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        showAlert();
989de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project    }
990de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
9919bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private void showAlert() {
992b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        int[] pickIds = {R.id.attach, R.id.cancel};
993b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        int[] normalIds = {R.id.gallery, R.id.share, R.id.discard};
994b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        int[] alwaysOnIds = {R.id.play};
995b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        int[] hideIds = pickIds;
996b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        int[] connectIds = normalIds;
9979bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (mIsVideoCaptureIntent) {
998b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            hideIds = normalIds;
999b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            connectIds = pickIds;
1000b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1001b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        for(int id : hideIds) {
1002b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mPostPictureAlert.findViewById(id).setVisibility(View.GONE);
1003b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
10048d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project        ActionMenuButton shareButton =
10058d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                (ActionMenuButton) mPostPictureAlert.findViewById(R.id.share);
10068d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project        shareButton.setRestricted(
10078d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                mCurrentVideoFileLength > SHARE_FILE_LENGTH_LIMIT);
1008b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        connectAndFadeIn(connectIds);
1009b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        connectAndFadeIn(alwaysOnIds);
1010de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        hideLastPictureButton();
1011b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mPostPictureAlert.setVisibility(View.VISIBLE);
10129bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang
10139bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        // There are two cases we are here:
10149bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        // (1) We are in a capture video intent, and we are reviewing the video
1015095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin        //     we just taken.
10169bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        // (2) The thumbnail button is clicked: we review the video associated
10179bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        //     with the thumbnail.
10189bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        // For the second case, we copy the associated URI and filename to
10199bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        // mCurrentVideoUri and mCurrentVideoFilename, so the video frame shown
10209bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        // and the target for actions (play, delete, ...) will be correct.
10219bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang
10229bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (!mIsVideoCaptureIntent) {
10239bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mCurrentVideoUri = mThumbController.getUri();
10249bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mCurrentVideoFilename = getDataPath(mCurrentVideoUri);
10259bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        }
10269bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang
10279bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        String path = mCurrentVideoFilename;
10289bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (path != null) {
10299bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            Bitmap videoFrame = ImageManager.createVideoThumbnail(path);
10309bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mVideoFrame.setImageBitmap(videoFrame);
10319bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mVideoFrame.setVisibility(View.VISIBLE);
10329bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        }
1033b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1034b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
10359bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private void hideAlert() {
1036de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        mVideoFrame.setVisibility(View.INVISIBLE);
1037de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        mPostPictureAlert.setVisibility(View.INVISIBLE);
1038de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        showLastPictureButton();
1039de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project    }
1040de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
1041b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void connectAndFadeIn(int[] connectIds) {
1042b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        for(int id : connectIds) {
1043b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            View view = mPostPictureAlert.findViewById(id);
1044b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            view.setOnClickListener(this);
1045b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Animation animation = new AlphaAnimation(0F, 1F);
1046b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            animation.setDuration(500);
10479bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            view.startAnimation(animation);
1048b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1049b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1050b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
10519bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private boolean isAlertVisible() {
1052b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return mPostPictureAlert.getVisibility() == View.VISIBLE;
1053b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1054b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1055b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void stopVideoRecording() {
1056b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Log.v(TAG, "stopVideoRecording");
1057b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        boolean needToRegisterRecording = false;
1058b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mMediaRecorderRecording || mMediaRecorder != null) {
1059b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (mMediaRecorderRecording && mMediaRecorder != null) {
1060b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                try {
1061b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    mMediaRecorder.setOnErrorListener(null);
10628d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                    mMediaRecorder.setOnInfoListener(null);
1063b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    mMediaRecorder.stop();
1064b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                } catch (RuntimeException e) {
1065b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    Log.e(TAG, "stop fail: " + e.getMessage());
1066b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
10678d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project
1068b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mCurrentVideoFilename = mCameraVideoFilename;
10698d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                try {
10708d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                    mCurrentVideoFileLength = new File(mCurrentVideoFilename).length();
10718d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                } catch (RuntimeException e) {
10728d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                    Log.e(TAG, "get file length fail: " + e.getMessage());
10738d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                    mCurrentVideoFileLength = 0;
10748d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                }
1075b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                Log.v(TAG, "Setting current video filename: " + mCurrentVideoFilename);
1076b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                needToRegisterRecording = true;
1077b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mMediaRecorderRecording = false;
1078b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
1079b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            releaseMediaRecorder();
1080b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            updateRecordingIndicator(false);
1081b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mRecordingTimeView.setVisibility(View.GONE);
1082b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            setScreenTimeoutLong();
1083b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
10849a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        if (needToRegisterRecording && mStorageStatus == STORAGE_STATUS_OK) {
10859a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project            registerVideo();
10869a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        }
1087b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1088b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mCameraVideoFilename = null;
1089b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mCameraVideoFileDescriptor = null;
1090b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1091b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1092b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void setScreenTimeoutSystemDefault() {
1093b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mHandler.removeMessages(CLEAR_SCREEN_DELAY);
1094b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        clearScreenOnFlag();
1095b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1096b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1097b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void setScreenTimeoutLong() {
1098b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mHandler.removeMessages(CLEAR_SCREEN_DELAY);
1099b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        setScreenOnFlag();
1100b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mHandler.sendEmptyMessageDelayed(CLEAR_SCREEN_DELAY, SCREEN_DELAY);
1101b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1102b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1103b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void setScreenTimeoutInfinite() {
1104b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mHandler.removeMessages(CLEAR_SCREEN_DELAY);
1105b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        setScreenOnFlag();
1106b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1107b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1108b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void clearScreenOnFlag() {
1109b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Window w = getWindow();
1110b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        final int keepScreenOnFlag = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
1111b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if ((w.getAttributes().flags & keepScreenOnFlag) != 0) {
1112b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            w.clearFlags(keepScreenOnFlag);
1113b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1114b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1115b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1116b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void setScreenOnFlag() {
1117b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Window w = getWindow();
1118b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        final int keepScreenOnFlag = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
1119b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if ((w.getAttributes().flags & keepScreenOnFlag) == 0) {
1120b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            w.addFlags(keepScreenOnFlag);
1121b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1122b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1123b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
11249bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private void hideAlertAndStartPreview() {
11259bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        hideAlert();
11269bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        initializeVideo();
1127b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1128b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
11299bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private void hideAlertAndStartVideoRecording() {
11309bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        hideAlert();
11319bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        startVideoRecording();
1132b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1133b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
11349bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private void acquireVideoThumb() {
11359bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        Bitmap videoFrame = ImageManager.createVideoThumbnail(mCurrentVideoFilename);
11369bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        mThumbController.setData(mCurrentVideoUri, videoFrame);
1137de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project    }
1138de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
11399bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private void showLastPictureButton() {
11409bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (!mIsVideoCaptureIntent) {
11419bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mLastPictureButton.setVisibility(View.VISIBLE);
1142de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        }
11439bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    }
1144de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
11459bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private void hideLastPictureButton() {
11469bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (!mIsVideoCaptureIntent) {
11479bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mLastPictureButton.setVisibility(View.INVISIBLE);
11489bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        }
1149de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project    }
1150de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
11519bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private static ImageManager.DataLocation dataLocation() {
11529bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        return ImageManager.DataLocation.EXTERNAL;
1153de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project    }
1154de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
11559bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private void updateLastVideo() {
11569bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        ImageManager.IImageList list = ImageManager.instance().allImages(
11579bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            this,
11589bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mContentResolver,
11599bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            dataLocation(),
11609bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            ImageManager.INCLUDE_VIDEOS,
11619bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            ImageManager.SORT_ASCENDING,
11629bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            ImageManager.CAMERA_IMAGE_BUCKET_ID);
11639bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        int count = list.getCount();
11649bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (count > 0) {
11659bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            ImageManager.IImage image = list.getImageAt(count-1);
11669bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            Uri uri = image.fullSizeImageUri();
11679bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mThumbController.setData(uri, image.miniThumbBitmap());
11689bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        } else {
11699bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mThumbController.setData(null, null);
11709bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        }
11719bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        list.deactivate();
1172b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1173b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
11749bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private static final String[] DATA_PATH_PROJECTION = new String[] {
11759bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        "_data"
11769bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    };
11779bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang
11789bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private String getDataPath(Uri uri) {
11799bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        Cursor c = null;
11809bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        try {
11819bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            c = mContentResolver.query(uri, DATA_PATH_PROJECTION, null, null, null);
11829bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            if (c != null && c.moveToFirst()) {
11839bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                return c.getString(0);
11849bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            } else {
11859bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                return null;
11869bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            }
11879bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        } finally {
11889bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            if (c != null) c.close();
1189b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1190b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1191b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project}
1192