VideoCamera.java revision 23c51b794e95c201290e36737f379c4bb8eefeae
1b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project/*
2b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project *
4b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * you may not use this file except in compliance with the License.
6b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * You may obtain a copy of the License at
7b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project *
8b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project *
10b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * See the License for the specific language governing permissions and
14b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * limitations under the License.
15b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project */
16b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
17b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectpackage com.android.camera;
18b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
19101d528d59f447847d5c6b7578642132c2b76f4fOwen Linimport com.android.camera.gallery.IImage;
20101d528d59f447847d5c6b7578642132c2b76f4fOwen Linimport com.android.camera.gallery.IImageList;
21101d528d59f447847d5c6b7578642132c2b76f4fOwen Linimport com.android.camera.gallery.Util;
22101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin
23b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.app.Activity;
24b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.BroadcastReceiver;
25b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.ContentResolver;
26b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.ContentValues;
27b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.Context;
28b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.Intent;
29b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.IntentFilter;
30b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.SharedPreferences;
31095afa19556bf550262e3cccb9edacc04e6f726aOwen Linimport android.database.Cursor;
32b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.graphics.Bitmap;
33b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.graphics.drawable.Drawable;
34b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.location.LocationManager;
35b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.media.MediaRecorder;
36b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.net.Uri;
37b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Bundle;
38b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Environment;
39b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Handler;
40b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Message;
41b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.StatFs;
42b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.SystemClock;
43b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.preference.PreferenceManager;
44b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.provider.MediaStore;
45b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.provider.MediaStore.Video;
46b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.text.format.DateFormat;
47b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.util.Log;
48b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.KeyEvent;
49b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.Menu;
50b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.MenuItem;
51d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Changimport android.view.MenuItem.OnMenuItemClickListener;
52b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.SurfaceHolder;
53b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.View;
54b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.Window;
55b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.WindowManager;
56b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.animation.AlphaAnimation;
57b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.animation.Animation;
58b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.widget.ImageView;
59b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.widget.TextView;
60b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.widget.Toast;
61b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
62d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Changimport java.io.File;
63d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Changimport java.io.FileDescriptor;
64d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Changimport java.io.IOException;
65d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Changimport java.text.SimpleDateFormat;
66d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Changimport java.util.ArrayList;
67d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Changimport java.util.Date;
68d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang
6923c51b794e95c201290e36737f379c4bb8eefeaeRay Chen/**
7023c51b794e95c201290e36737f379c4bb8eefeaeRay Chen * The Camcorder activity.
7123c51b794e95c201290e36737f379c4bb8eefeaeRay Chen */
72b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectpublic class VideoCamera extends Activity implements View.OnClickListener,
73d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        ShutterButton.OnShutterButtonListener, SurfaceHolder.Callback,
74d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        MediaRecorder.OnErrorListener, MediaRecorder.OnInfoListener {
75b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
76b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final String TAG = "videocamera";
77b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
78b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final int CLEAR_SCREEN_DELAY = 4;
79b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final int UPDATE_RECORD_TIME = 5;
80b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
81b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final int SCREEN_DELAY = 2 * 60 * 1000;
82b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
83b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final long NO_STORAGE_ERROR = -1L;
84b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final long CANNOT_STAT_ERROR = -2L;
85b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final long LOW_STORAGE_THRESHOLD = 512L * 1024L;
86e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project    private static final long SHARE_FILE_LENGTH_LIMIT = 3L * 1024L * 1024L;
87b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
889a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project    private static final int STORAGE_STATUS_OK = 0;
899a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project    private static final int STORAGE_STATUS_LOW = 1;
909a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project    private static final int STORAGE_STATUS_NONE = 2;
919a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project
92b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_SETTINGS = 6;
93b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_GALLERY_PHOTOS = 7;
94b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_GALLERY_VIDEOS = 8;
95b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_SAVE_GALLERY_PHOTO = 34;
96b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_SAVE_PLAY_VIDEO = 35;
97b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_SAVE_SELECT_VIDEO = 36;
98b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_SAVE_NEW_VIDEO = 37;
99b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
100b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    SharedPreferences mPreferences;
101b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
102b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final float VIDEO_ASPECT_RATIO = 176.0f / 144.0f;
103b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    VideoPreview mVideoPreview;
104b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    SurfaceHolder mSurfaceHolder = null;
105b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    ImageView mVideoFrame;
1069bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang
1079bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private boolean mIsVideoCaptureIntent;
1089bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    // mLastPictureButton and mThumbController
1099bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    // are non-null only if isVideoCaptureIntent() is true;
110de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project    private ImageView mLastPictureButton;
1119bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private ThumbnailController mThumbController;
112b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1138d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project    private static final int MAX_RECORDING_DURATION_MS = 10 * 60 * 1000;
1148d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project
1159a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project    private int mStorageStatus = STORAGE_STATUS_OK;
1169a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project
117b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private MediaRecorder mMediaRecorder;
118b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private boolean mMediaRecorderRecording = false;
119b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private long mRecordingStartTime;
120b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    // The video file that the hardware camera is about to record into
121b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    // (or is recording into.)
122b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private String mCameraVideoFilename;
123b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private FileDescriptor mCameraVideoFileDescriptor;
124b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
125b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    // The video file that has already been recorded, and that is being
126b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    // examined by the user.
127b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private String mCurrentVideoFilename;
1288d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project    private long mCurrentVideoFileLength = 0L;
129b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private Uri mCurrentVideoUri;
130b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private ContentValues mCurrentVideoValues;
131b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
132b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    boolean mPausing = false;
133b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
134d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang    private ContentResolver mContentResolver;
135b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
136b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    int mCurrentZoomIndex = 0;
137b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
138b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private ShutterButton mShutterButton;
139b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private TextView mRecordingTimeView;
1408d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project    private boolean mRecordingTimeCountsDown = false;
141b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
142b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    ArrayList<MenuItem> mGalleryItems = new ArrayList<MenuItem>();
143b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
144b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    View mPostPictureAlert;
145b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    LocationManager mLocationManager = null;
146b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
147b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private Handler mHandler = new MainHandler();
148b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
149d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang    // This Handler is used to post message back onto the main thread of the
150d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang    // application
151b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private class MainHandler extends Handler {
152b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        @Override
153b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        public void handleMessage(Message msg) {
154b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            switch (msg.what) {
155b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
156b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                case CLEAR_SCREEN_DELAY: {
157b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    clearScreenOnFlag();
158b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    break;
159b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
160b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
161b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                case UPDATE_RECORD_TIME: {
162d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                    updateRecordingTime();
163b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    break;
164b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
165b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
166b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                default:
167b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    Log.v(TAG, "Unhandled message: " + msg.what);
168b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                  break;
169b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
170b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
171b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    };
172b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
173b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
174b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        @Override
175b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        public void onReceive(Context context, Intent intent) {
176b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            String action = intent.getAction();
177b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (action.equals(Intent.ACTION_MEDIA_EJECT)) {
1789a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project                updateAndShowStorageHint(false);
179b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                stopVideoRecording();
180b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                initializeVideo();
181b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } else if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) {
1829a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project                updateAndShowStorageHint(true);
183b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                initializeVideo();
184b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } else if (action.equals(Intent.ACTION_MEDIA_UNMOUNTED)) {
185b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                // SD card unavailable
1869a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project                // handled in ACTION_MEDIA_EJECT
187b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_STARTED)) {
188d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                Toast.makeText(VideoCamera.this,
189d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                        getResources().getString(R.string.wait), 5000);
190b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) {
1919a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project                updateAndShowStorageHint(true);
192b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
193b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
194b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    };
195b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
196d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang    private static String createName(long dateTaken) {
197b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return DateFormat.format("yyyy-MM-dd kk.mm.ss", dateTaken).toString();
198b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
199b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
200b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    /** Called with the activity is first created. */
201b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
202b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void onCreate(Bundle icicle) {
203b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        super.onCreate(icicle);
204b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
205d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        mLocationManager = (LocationManager) getSystemService(
206d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                Context.LOCATION_SERVICE);
207b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
208b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mPreferences = PreferenceManager.getDefaultSharedPreferences(this);
209b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mContentResolver = getContentResolver();
210b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
211b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        //setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT);
212b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        requestWindowFeature(Window.FEATURE_PROGRESS);
213b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        setContentView(R.layout.video_camera);
214b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
215b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mVideoPreview = (VideoPreview) findViewById(R.id.camera_preview);
216b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mVideoPreview.setAspectRatio(VIDEO_ASPECT_RATIO);
217b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
218b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // don't set mSurfaceHolder here. We have it set ONLY within
219b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // surfaceCreated / surfaceDestroyed, other parts of the code
220b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // assume that when it is set, the surface is also set.
221b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        SurfaceHolder holder = mVideoPreview.getHolder();
222b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        holder.addCallback(this);
223b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
224b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
225b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mPostPictureAlert = findViewById(R.id.post_picture_panel);
226b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
227b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        int[] ids = new int[]{R.id.play, R.id.share, R.id.discard,
228b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                R.id.cancel, R.id.attach};
229b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        for (int id : ids) {
230b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            findViewById(id).setOnClickListener(this);
231b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
232b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
233b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mShutterButton = (ShutterButton) findViewById(R.id.shutter_button);
234b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mShutterButton.setOnShutterButtonListener(this);
235b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mRecordingTimeView = (TextView) findViewById(R.id.recording_time);
236b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mVideoFrame = (ImageView) findViewById(R.id.video_frame);
2379bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        mIsVideoCaptureIntent = isVideoCaptureIntent();
2389bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (!mIsVideoCaptureIntent) {
239d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang            mLastPictureButton = (ImageView) findViewById(
240d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                    R.id.last_picture_button);
2419bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mLastPictureButton.setOnClickListener(this);
242d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang            Drawable frame = getResources().getDrawable(
243d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                    R.drawable.frame_thumbnail);
2449bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mThumbController = new ThumbnailController(mLastPictureButton,
2459bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                    frame, mContentResolver);
2469bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mThumbController.loadData(ImageManager.getLastVideoThumbPath());
2479bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        }
248b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
249b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
250e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project    private void startShareVideoActivity() {
2518d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project        if (mCurrentVideoFileLength > SHARE_FILE_LENGTH_LIMIT) {
252e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project            Toast.makeText(VideoCamera.this,
253e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project                    R.string.too_large_to_attach, Toast.LENGTH_LONG).show();
254e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project            return;
255e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project        }
256e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project        Intent intent = new Intent();
257e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project        intent.setAction(Intent.ACTION_SEND);
258e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project        intent.setType("video/3gpp");
259e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project        intent.putExtra(Intent.EXTRA_STREAM, mCurrentVideoUri);
260e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project        try {
261d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang            startActivity(Intent.createChooser(
262d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                    intent, getText(R.string.sendVideo)));
263e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project        } catch (android.content.ActivityNotFoundException ex) {
264d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang            Toast.makeText(VideoCamera.this, R.string.no_way_to_share_video,
265d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                    Toast.LENGTH_SHORT).show();
266e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project        }
267e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project    }
268e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project
269b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void onClick(View v) {
270b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        switch (v.getId()) {
271b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
272b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case R.id.gallery:
273b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                MenuHelper.gotoCameraVideoGallery(this);
274b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
275b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
276b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case R.id.attach:
277b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                doReturnToCaller(true);
278b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
279b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
280b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case R.id.cancel:
281b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                doReturnToCaller(false);
282b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
283b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
284b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case R.id.discard: {
2857638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen                Runnable deleteCallback = new Runnable() {
2867638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen                    public void run() {
2877638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen                        discardCurrentVideoAndStartPreview();
2887638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen                    }
2897638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen                };
2907638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen                MenuHelper.deleteVideo(this, deleteCallback);
291b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
292b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
293b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
294b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case R.id.share: {
295e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project                startShareVideoActivity();
296b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
297b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
298b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
299b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case R.id.play: {
300b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                doPlayCurrentVideo();
301b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
302b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
303de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
304de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            case R.id.last_picture_button: {
3059bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                stopVideoRecordingAndShowAlert();
306de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                break;
307de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            }
308b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
309b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
310b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
311b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void onShutterButtonFocus(ShutterButton button, boolean pressed) {
312de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        // Do nothing (everything happens in onShutterButtonClick).
313de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project    }
314de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
315de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project    public void onShutterButtonClick(ShutterButton button) {
316b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        switch (button.getId()) {
317b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case R.id.shutter_button:
318de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                if (mMediaRecorderRecording) {
3199bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                    if (mIsVideoCaptureIntent) {
320de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                        stopVideoRecordingAndShowAlert();
321b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    } else {
3229bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                        stopVideoRecordingAndGetThumbnail();
3239bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                        initializeVideo();
3249bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                    }
3259bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                } else if (isAlertVisible()) {
3269bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                    if (mIsVideoCaptureIntent) {
3279bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                        discardCurrentVideoAndStartPreview();
3289bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                    } else {
3299bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                        hideAlertAndStartVideoRecording();
330b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    }
331de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                } else {
332de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                    startVideoRecording();
333b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
334b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
335b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
336b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
337b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
338b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void doPlayCurrentVideo() {
339b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Log.e(TAG, "Playing current video: " + mCurrentVideoUri);
340b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Intent intent = new Intent(Intent.ACTION_VIEW, mCurrentVideoUri);
341b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        try {
342b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            startActivity(intent);
343b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } catch (android.content.ActivityNotFoundException ex) {
344b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Log.e(TAG, "Couldn't view video " + mCurrentVideoUri, ex);
345b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
346b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
347b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
348b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void discardCurrentVideoAndStartPreview() {
349b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        deleteCurrentVideo();
3509bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        hideAlertAndStartPreview();
351b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
352b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
353b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private OnScreenHint mStorageHint;
354b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
3559a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project    private void updateAndShowStorageHint(boolean mayHaveSd) {
3569a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        mStorageStatus = getStorageStatus(mayHaveSd);
3579a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        showStorageHint();
3589a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project    }
3599a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project
3609a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project    private void showStorageHint() {
361b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        String errorMessage = null;
3629a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        switch (mStorageStatus) {
3639a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        case STORAGE_STATUS_NONE:
364b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            errorMessage = getString(R.string.no_storage);
3659a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project            break;
3669a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        case STORAGE_STATUS_LOW:
367b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            errorMessage = getString(R.string.spaceIsLow_content);
368b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
369b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (errorMessage != null) {
370b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (mStorageHint == null) {
371b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mStorageHint = OnScreenHint.makeText(this, errorMessage);
372b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } else {
373b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mStorageHint.setText(errorMessage);
374b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
375b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mStorageHint.show();
376b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } else if (mStorageHint != null) {
377b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mStorageHint.cancel();
378b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mStorageHint = null;
379b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
380b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
381b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
3829a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project    private int getStorageStatus(boolean mayHaveSd) {
3839a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        long remaining = mayHaveSd ? getAvailableStorage() : NO_STORAGE_ERROR;
3849a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        if (remaining == NO_STORAGE_ERROR) {
3859a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project            return STORAGE_STATUS_NONE;
3869a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        }
3879a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        return remaining < LOW_STORAGE_THRESHOLD
3889a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project                ? STORAGE_STATUS_LOW : STORAGE_STATUS_OK;
3899a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project    }
3909a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project
391b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
392b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void onResume() {
393b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        super.onResume();
394b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
395b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        setScreenTimeoutLong();
396b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
397b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mPausing = false;
398b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
399b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // install an intent filter to receive SD card related events.
400d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        IntentFilter intentFilter =
401d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                new IntentFilter(Intent.ACTION_MEDIA_MOUNTED);
402b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        intentFilter.addAction(Intent.ACTION_MEDIA_EJECT);
403b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
404b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED);
405b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
406b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        intentFilter.addDataScheme("file");
407b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        registerReceiver(mReceiver, intentFilter);
4089a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        mStorageStatus = getStorageStatus(true);
4099a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project
4109a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        mHandler.postDelayed(new Runnable() {
4119a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project            public void run() {
4129a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project                showStorageHint();
4139a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project            }
4149a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        }, 200);
415b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
4169bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        initializeVideo();
417b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
418b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
419b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
420b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void onStop() {
421b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        setScreenTimeoutSystemDefault();
422b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        super.onStop();
423b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
424b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
425b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
426b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    protected void onPause() {
427b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        super.onPause();
428b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
4299bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        // This is similar to what mShutterButton.performClick() does,
4309bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        // but not quite the same.
4319bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (mMediaRecorderRecording) {
4329bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            if (mIsVideoCaptureIntent) {
4339bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                stopVideoRecordingAndShowAlert();
4349bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            } else {
4359bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                stopVideoRecordingAndGetThumbnail();
4369bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            }
4379bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        } else {
4389bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            stopVideoRecording();
4399bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        }
440b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
441b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mPausing = true;
442b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
4439c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project        unregisterReceiver(mReceiver);
444b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        setScreenTimeoutSystemDefault();
445b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
4469bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (!mIsVideoCaptureIntent) {
4479bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mThumbController.storeData(ImageManager.getLastVideoThumbPath());
4489bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        }
449095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin
450b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mStorageHint != null) {
451b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mStorageHint.cancel();
452b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mStorageHint = null;
453b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
454b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
455b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
456b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
457b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public boolean onKeyDown(int keyCode, KeyEvent event) {
458b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        setScreenTimeoutLong();
459b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
460b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        switch (keyCode) {
461b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case KeyEvent.KEYCODE_BACK:
462b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                if (mMediaRecorderRecording) {
463de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                    mShutterButton.performClick();
464b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    return true;
465d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                } else if (isAlertVisible()) {
4669bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                    hideAlertAndStartPreview();
467b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    return true;
468b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
469b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
470b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case KeyEvent.KEYCODE_CAMERA:
471b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                if (event.getRepeatCount() == 0) {
472de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                    mShutterButton.performClick();
473b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    return true;
474b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
475de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                break;
476b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case KeyEvent.KEYCODE_DPAD_CENTER:
477b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                if (event.getRepeatCount() == 0) {
478de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                    mShutterButton.performClick();
479de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                    return true;
480b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
481b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
482b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case KeyEvent.KEYCODE_MENU:
483b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                if (mMediaRecorderRecording) {
484de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                    mShutterButton.performClick();
485b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    return true;
486b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
487b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
488b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
489b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
490b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return super.onKeyDown(keyCode, event);
491b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
492b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
493b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
494b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public boolean onKeyUp(int keyCode, KeyEvent event) {
495b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        switch(keyCode) {
496b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        case KeyEvent.KEYCODE_CAMERA:
497b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mShutterButton.setPressed(false);
498b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            return true;
499b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
500b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return super.onKeyUp(keyCode, event);
501b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
502b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
503b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
504314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber        if (mPausing) {
505314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber            // We're pausing, the screen is off and we already stopped
506314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber            // video recording. We don't want to start the camera again
507314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber            // in this case in order to conserve power.
508314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber            // The fact that surfaceChanged is called _after_ an onPause appears
509314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber            // to be legitimate since in that case the lockscreen always returns
510314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber            // to portrait orientation possibly triggering the notification.
511314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber            return;
512314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber        }
513314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber
514b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        stopVideoRecording();
515b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        initializeVideo();
516b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
517b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
518b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void surfaceCreated(SurfaceHolder holder) {
519b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mSurfaceHolder = holder;
520b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
521b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
522b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void surfaceDestroyed(SurfaceHolder holder) {
523b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mSurfaceHolder = null;
524b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
525b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
526b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    void gotoGallery() {
527b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        MenuHelper.gotoCameraVideoGallery(this);
528b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
529b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
530b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
531b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public boolean onPrepareOptionsMenu(Menu menu) {
532b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        super.onPrepareOptionsMenu(menu);
533b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
534b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        for (int i = 1; i <= MenuHelper.MENU_ITEM_MAX; i++) {
535b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (i != MenuHelper.GENERIC_ITEM) {
536b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                menu.setGroupVisible(i, false);
537b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
538b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
539b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
540b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        menu.setGroupVisible(MenuHelper.VIDEO_MODE_ITEM, true);
541b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return true;
542b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
543b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
544b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
545b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public boolean onCreateOptionsMenu(Menu menu) {
546b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        super.onCreateOptionsMenu(menu);
547b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
5489bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (mIsVideoCaptureIntent) {
549b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // No options menu for attach mode.
550b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            return false;
551b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } else {
552b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            addBaseMenuItems(menu);
553d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang            int menuFlags = MenuHelper.INCLUDE_ALL
554d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                    & ~MenuHelper.INCLUDE_ROTATE_MENU
555095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin                    & ~MenuHelper.INCLUDE_DETAILS_MENU;
556b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            MenuHelper.addImageMenuItems(
557b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    menu,
558095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin                    menuFlags,
559b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    false,
560b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    VideoCamera.this,
56123c51b794e95c201290e36737f379c4bb8eefeaeRay Chen                    mHandler,
562b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    // Handler for deletion
563b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    new Runnable() {
564b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        public void run() {
565b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            // What do we do here?
566b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            // mContentResolver.delete(uri, null, null);
567b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        }
568b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    },
569b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    new MenuHelper.MenuInvoker() {
570b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        public void run(final MenuHelper.MenuCallback cb) {
571b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        }
572b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    });
573b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
574d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang            MenuItem gallery = menu.add(MenuHelper.IMAGE_SAVING_ITEM,
575d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                    MENU_SAVE_GALLERY_PHOTO, 0,
576d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                    R.string.camera_gallery_photos_text)
577d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                    .setOnMenuItemClickListener(
578d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                    new MenuItem.OnMenuItemClickListener() {
579d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                        public boolean onMenuItemClick(MenuItem item) {
580d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                            gotoGallery();
581d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                            return true;
582d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                        }
583d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                    });
584b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            gallery.setIcon(android.R.drawable.ic_menu_gallery);
585b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
586b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return true;
587b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
588b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
589b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private boolean isVideoCaptureIntent() {
590b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        String action = getIntent().getAction();
591b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return (MediaStore.ACTION_VIDEO_CAPTURE.equals(action));
592b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
593b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
594b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void doReturnToCaller(boolean success) {
595b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Intent resultIntent = new Intent();
596b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        int resultCode;
597b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (success) {
598b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            resultCode = RESULT_OK;
599b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            resultIntent.setData(mCurrentVideoUri);
600b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } else {
601b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            resultCode = RESULT_CANCELED;
602b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
603b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        setResult(resultCode, resultIntent);
604b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        finish();
605b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
606b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
607b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    /**
608b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project     * Returns
609b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project     * @return number of bytes available, or an ERROR code.
610b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project     */
611b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static long getAvailableStorage() {
612b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        try {
613b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (!ImageManager.hasStorage()) {
614b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                return NO_STORAGE_ERROR;
615b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } else {
616d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                String storageDirectory = Environment
617d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                        .getExternalStorageDirectory().toString();
618b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                StatFs stat = new StatFs(storageDirectory);
619d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                return ((long) stat.getAvailableBlocks()
620d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                        * (long) stat.getBlockSize());
621b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
62223c51b794e95c201290e36737f379c4bb8eefeaeRay Chen        } catch (RuntimeException ex) {
623b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // if we can't stat the filesystem then we don't know how many
624b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // free bytes exist.  It might be zero but just leave it
625b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // blank since we really don't know.
626b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            return CANNOT_STAT_ERROR;
627b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
628b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
629b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
630b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void cleanupEmptyFile() {
631b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mCameraVideoFilename != null) {
632b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            File f = new File(mCameraVideoFilename);
633b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (f.length() == 0 && f.delete()) {
634b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project              Log.v(TAG, "Empty video file deleted: " + mCameraVideoFilename);
635b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project              mCameraVideoFilename = null;
636b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
637b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
638b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
639b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
6409bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    // initializeVideo() starts preview and prepare media recorder.
641b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    // Returns false if initializeVideo fails
642b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private boolean initializeVideo() {
643b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Log.v(TAG, "initializeVideo");
6449bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang
6459bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        // We will call initializeVideo() again when the alert is hidden.
64623c51b794e95c201290e36737f379c4bb8eefeaeRay Chen        if (isAlertVisible()) {
64723c51b794e95c201290e36737f379c4bb8eefeaeRay Chen            return false;
64823c51b794e95c201290e36737f379c4bb8eefeaeRay Chen        }
6499bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang
650b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Intent intent = getIntent();
651b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Bundle myExtras = intent.getExtras();
652b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
6539bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (mIsVideoCaptureIntent && myExtras != null) {
654b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Uri saveUri = (Uri) myExtras.getParcelable(MediaStore.EXTRA_OUTPUT);
655b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (saveUri != null) {
656b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                try {
657b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    mCameraVideoFileDescriptor = mContentResolver.
658b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        openFileDescriptor(saveUri, "rw").getFileDescriptor();
659b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    mCurrentVideoUri = saveUri;
660d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                } catch (java.io.FileNotFoundException ex) {
661b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    // invalid uri
662b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    Log.e(TAG, ex.toString());
663b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
664b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
665b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
666b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        releaseMediaRecorder();
667b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
668b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mSurfaceHolder == null) {
669b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Log.v(TAG, "SurfaceHolder is null");
670b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            return false;
671b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
672b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
673b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mMediaRecorder = new MediaRecorder();
674b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
675d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
676b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
677b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
678b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
6798d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project        mMediaRecorder.setMaxDuration(MAX_RECORDING_DURATION_MS);
6808d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project
6819a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        if (mStorageStatus != STORAGE_STATUS_OK) {
682b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mMediaRecorder.setOutputFile("/dev/null");
683b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } else {
684d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang            // We try Uri in intent first. If it doesn't work, use our own
685d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang            // instead.
686b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (mCameraVideoFileDescriptor != null) {
687b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mMediaRecorder.setOutputFile(mCameraVideoFileDescriptor);
688b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } else {
689b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                createVideoPath();
690b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mMediaRecorder.setOutputFile(mCameraVideoFilename);
691b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
692b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
693b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
694d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        boolean videoQualityHigh = getBooleanPreference(
695d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                CameraSettings.KEY_VIDEO_QUALITY,
696b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                CameraSettings.DEFAULT_VIDEO_QUALITY_VALUE);
697b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
698b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (intent.hasExtra(MediaStore.EXTRA_VIDEO_QUALITY)) {
699d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang            int extraVideoQuality = intent.getIntExtra(
700d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                    MediaStore.EXTRA_VIDEO_QUALITY, 0);
701b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            videoQualityHigh = (extraVideoQuality > 0);
702b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
703b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
704b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // Use the same frame rate for both, since internally
705b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // if the frame rate is too large, it can cause camera to become
706b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // unstable. We need to fix the MediaRecorder to disable the support
707b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // of setting frame rate for now.
708b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mMediaRecorder.setVideoFrameRate(20);
709b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (videoQualityHigh) {
710d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang            mMediaRecorder.setVideoSize(352, 288);
711b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } else {
712d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang            mMediaRecorder.setVideoSize(176, 144);
713b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
714b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
715d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
716b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
717de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
718de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        long remaining = getAvailableStorage();
719de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        // remaining >= LOW_STORAGE_THRESHOLD at this point, reserve a quarter
720d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        // of that to make it more likely that recording can complete
721d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        // successfully.
722de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        try {
723d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang            mMediaRecorder.setMaxFileSize(remaining -
724d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                    LOW_STORAGE_THRESHOLD / 4);
725de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        } catch (RuntimeException exception) {
726de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            // We are going to ignore failure of setMaxFileSize here, as
727de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            // a) The composer selected may simply not support it, or
728de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            // b) The underlying media framework may not handle 64-bit range
729de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            //    on the size restriction.
730de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        }
731de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
732b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        try {
733b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mMediaRecorder.prepare();
734b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } catch (IOException exception) {
735b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Log.e(TAG, "prepare failed for " + mCameraVideoFilename);
736b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            releaseMediaRecorder();
737b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // TODO: add more exception handling logic here
738b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            return false;
739b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
740b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mMediaRecorderRecording = false;
7419bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang
7429bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (!mIsVideoCaptureIntent && !mThumbController.isUriValid()) {
7439bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            updateLastVideo();
7449bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        }
7459bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang
7469bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (!mIsVideoCaptureIntent) {
7479bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mThumbController.updateDisplayIfNeeded();
7489bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        }
7499bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang
750b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return true;
751b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
752b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
753b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void releaseMediaRecorder() {
754b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Log.v(TAG, "Releasing media recorder.");
755b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mMediaRecorder != null) {
756b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            cleanupEmptyFile();
757b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mMediaRecorder.reset();
758b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mMediaRecorder.release();
759b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mMediaRecorder = null;
760b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
761b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
762b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
763b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private int getIntPreference(String key, int defaultValue) {
764b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        String s = mPreferences.getString(key, "");
765b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        int result = defaultValue;
766b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        try {
767b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            result = Integer.parseInt(s);
768b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } catch (NumberFormatException e) {
769b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // Ignore, result is already the default value.
770b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
771b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return result;
772b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
773b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
774b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private boolean getBooleanPreference(String key, boolean defaultValue) {
775b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return getIntPreference(key, defaultValue ? 1 : 0) != 0;
776b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
777b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
778b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void createVideoPath() {
779b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        long dateTaken = System.currentTimeMillis();
780b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        String title = createName(dateTaken);
781b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        String displayName = title + ".3gp"; // Used when emailing.
782b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        String cameraDirPath = ImageManager.CAMERA_IMAGE_BUCKET_NAME;
783b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        File cameraDir = new File(cameraDirPath);
784b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        cameraDir.mkdirs();
785b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        SimpleDateFormat dateFormat = new SimpleDateFormat(
786b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                getString(R.string.video_file_name_format));
787b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Date date = new Date(dateTaken);
788b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        String filepart = dateFormat.format(date);
789b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        String filename = cameraDirPath + "/" + filepart + ".3gp";
790b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        ContentValues values = new ContentValues(7);
791b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        values.put(Video.Media.TITLE, title);
792b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        values.put(Video.Media.DISPLAY_NAME, displayName);
793b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        values.put(Video.Media.DESCRIPTION, "");
794b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        values.put(Video.Media.DATE_TAKEN, dateTaken);
795b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        values.put(Video.Media.MIME_TYPE, "video/3gpp");
796b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        values.put(Video.Media.DATA, filename);
797b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mCameraVideoFilename = filename;
798b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Log.v(TAG, "Current camera video filename: " + mCameraVideoFilename);
799b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mCurrentVideoValues = values;
800b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
801b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
802b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void registerVideo() {
803b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mCameraVideoFileDescriptor == null) {
804b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Uri videoTable = Uri.parse("content://media/external/video/media");
805b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mCurrentVideoUri = mContentResolver.insert(videoTable,
806b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    mCurrentVideoValues);
807b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Log.v(TAG, "Current video URI: " + mCurrentVideoUri);
808b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
809b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mCurrentVideoValues = null;
810b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
811b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
812b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void deleteCurrentVideo() {
813b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mCurrentVideoFilename != null) {
814b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            deleteVideoFile(mCurrentVideoFilename);
815b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mCurrentVideoFilename = null;
816b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
817b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mCurrentVideoUri != null) {
818b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mContentResolver.delete(mCurrentVideoUri, null, null);
819b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mCurrentVideoUri = null;
820b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
821de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        updateAndShowStorageHint(true);
822b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
823b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
824b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void deleteVideoFile(String fileName) {
825b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Log.v(TAG, "Deleting video " + fileName);
826b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        File f = new File(fileName);
827d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        if (!f.delete()) {
828b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Log.v(TAG, "Could not delete " + fileName);
829b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
830b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
831b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
832b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void addBaseMenuItems(Menu menu) {
833b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        MenuHelper.addSwitchModeMenuItem(menu, this, false);
834b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        {
835d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang            MenuItem gallery = menu.add(MenuHelper.IMAGE_MODE_ITEM,
836d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                    MENU_GALLERY_PHOTOS, 0, R.string.camera_gallery_photos_text)
837d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                    .setOnMenuItemClickListener(new OnMenuItemClickListener() {
838d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                        public boolean onMenuItemClick(MenuItem item) {
839d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                            gotoGallery();
840d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                            return true;
841d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                        }
842d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                    });
843b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            gallery.setIcon(android.R.drawable.ic_menu_gallery);
844b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mGalleryItems.add(gallery);
845b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
846b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        {
847d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang            MenuItem gallery = menu.add(MenuHelper.VIDEO_MODE_ITEM,
848d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                    MENU_GALLERY_VIDEOS, 0, R.string.camera_gallery_photos_text)
849d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                    .setOnMenuItemClickListener(new OnMenuItemClickListener() {
850d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                        public boolean onMenuItemClick(MenuItem item) {
851d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                            gotoGallery();
852d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                            return true;
853d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                        }
854d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                    });
855b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            gallery.setIcon(android.R.drawable.ic_menu_gallery);
856b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mGalleryItems.add(gallery);
857b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
858b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
859d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        MenuItem item = menu.add(MenuHelper.GENERIC_ITEM, MENU_SETTINGS, 0,
860d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                R.string.settings)
861d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                .setOnMenuItemClickListener(new OnMenuItemClickListener() {
862d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                    public boolean onMenuItemClick(MenuItem item) {
863d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                        Intent intent = new Intent();
864d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                        intent.setClass(VideoCamera.this, CameraSettings.class);
865d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                        startActivity(intent);
866d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                        return true;
867d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                    }
868d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                });
869b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        item.setIcon(android.R.drawable.ic_menu_preferences);
870b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
871b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
872b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    // from MediaRecorder.OnErrorListener
873b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void onError(MediaRecorder mr, int what, int extra) {
874b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (what == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) {
875b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // We may have run out of space on the sdcard.
876b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            stopVideoRecording();
8779a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project            updateAndShowStorageHint(true);
878b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
879b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
880b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
8818d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project    // from MediaRecorder.OnInfoListener
8828d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project    public void onInfo(MediaRecorder mr, int what, int extra) {
8838d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project        if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
884de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            mShutterButton.performClick();
885d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        } else if (what
886d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                == MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED) {
887de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            mShutterButton.performClick();
888de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            updateAndShowStorageHint(true);
8898d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project        }
8908d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project    }
8918d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project
8929c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project    /*
8939c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project     * Make sure we're not recording music playing in the background, ask
8949c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project     * the MediaPlaybackService to pause playback.
8959c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project     */
8969c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project    private void pauseAudioPlayback() {
8979c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project        // Shamelessly copied from MediaPlaybackService.java, which
8989c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project        // should be public, but isn't.
8999c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project        Intent i = new Intent("com.android.music.musicservicecommand");
9009c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project        i.putExtra("command", "pause");
9019c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project
9029c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project        sendBroadcast(i);
9039c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project    }
9049c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project
905b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void startVideoRecording() {
906b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Log.v(TAG, "startVideoRecording");
907b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (!mMediaRecorderRecording) {
908b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
9099a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project            if (mStorageStatus != STORAGE_STATUS_OK) {
910b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                Log.v(TAG, "Storage issue, ignore the start request");
911b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                return;
912b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
913b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
914b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // Check mMediaRecorder to see whether it is initialized or not.
915d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang            if (mMediaRecorder == null && initializeVideo() == false) {
916b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                Log.e(TAG, "Initialize video (MediaRecorder) failed.");
917b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                return;
918b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
919b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
9209c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project            pauseAudioPlayback();
9219c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project
922b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            try {
923b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mMediaRecorder.setOnErrorListener(this);
9248d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                mMediaRecorder.setOnInfoListener(this);
925b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mMediaRecorder.start();   // Recording is now started
926b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } catch (RuntimeException e) {
927b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                Log.e(TAG, "Could not start media recorder. ", e);
928b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                return;
929b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
930b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mMediaRecorderRecording = true;
931b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mRecordingStartTime = SystemClock.uptimeMillis();
932b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            updateRecordingIndicator(true);
933b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mRecordingTimeView.setText("");
934b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mRecordingTimeView.setVisibility(View.VISIBLE);
935b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mHandler.sendEmptyMessage(UPDATE_RECORD_TIME);
936b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            setScreenTimeoutInfinite();
937de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            hideLastPictureButton();
938b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
939b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
940b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
941b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void updateRecordingIndicator(boolean showRecording) {
942d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        int drawableId = showRecording
943d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                ? R.drawable.ic_camera_bar_indicator_record
944d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                : R.drawable.ic_camera_indicator_video;
945b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Drawable drawable = getResources().getDrawable(drawableId);
946b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mShutterButton.setImageDrawable(drawable);
947b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
948b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
9499bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private void stopVideoRecordingAndGetThumbnail() {
9509bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        stopVideoRecording();
9519bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        acquireVideoThumb();
952b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
953b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
954de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project    private void stopVideoRecordingAndShowAlert() {
955de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        stopVideoRecording();
9569bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        showAlert();
957de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project    }
958de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
9599bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private void showAlert() {
960b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        int[] pickIds = {R.id.attach, R.id.cancel};
961b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        int[] normalIds = {R.id.gallery, R.id.share, R.id.discard};
962b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        int[] alwaysOnIds = {R.id.play};
963b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        int[] hideIds = pickIds;
964b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        int[] connectIds = normalIds;
9659bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (mIsVideoCaptureIntent) {
966b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            hideIds = normalIds;
967b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            connectIds = pickIds;
968b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
969d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        for (int id : hideIds) {
970b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mPostPictureAlert.findViewById(id).setVisibility(View.GONE);
971b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
9728d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project        ActionMenuButton shareButton =
9738d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                (ActionMenuButton) mPostPictureAlert.findViewById(R.id.share);
9748d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project        shareButton.setRestricted(
9758d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                mCurrentVideoFileLength > SHARE_FILE_LENGTH_LIMIT);
976b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        connectAndFadeIn(connectIds);
977b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        connectAndFadeIn(alwaysOnIds);
978de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        hideLastPictureButton();
979b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mPostPictureAlert.setVisibility(View.VISIBLE);
9809bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang
9819bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        // There are two cases we are here:
9829bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        // (1) We are in a capture video intent, and we are reviewing the video
983095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin        //     we just taken.
9849bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        // (2) The thumbnail button is clicked: we review the video associated
9859bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        //     with the thumbnail.
9869bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        // For the second case, we copy the associated URI and filename to
9879bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        // mCurrentVideoUri and mCurrentVideoFilename, so the video frame shown
9889bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        // and the target for actions (play, delete, ...) will be correct.
9899bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang
9909bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (!mIsVideoCaptureIntent) {
9919bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mCurrentVideoUri = mThumbController.getUri();
9929bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mCurrentVideoFilename = getDataPath(mCurrentVideoUri);
9939bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        }
9949bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang
9959bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        String path = mCurrentVideoFilename;
9969bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (path != null) {
997101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin            Bitmap videoFrame = Util.createVideoThumbnail(path);
9989bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mVideoFrame.setImageBitmap(videoFrame);
9999bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mVideoFrame.setVisibility(View.VISIBLE);
10009bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        }
1001b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1002b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
10039bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private void hideAlert() {
1004de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        mVideoFrame.setVisibility(View.INVISIBLE);
1005de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        mPostPictureAlert.setVisibility(View.INVISIBLE);
1006de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        showLastPictureButton();
1007de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project    }
1008de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
1009b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void connectAndFadeIn(int[] connectIds) {
1010d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        for (int id : connectIds) {
1011b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            View view = mPostPictureAlert.findViewById(id);
1012b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            view.setOnClickListener(this);
1013b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Animation animation = new AlphaAnimation(0F, 1F);
1014b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            animation.setDuration(500);
10159bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            view.startAnimation(animation);
1016b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1017b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1018b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
10199bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private boolean isAlertVisible() {
1020b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return mPostPictureAlert.getVisibility() == View.VISIBLE;
1021b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1022b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1023b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void stopVideoRecording() {
1024b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Log.v(TAG, "stopVideoRecording");
1025b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        boolean needToRegisterRecording = false;
1026b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mMediaRecorderRecording || mMediaRecorder != null) {
1027b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (mMediaRecorderRecording && mMediaRecorder != null) {
1028b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                try {
1029b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    mMediaRecorder.setOnErrorListener(null);
10308d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                    mMediaRecorder.setOnInfoListener(null);
1031b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    mMediaRecorder.stop();
1032b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                } catch (RuntimeException e) {
1033b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    Log.e(TAG, "stop fail: " + e.getMessage());
1034b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
10358d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project
1036b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mCurrentVideoFilename = mCameraVideoFilename;
10378d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                try {
1038d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                    mCurrentVideoFileLength =
1039d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                            new File(mCurrentVideoFilename).length();
10408d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                } catch (RuntimeException e) {
10418d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                    Log.e(TAG, "get file length fail: " + e.getMessage());
10428d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                    mCurrentVideoFileLength = 0;
10438d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project                }
1044d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                Log.v(TAG, "Setting current video filename: "
1045d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                        + mCurrentVideoFilename);
1046b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                needToRegisterRecording = true;
1047b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mMediaRecorderRecording = false;
1048b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
1049b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            releaseMediaRecorder();
1050b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            updateRecordingIndicator(false);
1051b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mRecordingTimeView.setVisibility(View.GONE);
1052b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            setScreenTimeoutLong();
1053b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
10549a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        if (needToRegisterRecording && mStorageStatus == STORAGE_STATUS_OK) {
10559a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project            registerVideo();
10569a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        }
1057b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1058b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mCameraVideoFilename = null;
1059b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mCameraVideoFileDescriptor = null;
1060b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1061b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1062b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void setScreenTimeoutSystemDefault() {
1063b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mHandler.removeMessages(CLEAR_SCREEN_DELAY);
1064b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        clearScreenOnFlag();
1065b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1066b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1067b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void setScreenTimeoutLong() {
1068b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mHandler.removeMessages(CLEAR_SCREEN_DELAY);
1069b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        setScreenOnFlag();
1070b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mHandler.sendEmptyMessageDelayed(CLEAR_SCREEN_DELAY, SCREEN_DELAY);
1071b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1072b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1073b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void setScreenTimeoutInfinite() {
1074b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mHandler.removeMessages(CLEAR_SCREEN_DELAY);
1075b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        setScreenOnFlag();
1076b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1077b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1078b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void clearScreenOnFlag() {
1079b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Window w = getWindow();
1080d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        final int flag = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
1081d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        if ((w.getAttributes().flags & flag) != 0) {
1082d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang            w.clearFlags(flag);
1083b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1084b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1085b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1086b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void setScreenOnFlag() {
1087b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Window w = getWindow();
1088d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        final int flag = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
1089d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        if ((w.getAttributes().flags & flag) == 0) {
1090d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang            w.addFlags(flag);
1091b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1092b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1093b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
10949bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private void hideAlertAndStartPreview() {
10959bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        hideAlert();
10969bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        initializeVideo();
1097b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1098b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
10999bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private void hideAlertAndStartVideoRecording() {
11009bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        hideAlert();
11019bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        startVideoRecording();
1102b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1103b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
11049bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private void acquireVideoThumb() {
1105101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin        Bitmap videoFrame = Util.createVideoThumbnail(mCurrentVideoFilename);
11069bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        mThumbController.setData(mCurrentVideoUri, videoFrame);
1107de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project    }
1108de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
11099bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private void showLastPictureButton() {
11109bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (!mIsVideoCaptureIntent) {
11119bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mLastPictureButton.setVisibility(View.VISIBLE);
1112de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        }
11139bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    }
1114de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
11159bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private void hideLastPictureButton() {
11169bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (!mIsVideoCaptureIntent) {
11179bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mLastPictureButton.setVisibility(View.INVISIBLE);
11189bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        }
1119de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project    }
1120de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
11219bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private static ImageManager.DataLocation dataLocation() {
11229bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        return ImageManager.DataLocation.EXTERNAL;
1123de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project    }
1124de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
11259bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private void updateLastVideo() {
1126101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin        IImageList list = ImageManager.instance().allImages(
11279bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            this,
11289bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mContentResolver,
11299bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            dataLocation(),
11309bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            ImageManager.INCLUDE_VIDEOS,
11319bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            ImageManager.SORT_ASCENDING,
11329bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            ImageManager.CAMERA_IMAGE_BUCKET_ID);
11339bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        int count = list.getCount();
11349bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (count > 0) {
1135d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang            IImage image = list.getImageAt(count - 1);
11369bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            Uri uri = image.fullSizeImageUri();
11379bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mThumbController.setData(uri, image.miniThumbBitmap());
11389bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        } else {
11399bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mThumbController.setData(null, null);
11409bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        }
11419bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        list.deactivate();
1142b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1143b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
11449bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private static final String[] DATA_PATH_PROJECTION = new String[] {
11459bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        "_data"
11469bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    };
11479bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang
11489bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private String getDataPath(Uri uri) {
11499bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        Cursor c = null;
11509bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        try {
1151d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang            c = mContentResolver.query(uri, DATA_PATH_PROJECTION, null, null,
1152d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                    null);
11539bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            if (c != null && c.moveToFirst()) {
11549bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                return c.getString(0);
11559bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            } else {
11569bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                return null;
11579bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            }
11589bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        } finally {
115923c51b794e95c201290e36737f379c4bb8eefeaeRay Chen            if (c != null) {
116023c51b794e95c201290e36737f379c4bb8eefeaeRay Chen                c.close();
116123c51b794e95c201290e36737f379c4bb8eefeaeRay Chen            }
1162b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1163b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1164d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang
1165d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang    private void updateRecordingTime() {
116623c51b794e95c201290e36737f379c4bb8eefeaeRay Chen        if (!mMediaRecorderRecording) {
116723c51b794e95c201290e36737f379c4bb8eefeaeRay Chen            return;
116823c51b794e95c201290e36737f379c4bb8eefeaeRay Chen        }
1169d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        long now = SystemClock.uptimeMillis();
1170d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        long delta = now - mRecordingStartTime;
1171d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang
1172d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        // Starting a minute before reaching the max duration
1173d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        // limit, we'll countdown the remaining time instead.
1174d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        boolean countdownRemainingTime =
1175d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang            (delta >= MAX_RECORDING_DURATION_MS - 60000);
1176d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang
1177d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        if (countdownRemainingTime) {
1178d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang            delta = Math.max(0, MAX_RECORDING_DURATION_MS - delta);
1179d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        }
1180d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang
1181d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        long seconds = (delta + 500) / 1000;  // round to nearest
1182d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        long minutes = seconds / 60;
1183d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        long hours = minutes / 60;
1184d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        long remainderMinutes = minutes - (hours * 60);
1185d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        long remainderSeconds = seconds - (minutes * 60);
1186d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang
1187d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        String secondsString = Long.toString(remainderSeconds);
1188d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        if (secondsString.length() < 2) {
1189d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang            secondsString = "0" + secondsString;
1190d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        }
1191d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        String minutesString = Long.toString(remainderMinutes);
1192d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        if (minutesString.length() < 2) {
1193d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang            minutesString = "0" + minutesString;
1194d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        }
1195d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        String text = minutesString + ":" + secondsString;
1196d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        if (hours > 0) {
1197d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang            String hoursString = Long.toString(hours);
1198d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang            if (hoursString.length() < 2) {
1199d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                hoursString = "0" + hoursString;
1200d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang            }
1201d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang            text = hoursString + ":" + text;
1202d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        }
1203d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        mRecordingTimeView.setText(text);
1204d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang
1205d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        if (mRecordingTimeCountsDown != countdownRemainingTime) {
1206d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang            // Avoid setting the color on every update, do it only
1207d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang            // when it needs changing.
1208d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang
1209d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang            mRecordingTimeCountsDown = countdownRemainingTime;
1210d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang
1211d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang            int color = getResources().getColor(
1212d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                    countdownRemainingTime
1213d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                    ? R.color.recording_time_remaining_text
1214d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang                    : R.color.recording_time_elapsed_text);
1215d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang
1216d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang            mRecordingTimeView.setTextColor(color);
1217d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        }
1218d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang
1219d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        // Work around a limitation of the T-Mobile G1: The T-Mobile
1220d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        // hardware blitter can't pixel-accurately scale and clip at the
1221d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        // same time, and the SurfaceFlinger doesn't attempt to work around
1222d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        // this limitation. In order to avoid visual corruption we must
1223d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        // manually refresh the entire surface view when changing any
1224d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        // overlapping view's contents.
1225d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        mVideoPreview.invalidate();
1226d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang        mHandler.sendEmptyMessageDelayed(UPDATE_RECORD_TIME, 1000);
1227d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang    }
1228b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project}
1229