Camera.java revision 9bc8d1b47e5bab978cc9571ddfdedc8309a0b65d
1b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project/*
2b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project *
4b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * you may not use this file except in compliance with the License.
6b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * You may obtain a copy of the License at
7b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project *
8b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project *
10b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * See the License for the specific language governing permissions and
14b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * limitations under the License.
15b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project */
16b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
17b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectpackage com.android.camera;
18b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
19b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.io.File;
20b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.io.FileNotFoundException;
21b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.io.FileOutputStream;
22b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.io.IOException;
23b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.io.OutputStream;
24b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.util.ArrayList;
25b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
26b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.app.Activity;
27b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.BroadcastReceiver;
28b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.ContentResolver;
29b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.Context;
30b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.Intent;
31b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.IntentFilter;
32b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.SharedPreferences;
33b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.pm.ActivityInfo;
34b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.res.AssetFileDescriptor;
35b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.graphics.Bitmap;
36b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.graphics.BitmapFactory;
37b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.graphics.Matrix;
38b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.graphics.drawable.Drawable;
39b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.hardware.Camera.PictureCallback;
40b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.hardware.Camera.Size;
41b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.location.Location;
42b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.location.LocationManager;
43b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.location.LocationProvider;
44b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.media.AudioManager;
45b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.media.MediaPlayer;
46b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.media.ToneGenerator;
47b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.net.Uri;
48b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Bundle;
49b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Debug;
50b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Environment;
51b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Handler;
52b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Message;
53b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.SystemClock;
54b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.preference.PreferenceManager;
55b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.provider.MediaStore;
56b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.text.format.DateFormat;
57b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.util.Config;
58b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.util.Log;
59b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.KeyEvent;
60b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.Menu;
61b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.MenuItem;
62b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.MenuItem.OnMenuItemClickListener;
63b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.OrientationEventListener;
64b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.SurfaceHolder;
65b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.View;
66b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.ViewGroup;
67b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.Window;
68b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.WindowManager;
69b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.animation.AlphaAnimation;
70b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.animation.Animation;
71b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.animation.AnimationUtils;
72b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.widget.ImageView;
73b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.widget.Toast;
74b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
75b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectpublic class Camera extends Activity implements View.OnClickListener,
76b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    ShutterButton.OnShutterButtonListener, SurfaceHolder.Callback {
77b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
78b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final String TAG = "camera";
79b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
80b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final boolean DEBUG = false;
81b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final boolean DEBUG_TIME_OPERATIONS = DEBUG && false;
82b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
83b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final int CROP_MSG = 1;
84b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final int RESTART_PREVIEW = 3;
85b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final int CLEAR_SCREEN_DELAY = 4;
86b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
87b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final int SCREEN_DELAY = 2 * 60 * 1000;
88b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final int FOCUS_BEEP_VOLUME = 100;
89b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
90b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_SWITCH_TO_VIDEO = 0;
91b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_SWITCH_TO_CAMERA = 1;
92b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_FLASH_SETTING = 2;
93b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_FLASH_AUTO = 3;
94b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_FLASH_ON = 4;
95b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_FLASH_OFF = 5;
96b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_SETTINGS = 6;
97b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_GALLERY_PHOTOS = 7;
98b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_GALLERY_VIDEOS = 8;
99b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_SAVE_SELECT_PHOTOS = 30;
100b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_SAVE_NEW_PHOTO = 31;
101b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_SAVE_GALLERY_PHOTO = 34;
102b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_SAVE_GALLERY_VIDEO_PHOTO = 35;
103b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_SAVE_CAMERA_DONE = 36;
104b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public static final int MENU_SAVE_CAMERA_VIDEO_DONE = 37;
105b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
106b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private OrientationEventListener mOrientationListener;
107b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private int mLastOrientation = OrientationEventListener.ORIENTATION_UNKNOWN;
108b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private SharedPreferences mPreferences;
109b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
110b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final int IDLE = 1;
111b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final int SNAPSHOT_IN_PROGRESS = 2;
112b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final int SNAPSHOT_COMPLETED = 3;
113b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
114b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private int mStatus = IDLE;
115b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static final String sTempCropFilename = "crop-temp";
116b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
117b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private android.hardware.Camera mCameraDevice;
118b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private android.hardware.Camera.Parameters mParameters;
119b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private VideoPreview mSurfaceView;
120b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private SurfaceHolder mSurfaceHolder = null;
121b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
122b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private int mOriginalViewFinderWidth, mOriginalViewFinderHeight;
123b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private int mViewFinderWidth, mViewFinderHeight;
124b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private boolean mPreviewing = false;
125b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
126b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private MediaPlayer mClickSound;
127b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
128b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private Capturer mCaptureObject;
129b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private ImageCapture mImageCapture = null;
130b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
131b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private boolean mPausing = false;
132b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1339c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project    private static final int FOCUS_NOT_STARTED = 0;
1349c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project    private static final int FOCUSING = 1;
1359c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project    private static final int FOCUSING_SNAP_ON_FINISH = 2;
1369c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project    private static final int FOCUS_SUCCESS = 3;
1379c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project    private static final int FOCUS_FAIL = 4;
1389c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project    private int mFocusState = FOCUS_NOT_STARTED;
139b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
140b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private static ContentResolver mContentResolver;
141b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private boolean mDidRegister = false;
142b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
143b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private ArrayList<MenuItem> mGalleryItems = new ArrayList<MenuItem>();
144b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
145b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private LocationManager mLocationManager = null;
146b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
147b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private ShutterButton mShutterButton;
148b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
149b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private Animation mFocusBlinkAnimation;
150b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private View mFocusIndicator;
151b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private ToneGenerator mFocusToneGenerator;
152b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
153b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
154b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private ShutterCallback mShutterCallback = new ShutterCallback();
155b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private RawPictureCallback mRawPictureCallback = new RawPictureCallback();
156b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private AutoFocusCallback mAutoFocusCallback = new AutoFocusCallback();
157b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private long mFocusStartTime;
158b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private long mFocusCallbackTime;
159b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private long mCaptureStartTime;
160b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private long mShutterCallbackTime;
161b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private long mRawPictureCallbackTime;
162b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private int mPicturesRemaining;
163b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
164b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private boolean mKeepAndRestartPreview;
165b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1669bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private boolean mIsImageCaptureIntent;
1679bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    // mPostCaptureAlert, mLastPictureButton, mThumbController
1689bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    // are non-null only if isImageCaptureIntent() is true.
169b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private View mPostCaptureAlert;
1709bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private ImageView mLastPictureButton;
1719bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private ThumbnailController mThumbController;
172b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
173b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private Handler mHandler = new MainHandler();
174b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
175b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private interface Capturer {
176b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Uri getLastCaptureUri();
177b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        void onSnap();
1789a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        void dismissFreezeFrame();
179b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
180b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
181b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    /** This Handler is used to post message back onto the main thread of the application */
182b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private class MainHandler extends Handler {
183b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        @Override
184b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        public void handleMessage(Message msg) {
185b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            switch (msg.what) {
186b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                case RESTART_PREVIEW: {
187b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    if (mStatus == SNAPSHOT_IN_PROGRESS) {
188b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        // We are still in the processing of taking the picture, wait.
189e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project                        // This is strange.  Why are we polling?
190b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        // TODO remove polling
191b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        mHandler.sendEmptyMessageDelayed(RESTART_PREVIEW, 100);
192b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    } else if (mStatus == SNAPSHOT_COMPLETED){
1939a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project                        mCaptureObject.dismissFreezeFrame();
194b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        hidePostCaptureAlert();
195b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    }
196b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    break;
197b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
198b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
199b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                case CLEAR_SCREEN_DELAY: {
200b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
201b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    break;
202b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
203b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
204b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
205b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    };
206b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
207b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    LocationListener [] mLocationListeners = new LocationListener[] {
208b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            new LocationListener(LocationManager.GPS_PROVIDER),
209b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            new LocationListener(LocationManager.NETWORK_PROVIDER)
210b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    };
211b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
212b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
213b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
214b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        @Override
215b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        public void onReceive(Context context, Intent intent) {
216b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            String action = intent.getAction();
217b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) {
218b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                // SD card available
219b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                updateStorageHint(calculatePicturesRemaining());
220b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } else if (action.equals(Intent.ACTION_MEDIA_UNMOUNTED) ||
221b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    action.equals(Intent.ACTION_MEDIA_CHECKING)) {
222b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                // SD card unavailable
223b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mPicturesRemaining = MenuHelper.NO_STORAGE_ERROR;
224b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                updateStorageHint(mPicturesRemaining);
225b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_STARTED)) {
226b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                Toast.makeText(Camera.this, getResources().getString(R.string.wait), 5000);
227b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) {
228b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                updateStorageHint();
229b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
230b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
231b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    };
232b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
233b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private class LocationListener implements android.location.LocationListener {
234b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Location mLastLocation;
235b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        boolean mValid = false;
236b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        String mProvider;
237b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
238b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        public LocationListener(String provider) {
239b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mProvider = provider;
240b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mLastLocation = new Location(mProvider);
241b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
242b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
243b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        public void onLocationChanged(Location newLocation) {
244b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (newLocation.getLatitude() == 0.0 && newLocation.getLongitude() == 0.0) {
245b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                // Hack to filter out 0.0,0.0 locations
246b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                return;
247b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
248b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mLastLocation.set(newLocation);
249b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mValid = true;
250b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
251b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
252b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        public void onProviderEnabled(String provider) {
253b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
254b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
255b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        public void onProviderDisabled(String provider) {
256b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mValid = false;
257b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
258b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
259b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        public void onStatusChanged(String provider, int status, Bundle extras) {
260b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (status == LocationProvider.OUT_OF_SERVICE) {
261b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mValid = false;
262b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
263b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
264b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
265b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        public Location current() {
266b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            return mValid ? mLastLocation : null;
267b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
268b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    };
269b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
270b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private boolean mImageSavingItem = false;
271b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
272b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private final class ShutterCallback implements android.hardware.Camera.ShutterCallback {
273b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        public void onShutter() {
274b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (DEBUG_TIME_OPERATIONS) {
275b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mShutterCallbackTime = System.currentTimeMillis();
276b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                Log.v(TAG, "Shutter lag was " + (mShutterCallbackTime - mCaptureStartTime) + " ms.");
277b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
278b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
279e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project            // We are going to change the size of surface view and show captured
280de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            // image. Set it to invisible now and set it back to visible in
281e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project            // surfaceChanged() so that users won't see the image is resized on
282e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project            // the screen.
283e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project            mSurfaceView.setVisibility(View.INVISIBLE);
284b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // Resize the SurfaceView to the aspect-ratio of the still image
285b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // and so that we can see the full image that was taken.
286e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project            Size pictureSize = mParameters.getPictureSize();
287b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mSurfaceView.setAspectRatio(pictureSize.width, pictureSize.height);
288e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project
289e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project            if (mClickSound != null) {
290e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project                mClickSound.start();
291e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project            }
292b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
293b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    };
294b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
295b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private final class RawPictureCallback implements PictureCallback {
296b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        public void onPictureTaken(byte [] rawData, android.hardware.Camera camera) {
297b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (Config.LOGV)
298b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                Log.v(TAG, "got RawPictureCallback...");
299b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mRawPictureCallbackTime = System.currentTimeMillis();
300b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (DEBUG_TIME_OPERATIONS) {
301b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                Log.v(TAG, (mRawPictureCallbackTime - mShutterCallbackTime) + "ms elapsed between" +
302b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        " ShutterCallback and RawPictureCallback.");
303b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
304b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
305b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    };
306b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
307b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private final class JpegPictureCallback implements PictureCallback {
308b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Location mLocation;
309b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
310b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        public JpegPictureCallback(Location loc) {
311b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mLocation = loc;
312b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
313b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
314b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        public void onPictureTaken(byte [] jpegData, android.hardware.Camera camera) {
315de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            if (mPausing) {
316e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project                return;
317e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project            }
318b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (Config.LOGV)
319b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                Log.v(TAG, "got JpegPictureCallback...");
320b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
321b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (DEBUG_TIME_OPERATIONS) {
322b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                long mJpegPictureCallback = System.currentTimeMillis();
323b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                Log.v(TAG, (mJpegPictureCallback - mRawPictureCallbackTime) + "ms elapsed between" +
324b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        " RawPictureCallback and JpegPictureCallback.");
325b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
326b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
327de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            if (jpegData != null) {
328de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project                mImageCapture.storeImage(jpegData, camera, mLocation);
329de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            }
330b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
331b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mStatus = SNAPSHOT_COMPLETED;
332b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
333b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (mKeepAndRestartPreview) {
334b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                long delay = 1500 - (System.currentTimeMillis() - mRawPictureCallbackTime);
335b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mHandler.sendEmptyMessageDelayed(RESTART_PREVIEW, Math.max(delay, 0));
336b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
337b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
338b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    };
339b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
340b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private final class AutoFocusCallback implements android.hardware.Camera.AutoFocusCallback {
341b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        public void onAutoFocus(boolean focused, android.hardware.Camera camera) {
342b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (DEBUG_TIME_OPERATIONS) {
343b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mFocusCallbackTime = System.currentTimeMillis();
344b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                Log.v(TAG, "Auto focus took " + (mFocusCallbackTime - mFocusStartTime) + " ms.");
345b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
346b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
3479c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project            if (mFocusState == FOCUSING_SNAP_ON_FINISH && mCaptureObject != null) {
3489c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                // Take the picture no matter focus succeeds or fails.
3499c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                // No need to play the AF sound if we're about to play the shutter sound.
3509c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                mCaptureObject.onSnap();
3519c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                clearFocusState();
3529c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project            } else if (mFocusState == FOCUSING) {
3539c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                // User is half-pressing the focus key. Play the focus tone.
3549c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                // Do not take the picture now.
3559c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                ToneGenerator tg = mFocusToneGenerator;
3569c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                if (tg != null)
3579c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                   tg.startTone(ToneGenerator.TONE_PROP_BEEP2);
3589c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                if (focused) {
3599c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                    mFocusState = FOCUS_SUCCESS;
360b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
3619c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                else {
3629c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                    mFocusState = FOCUS_FAIL;
3639c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                }
3649c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project            } else if (mFocusState == FOCUS_NOT_STARTED) {
3659c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                // User has released the focus key before focus completes.
3669c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                // Do nothing.
367de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            }
368b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            updateFocusIndicator();
369b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
370b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    };
371b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
372b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private class ImageCapture implements Capturer {
373b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
374b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        private boolean mCancel = false;
375b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        private boolean mCapturing = false;
376b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
377b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        private Uri mLastContentUri;
378b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        private ImageManager.IAddImage_cancelable mAddImageCancelable;
379b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
380b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Bitmap mCaptureOnlyBitmap;
381b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
382b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        /** These member variables are used for various debug timings */
383b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        private long mThreadTimeStart;
384b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        private long mThreadTimeEnd;
385b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        private long mWallTimeStart;
386b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        private long mWallTimeEnd;
387b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
388b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
389b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        public ImageCapture() {
390b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
391b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
392b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        /**
393b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project         * This method sets whether or not we are capturing a picture. This method must be called
394b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project         * with the ImageCapture.this lock held.
395b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project         */
396b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        public void setCapturingLocked(boolean capturing) {
397b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mCapturing = capturing;
398b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
399b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
4009a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        public void dismissFreezeFrame() {
401b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (mStatus == SNAPSHOT_IN_PROGRESS) {
402b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                // If we are still in the process of taking a picture, then just post a message.
403b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mHandler.sendEmptyMessage(RESTART_PREVIEW);
404b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } else {
405b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                restartPreview();
406b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
407b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
408b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
409b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        private void startTiming() {
410b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mWallTimeStart = SystemClock.elapsedRealtime();
411b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mThreadTimeStart = Debug.threadCpuTimeNanos();
412b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
413b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
414b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        private void stopTiming() {
415b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mThreadTimeEnd = Debug.threadCpuTimeNanos();
416b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mWallTimeEnd = SystemClock.elapsedRealtime();
417b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
418b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
419b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        private void storeImage(byte[] data, Location loc) {
420b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            try {
421b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                if (DEBUG_TIME_OPERATIONS) {
422b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    startTiming();
423b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
424b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                long dateTaken = System.currentTimeMillis();
425b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                String name = createName(dateTaken) + ".jpg";
426b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mLastContentUri = ImageManager.instance().addImage(
427b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        Camera.this,
428b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        mContentResolver,
429b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        name,
430b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        "",
431b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        dateTaken,
432b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        // location for the database goes here
433b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        loc,
434b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        0,   // the dsp will use the right orientation so don't "double set it"
435b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        ImageManager.CAMERA_IMAGE_BUCKET_NAME,
436b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        name);
437b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
438b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                if (mLastContentUri == null) {
439b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    // this means we got an error
440b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    mCancel = true;
441b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
442b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                if (!mCancel) {
443b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    mAddImageCancelable = ImageManager.instance().storeImage(mLastContentUri,
444b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            Camera.this, mContentResolver, 0, null, data);
445b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    mAddImageCancelable.get();
446b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    mAddImageCancelable = null;
447b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
448b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
449b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                if (DEBUG_TIME_OPERATIONS) {
450b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    stopTiming();
451b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    Log.d(TAG, "Storing image took " + (mWallTimeEnd - mWallTimeStart) + " ms. " +
452b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            "Thread time was " + ((mThreadTimeEnd - mThreadTimeStart) / 1000000) +
453b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            " ms.");
454b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
455b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } catch (Exception ex) {
456b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                Log.e(TAG, "Exception while compressing image.", ex);
457b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
458b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
459b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
460b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        public void storeImage(byte[] data, android.hardware.Camera camera, Location loc) {
4619bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            boolean captureOnly = mIsImageCaptureIntent;
462b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
463b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (!captureOnly) {
464b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                storeImage(data, loc);
465b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                sendBroadcast(new Intent("com.android.camera.NEW_PICTURE", mLastContentUri));
466b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                setLastPictureThumb(data, mCaptureObject.getLastCaptureUri());
4679a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project                dismissFreezeFrame();
468b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } else {
469b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                BitmapFactory.Options options = new BitmapFactory.Options();
470b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                options.inSampleSize = 4;
471b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
472b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                if (DEBUG_TIME_OPERATIONS) {
473b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    startTiming();
474b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
475b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
476b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mCaptureOnlyBitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
477b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
478b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                if (DEBUG_TIME_OPERATIONS) {
479b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    stopTiming();
480b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    Log.d(TAG, "Decoded mCaptureOnly bitmap (" + mCaptureOnlyBitmap.getWidth() +
481b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            "x" + mCaptureOnlyBitmap.getHeight() + " ) in " +
482b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            (mWallTimeEnd - mWallTimeStart) + " ms. Thread time was " +
483b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            ((mThreadTimeEnd - mThreadTimeStart) / 1000000) + " ms.");
484b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
485b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
486b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                showPostCaptureAlert();
487b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                cancelAutomaticPreviewRestart();
488b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
489b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
490b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mCapturing = false;
491b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (mPausing) {
492b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                closeCamera();
493b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
494b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
495b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
496b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        /*
497b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project         * Initiate the capture of an image.
498b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project         */
499b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        public void initiate(boolean captureOnly) {
500b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (mCameraDevice == null) {
501b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                return;
502b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
503b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
504b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mCancel = false;
505b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mCapturing = true;
506b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
507b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            capture(captureOnly);
508b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
509b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
510b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        public Uri getLastCaptureUri() {
511b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            return mLastContentUri;
512b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
513b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
514b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        public Bitmap getLastBitmap() {
515b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            return mCaptureOnlyBitmap;
516b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
517b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
518b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        private void capture(boolean captureOnly) {
519b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mPreviewing = false;
520b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mCaptureOnlyBitmap = null;
521b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
522b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            final int latchedOrientation = ImageManager.roundOrientation(mLastOrientation + 90);
523b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
524b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Boolean recordLocation = mPreferences.getBoolean("pref_camera_recordlocation_key", false);
525b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Location loc = recordLocation ? getCurrentLocation() : null;
526b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // Quality 75 has visible artifacts, and quality 90 looks great but the files begin to
527b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // get large. 85 is a good compromise between the two.
528b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mParameters.set("jpeg-quality", 85);
529b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mParameters.set("rotation", latchedOrientation);
530b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
531b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mParameters.remove("gps-latitude");
532b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mParameters.remove("gps-longitude");
533b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mParameters.remove("gps-altitude");
534b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mParameters.remove("gps-timestamp");
535b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
536b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (loc != null) {
537b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                double lat = loc.getLatitude();
538b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                double lon = loc.getLongitude();
539b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                boolean hasLatLon = (lat != 0.0d) || (lon != 0.0d);
540b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
541b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                if (hasLatLon) {
542b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    String latString = String.valueOf(lat);
543b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    String lonString = String.valueOf(lon);
544b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    mParameters.set("gps-latitude",  latString);
545b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    mParameters.set("gps-longitude", lonString);
546d7e9d1916fbabaecd4be9dacb4472fa3ffe62ed4The Android Open Source Project                    if (loc.hasAltitude()) {
547b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        mParameters.set("gps-altitude",  String.valueOf(loc.getAltitude()));
548d7e9d1916fbabaecd4be9dacb4472fa3ffe62ed4The Android Open Source Project                    } else {
549d7e9d1916fbabaecd4be9dacb4472fa3ffe62ed4The Android Open Source Project                        // for NETWORK_PROVIDER location provider, we may have
550d7e9d1916fbabaecd4be9dacb4472fa3ffe62ed4The Android Open Source Project                        // no altitude information, but the driver needs it, so
551d7e9d1916fbabaecd4be9dacb4472fa3ffe62ed4The Android Open Source Project                        // we fake one.
552d7e9d1916fbabaecd4be9dacb4472fa3ffe62ed4The Android Open Source Project                        mParameters.set("gps-altitude",  "0");
553d7e9d1916fbabaecd4be9dacb4472fa3ffe62ed4The Android Open Source Project                    }
554b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    if (loc.getTime() != 0) {
555b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        // Location.getTime() is UTC in milliseconds.
556b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        // gps-timestamp is UTC in seconds.
557b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        long utcTimeSeconds = loc.getTime() / 1000;
558b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        mParameters.set("gps-timestamp", String.valueOf(utcTimeSeconds));
559b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    }
560b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                } else {
561b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    loc = null;
562b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
563b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
564b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
565b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mCameraDevice.setParameters(mParameters);
566b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
567b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mCameraDevice.takePicture(mShutterCallback, mRawPictureCallback, new JpegPictureCallback(loc));
568b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // Prepare the sound to play in shutter callback.
569b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (mClickSound != null) {
570b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mClickSound.seekTo(0);
571b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
572b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
573b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
574b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        public void onSnap() {
575de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            if (mPausing) {
576e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project                return;
577e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project            }
578b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (DEBUG_TIME_OPERATIONS) mCaptureStartTime = System.currentTimeMillis();
579b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
580b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // If we are already in the middle of taking a snapshot then we should just save
581b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // the image after we have returned from the camera service.
582b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (mStatus == SNAPSHOT_IN_PROGRESS || mStatus == SNAPSHOT_COMPLETED) {
583b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mKeepAndRestartPreview = true;
584b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mHandler.sendEmptyMessage(RESTART_PREVIEW);
585b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                return;
586b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
587b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
588b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // Don't check the filesystem here, we can't afford the latency. Instead, check the
589b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // cached value which was calculated when the preview was restarted.
590b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (mPicturesRemaining < 1) {
591b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                updateStorageHint(mPicturesRemaining);
592b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                return;
593b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
594b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
595b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mStatus = SNAPSHOT_IN_PROGRESS;
596b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
597b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mKeepAndRestartPreview = true;
598b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
5999bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            boolean getContentAction = mIsImageCaptureIntent;
600b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (getContentAction) {
601b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mImageCapture.initiate(true);
602b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } else {
603b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mImageCapture.initiate(false);
604b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
605b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
606de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
6079a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        private void clearLastBitmap() {
6089a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project            if (mCaptureOnlyBitmap != null) {
6099a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project                mCaptureOnlyBitmap.recycle();
6109a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project                mCaptureOnlyBitmap = null;
6119a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project            }
6129a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        }
613b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
614b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
615b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void setLastPictureThumb(byte[] data, Uri uri) {
616b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        BitmapFactory.Options options = new BitmapFactory.Options();
617b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        options.inSampleSize = 16;
618b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Bitmap lastPictureThumb = BitmapFactory.decodeByteArray(data, 0, data.length, options);
6199bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        mThumbController.setData(uri, lastPictureThumb);
620b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
621b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
622b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    static private String createName(long dateTaken) {
623b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return DateFormat.format("yyyy-MM-dd kk.mm.ss", dateTaken).toString();
624b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
625b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
626b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    static public Matrix GetDisplayMatrix(Bitmap b, ImageView v) {
627b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Matrix m = new Matrix();
628b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        float bw = (float)b.getWidth();
629b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        float bh = (float)b.getHeight();
630b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        float vw = (float)v.getWidth();
631b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        float vh = (float)v.getHeight();
632b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        float scale, x, y;
633b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (bw*vh > vw*bh) {
634b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            scale = vh / bh;
635b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            x = (vw - scale*bw)*0.5F;
636b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            y = 0;
637b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } else {
638b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            scale = vw / bw;
639b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            x = 0;
640b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            y = (vh - scale*bh)*0.5F;
641b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
642b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        m.setScale(scale, scale, 0.5F, 0.5F);
643b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        m.postTranslate(x, y);
644b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return m;
645b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
646b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
647b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    /** Called with the activity is first created. */
648b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
649b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void onCreate(Bundle icicle) {
650b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        super.onCreate(icicle);
651b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
652b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // To reduce startup time, we open camera device in another thread.
653b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // We make sure the camera is opened at the end of onCreate.
654b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Thread openCameraThread = new Thread(new Runnable() {
655b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            public void run() {
656b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mCameraDevice = android.hardware.Camera.open();
657b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
658b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        });
659b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        openCameraThread.start();
660b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
661b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // To reduce startup time, we run some service creation code in another thread.
662b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // We make sure the services are loaded at the end of onCreate().
663b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Thread loadServiceThread = new Thread(new Runnable() {
664b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            public void run() {
665b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
666b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mOrientationListener = new OrientationEventListener(Camera.this) {
667b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    public void onOrientationChanged(int orientation) {
6689c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                        // We keep the last known orientation. So if the user
6699c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                        // first orient the camera then point the camera to
6709c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                        // floor/sky, we still have the correct orientation.
6719c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                        if (orientation != ORIENTATION_UNKNOWN)
6729c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                            mLastOrientation = orientation;
673b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    }
674b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                };
675b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
676b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        });
677b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        loadServiceThread.start();
678b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
679b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mPreferences = PreferenceManager.getDefaultSharedPreferences(this);
680b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mContentResolver = getContentResolver();
681b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
682b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Window win = getWindow();
683b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
684b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        setContentView(R.layout.camera);
685b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
686b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mSurfaceView = (VideoPreview) findViewById(R.id.camera_preview);
687b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
688b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // don't set mSurfaceHolder here. We have it set ONLY within
689b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // surfaceCreated / surfaceDestroyed, other parts of the code
690b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // assume that when it is set, the surface is also set.
691b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        SurfaceHolder holder = mSurfaceView.getHolder();
692b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        holder.addCallback(this);
693b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
694b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
6959bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        mIsImageCaptureIntent = isImageCaptureIntent();
6969bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang
6979bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (!mIsImageCaptureIntent)  {
698b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mLastPictureButton = (ImageView) findViewById(R.id.last_picture_button);
699b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mLastPictureButton.setOnClickListener(this);
7009bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            Drawable frame = getResources().getDrawable(R.drawable.frame_thumbnail);
7019bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mThumbController = new ThumbnailController(mLastPictureButton,
7029bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang                    frame, mContentResolver);
7039bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mThumbController.loadData(ImageManager.getLastImageThumbPath());
704b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
705b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
706b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mShutterButton = (ShutterButton) findViewById(R.id.shutter_button);
707b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mShutterButton.setOnShutterButtonListener(this);
708b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
709b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        try {
710b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mClickSound = new MediaPlayer();
711b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            AssetFileDescriptor afd = getResources().openRawResourceFd(R.raw.camera_click);
712b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
713b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mClickSound.setDataSource(afd.getFileDescriptor(),
714b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                             afd.getStartOffset(),
715b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                             afd.getLength());
716b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
717b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (mClickSound != null) {
718b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mClickSound.setAudioStreamType(AudioManager.STREAM_ALARM);
719b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mClickSound.prepare();
720b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
721b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } catch (Exception ex) {
722b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Log.w(TAG, "Couldn't create click sound", ex);
723b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
724b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
725b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mFocusIndicator = findViewById(R.id.focus_indicator);
726b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mFocusBlinkAnimation = AnimationUtils.loadAnimation(this, R.anim.auto_focus_blink);
727b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mFocusBlinkAnimation.setRepeatCount(Animation.INFINITE);
728b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mFocusBlinkAnimation.setRepeatMode(Animation.REVERSE);
729b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
730b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // We load the post_picture_panel layout only if it is needed.
7319bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (mIsImageCaptureIntent) {
732b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            ViewGroup cameraView = (ViewGroup)findViewById(R.id.camera);
733b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            getLayoutInflater().inflate(R.layout.post_picture_panel,
734b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                                        cameraView);
735b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mPostCaptureAlert = findViewById(R.id.post_picture_panel);
736b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
737b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
738b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // Make sure the services are loaded.
739b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        try {
740b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            openCameraThread.join();
741b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            loadServiceThread.join();
742b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } catch (InterruptedException ex) {
743b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
744b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
745b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        ImageManager.ensureOSXCompatibleFolder();
746b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
747b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
748b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
749b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void onStart() {
750b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        super.onStart();
751b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
752b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Thread t = new Thread(new Runnable() {
753b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            public void run() {
754b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                final boolean storageOK = calculatePicturesRemaining() > 0;
755b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
756b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                if (!storageOK) {
757b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    mHandler.post(new Runnable() {
758b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        public void run() {
759b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            updateStorageHint(mPicturesRemaining);
760b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        }
761b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    });
762b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
763b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
764b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        });
765b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        t.start();
766b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
767b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
768b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void onClick(View v) {
769b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        switch (v.getId()) {
770b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        case R.id.last_picture_button:
771b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            viewLastImage();
772b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            break;
773b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        case R.id.attach:
774b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            doAttach();
775b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            break;
776b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        case R.id.cancel:
777b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            doCancel();
778b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
779b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
780b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
781b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void doAttach() {
782de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        if (mPausing) {
783e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project            return;
784e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project        }
785b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Bitmap bitmap = mImageCapture.getLastBitmap();
786b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
787b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        String cropValue = null;
788b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Uri saveUri = null;
789b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
790b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Bundle myExtras = getIntent().getExtras();
791b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (myExtras != null) {
792b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            saveUri = (Uri) myExtras.getParcelable(MediaStore.EXTRA_OUTPUT);
793b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            cropValue = myExtras.getString("crop");
794b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
795b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
796b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
797b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (cropValue == null) {
798b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            /*
799b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project             * First handle the no crop case -- just return the value.  If the caller
800b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project             * specifies a "save uri" then write the data to it's stream.  Otherwise,
801b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project             * pass back a scaled down version of the bitmap directly in the extras.
802b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project             */
803b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (saveUri != null) {
804b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                OutputStream outputStream = null;
805b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                try {
806b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    outputStream = mContentResolver.openOutputStream(saveUri);
807b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    bitmap.compress(Bitmap.CompressFormat.JPEG, 75, outputStream);
808b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    outputStream.close();
809b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
810b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    setResult(RESULT_OK);
811b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    finish();
812b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                } catch (IOException ex) {
813b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    //
814b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                } finally {
815b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    if (outputStream != null) {
816b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        try {
817b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            outputStream.close();
818b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        } catch (IOException ex) {
819b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
820b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        }
821b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    }
822b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
823b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } else {
824b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                float scale = .5F;
825b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                Matrix m = new Matrix();
826b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                m.setScale(scale, scale);
827b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
828b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                bitmap = Bitmap.createBitmap(bitmap, 0, 0,
829b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        bitmap.getWidth(),
830b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        bitmap.getHeight(),
831b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        m, true);
832b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
833b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                setResult(RESULT_OK, new Intent("inline-data").putExtra("data", bitmap));
834b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                finish();
835b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
836b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
837b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        else {
838b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            /*
839b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project             * Save the image to a temp file and invoke the cropper
840b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project             */
841b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Uri tempUri = null;
842b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            FileOutputStream tempStream = null;
843b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            try {
844b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                File path = getFileStreamPath(sTempCropFilename);
845b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                path.delete();
846b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                tempStream = openFileOutput(sTempCropFilename, 0);
847b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                bitmap.compress(Bitmap.CompressFormat.JPEG, 75, tempStream);
848b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                tempStream.close();
849b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                tempUri = Uri.fromFile(path);
850b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } catch (FileNotFoundException ex) {
851b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                setResult(Activity.RESULT_CANCELED);
852b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                finish();
853b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                return;
854b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } catch (IOException ex) {
855b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                setResult(Activity.RESULT_CANCELED);
856b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                finish();
857b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                return;
858b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } finally {
859b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                if (tempStream != null) {
860b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    try {
861b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        tempStream.close();
862b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    } catch (IOException ex) {
863b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
864b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    }
865b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
866b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
867b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
868b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Bundle newExtras = new Bundle();
869b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (cropValue.equals("circle"))
870b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                newExtras.putString("circleCrop", "true");
871b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (saveUri != null)
872b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                newExtras.putParcelable(MediaStore.EXTRA_OUTPUT, saveUri);
873b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            else
874b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                newExtras.putBoolean("return-data", true);
875b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
876b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Intent cropIntent = new Intent();
877b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            cropIntent.setClass(Camera.this, CropImage.class);
878b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            cropIntent.setData(tempUri);
879b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            cropIntent.putExtras(newExtras);
880b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
881b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            startActivityForResult(cropIntent, CROP_MSG);
882b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
883b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
884b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
885b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void doCancel() {
886b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        setResult(RESULT_CANCELED, new Intent());
887b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        finish();
888b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
889b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
890b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void onShutterButtonFocus(ShutterButton button, boolean pressed) {
891de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        if (mPausing) {
892e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project            return;
893e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project        }
894b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        switch (button.getId()) {
895b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case R.id.shutter_button:
896b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                doFocus(pressed);
897b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
898b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
899b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
900b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
901b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void onShutterButtonClick(ShutterButton button) {
902de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        if (mPausing) {
903e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project            return;
904e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project        }
905b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        switch (button.getId()) {
906b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case R.id.shutter_button:
9079c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                doSnap();
908b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
909b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
910b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
911b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
912b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void updateStorageHint() {
913b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project      updateStorageHint(MenuHelper.calculatePicturesRemaining());
914b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
915b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
916b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private OnScreenHint mStorageHint;
917b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
918b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void updateStorageHint(int remaining) {
919b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        String noStorageText = null;
920b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
921b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (remaining == MenuHelper.NO_STORAGE_ERROR) {
922b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            String state = Environment.getExternalStorageState();
923b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (state == Environment.MEDIA_CHECKING) {
924b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                noStorageText = getString(R.string.preparing_sd);
925b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } else {
926b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                noStorageText = getString(R.string.no_storage);
927b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
928b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } else if (remaining < 1) {
929b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            noStorageText = getString(R.string.not_enough_space);
930b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
931b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
932b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (noStorageText != null) {
933b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (mStorageHint == null) {
934b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mStorageHint = OnScreenHint.makeText(this, noStorageText);
935b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } else {
936b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mStorageHint.setText(noStorageText);
937b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
938b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mStorageHint.show();
939b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } else if (mStorageHint != null) {
940b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mStorageHint.cancel();
941b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mStorageHint = null;
942b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
943b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
944b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
945b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
946b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void onResume() {
947b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        super.onResume();
948b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mHandler.sendEmptyMessageDelayed(CLEAR_SCREEN_DELAY, SCREEN_DELAY);
949b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
950b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mPausing = false;
951b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mOrientationListener.enable();
952b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
953b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // install an intent filter to receive SD card related events.
954b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED);
955b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
956b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED);
957b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
958b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        intentFilter.addAction(Intent.ACTION_MEDIA_CHECKING);
959b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        intentFilter.addDataScheme("file");
960b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        registerReceiver(mReceiver, intentFilter);
961b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mDidRegister = true;
962b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
963b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mImageCapture = new ImageCapture();
964b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
965b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        restartPreview();
966b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
967b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mPreferences.getBoolean("pref_camera_recordlocation_key", false))
968b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            startReceivingLocationUpdates();
969b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
970b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        updateFocusIndicator();
971b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
972b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        try {
973b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mFocusToneGenerator = new ToneGenerator(AudioManager.STREAM_SYSTEM, FOCUS_BEEP_VOLUME);
974b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } catch (RuntimeException e) {
975b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Log.w(TAG, "Exception caught while creating local tone generator: " + e);
976b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mFocusToneGenerator = null;
977b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
978b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
979b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
9809bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang    private static ImageManager.DataLocation dataLocation() {
981b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return ImageManager.DataLocation.EXTERNAL;
982b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
983b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
984b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
985b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void onStop() {
986b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        keep();
987b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        stopPreview();
988b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        closeCamera();
989b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mHandler.removeMessages(CLEAR_SCREEN_DELAY);
990b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        super.onStop();
991b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
992b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
993b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
994b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    protected void onPause() {
995b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        keep();
996b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
997b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mPausing = true;
998b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mOrientationListener.disable();
999b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1000b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        stopPreview();
1001b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1002b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (!mImageCapture.mCapturing) {
1003b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            closeCamera();
1004b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1005b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mDidRegister) {
1006b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            unregisterReceiver(mReceiver);
1007b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mDidRegister = false;
1008b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1009b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        stopReceivingLocationUpdates();
1010b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1011b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mFocusToneGenerator != null) {
1012b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mFocusToneGenerator.release();
1013b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mFocusToneGenerator = null;
1014b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1015b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
10169bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (!mIsImageCaptureIntent) {
10179bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mThumbController.storeData(ImageManager.getLastImageThumbPath());
10189bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        }
10199bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang
1020b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mStorageHint != null) {
1021b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mStorageHint.cancel();
1022b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mStorageHint = null;
1023b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1024de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
10259a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        // If we are in an image capture intent and has taken
10269a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        // a picture, we just clear it in onPause.
10279a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        mImageCapture.clearLastBitmap();
10289a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        mImageCapture = null;
10299a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        hidePostCaptureAlert();
1030e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project
1031b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        super.onPause();
1032b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1033b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1034b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
1035b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
1036b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        switch (requestCode) {
1037b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case CROP_MSG: {
1038b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                Intent intent = new Intent();
1039b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                if (data != null) {
1040b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    Bundle extras = data.getExtras();
1041b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    if (extras != null) {
1042b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        intent.putExtras(extras);
1043b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    }
1044b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
1045b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                setResult(resultCode, intent);
1046b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                finish();
1047b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1048b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                File path = getFileStreamPath(sTempCropFilename);
1049b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                path.delete();
1050b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1051b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
1052b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
1053b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1054b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1055b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1056b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void autoFocus() {
1057b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        updateFocusIndicator();
10589c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project        if (mFocusState != FOCUSING && mFocusState != FOCUSING_SNAP_ON_FINISH) {
1059b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (mCameraDevice != null) {
1060b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                if (DEBUG_TIME_OPERATIONS) {
1061b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    mFocusStartTime = System.currentTimeMillis();
1062b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
10639c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                mFocusState = FOCUSING;
10649c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                mCameraDevice.autoFocus(mAutoFocusCallback);
1065b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
1066b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1067b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1068b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
10699c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project    private void clearFocusState() {
10709c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project        mFocusState = FOCUS_NOT_STARTED;
1071b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1072b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1073b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void updateFocusIndicator() {
1074b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mHandler.post(new Runnable() {
1075b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            public void run() {
10769c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                if (mFocusState == FOCUS_SUCCESS) {
10779c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                    mFocusIndicator.setVisibility(View.VISIBLE);
1078b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    mFocusIndicator.clearAnimation();
10799c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                } else if (mFocusState == FOCUS_FAIL) {
10809c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                    mFocusIndicator.setVisibility(View.VISIBLE);
10819c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                    mFocusIndicator.startAnimation(mFocusBlinkAnimation);
1082b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                } else {
10839c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                    mFocusIndicator.setVisibility(View.GONE);
10849c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                    mFocusIndicator.clearAnimation();
1085b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
1086b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
1087b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        });
1088b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1089b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1090b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1091b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
1092b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public boolean onKeyDown(int keyCode, KeyEvent event) {
1093b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mHandler.sendEmptyMessageDelayed(CLEAR_SCREEN_DELAY, SCREEN_DELAY);
1094b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
1095b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1096b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        switch (keyCode) {
1097b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case KeyEvent.KEYCODE_BACK:
1098b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                if (mStatus == SNAPSHOT_IN_PROGRESS) {
1099b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    // ignore backs while we're taking a picture
1100b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    return true;
1101b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
1102b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
1103b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case KeyEvent.KEYCODE_FOCUS:
1104b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                if (event.getRepeatCount() == 0) {
1105b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    doFocus(true);
1106b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
1107b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                return true;
1108b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case KeyEvent.KEYCODE_CAMERA:
1109b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                if (event.getRepeatCount() == 0) {
11109c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                    doSnap();
1111b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
1112b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                return true;
1113b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case KeyEvent.KEYCODE_DPAD_CENTER:
1114b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                // If we get a dpad center event without any focused view, move the
1115b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                // focus to the shutter button and press it.
1116b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                if (event.getRepeatCount() == 0) {
1117b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    // Start auto-focus immediately to reduce shutter lag. After the shutter button
1118b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    // gets the focus, doFocus() will be called again but it is fine.
1119b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    doFocus(true);
1120b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    if (mShutterButton.isInTouchMode()) {
1121b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        mShutterButton.requestFocusFromTouch();
1122b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    } else {
1123b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        mShutterButton.requestFocus();
1124b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    }
1125b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    mShutterButton.setPressed(true);
1126b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
1127b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                return true;
1128b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1129b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1130b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return super.onKeyDown(keyCode, event);
1131b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1132b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1133b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
1134b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public boolean onKeyUp(int keyCode, KeyEvent event) {
1135b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        switch (keyCode) {
1136b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            case KeyEvent.KEYCODE_FOCUS:
1137b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                doFocus(false);
1138b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                return true;
1139b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1140b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return super.onKeyUp(keyCode, event);
1141b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1142b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
11439c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project    private void doSnap() {
11449c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project        // If the user has half-pressed the shutter and focus is completed, we
11459c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project        // can take the photo right away.
1146de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        if ((mFocusState == FOCUS_SUCCESS || mFocusState == FOCUS_FAIL)
11479c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                || !mPreviewing) {
1148b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // doesn't get set until the idler runs
1149b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (mCaptureObject != null) {
1150b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mCaptureObject.onSnap();
1151b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
11529c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project            clearFocusState();
1153b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            updateFocusIndicator();
11548d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project        } else if (mFocusState == FOCUSING) {
1155de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            // Half pressing the shutter (i.e. the focus button event) will
1156de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project            // already have requested AF for us, so just request capture on
11579c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project            // focus here.
11589c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project            mFocusState = FOCUSING_SNAP_ON_FINISH;
11598d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project        } else if (mFocusState == FOCUS_NOT_STARTED) {
11608d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project            // Focus key down event is dropped for some reasons. Just ignore.
1161b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1162b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1163b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1164b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void doFocus(boolean pressed) {
11659c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project        if (pressed) {  // Focus key down.
1166b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (mPreviewing) {
1167b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                autoFocus();
1168b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } else if (mCaptureObject != null) {
1169b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                // Save and restart preview
1170b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mCaptureObject.onSnap();
1171b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
11729c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project        } else {  // Focus key up.
11739c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project            if (mFocusState != FOCUSING_SNAP_ON_FINISH) {
11749c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                // User releases half-pressed focus key.
11759c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                clearFocusState();
11769c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project                updateFocusIndicator();
11779c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project            }
1178b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1179b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1180b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1181b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
1182e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project        mSurfaceView.setVisibility(View.VISIBLE);
1183b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // if we're creating the surface, start the preview as well.
1184b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        boolean preview = holder.isCreating();
1185b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        setViewFinder(w, h, preview);
1186de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        mCaptureObject = mImageCapture;
1187b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1188b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1189b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void surfaceCreated(SurfaceHolder holder) {
1190b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mSurfaceHolder = holder;
1191b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1192b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1193b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void surfaceDestroyed(SurfaceHolder holder) {
1194b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        stopPreview();
1195b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mSurfaceHolder = null;
1196b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1197b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1198b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void closeCamera() {
1199b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mCameraDevice != null) {
1200b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mCameraDevice.release();
1201b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mCameraDevice = null;
1202b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mPreviewing = false;
1203b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1204b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1205b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1206b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private boolean ensureCameraDevice() {
1207b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mCameraDevice == null) {
1208b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mCameraDevice = android.hardware.Camera.open();
1209b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1210b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return mCameraDevice != null;
1211b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1212de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
1213b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void updateLastImage() {
1214b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        ImageManager.IImageList list = ImageManager.instance().allImages(
1215b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            this,
1216b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mContentResolver,
1217b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            dataLocation(),
1218b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            ImageManager.INCLUDE_IMAGES,
1219b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            ImageManager.SORT_ASCENDING,
1220b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            ImageManager.CAMERA_IMAGE_BUCKET_ID);
1221b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        int count = list.getCount();
1222b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (count > 0) {
1223b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            ImageManager.IImage image = list.getImageAt(count-1);
12249bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            Uri uri = image.fullSizeImageUri();
12259bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mThumbController.setData(uri, image.miniThumbBitmap());
1226b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } else {
12279bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mThumbController.setData(null, null);
1228b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1229b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        list.deactivate();
1230b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1231b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1232b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void restartPreview() {
1233b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        VideoPreview surfaceView = mSurfaceView;
1234b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1235b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // make sure the surfaceview fills the whole screen when previewing
1236b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        surfaceView.setAspectRatio(VideoPreview.DONT_CARE);
1237b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        setViewFinder(mOriginalViewFinderWidth, mOriginalViewFinderHeight, true);
1238b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mStatus = IDLE;
1239b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1240b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // Calculate this in advance of each shot so we don't add to shutter latency. It's true that
1241b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // someone else could write to the SD card in the mean time and fill it, but that could have
1242b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // happened between the shutter press and saving the JPEG too.
1243b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // TODO: The best longterm solution is to write a reserve file of maximum JPEG size, always
1244b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // let the user take a picture, and delete that file if needed to save the new photo.
1245b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        calculatePicturesRemaining();
1246b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
12479bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (!mIsImageCaptureIntent && !mThumbController.isUriValid()) {
1248b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            updateLastImage();
1249b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1250de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project
12519bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (!mIsImageCaptureIntent) {
12529bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            mThumbController.updateDisplayIfNeeded();
1253b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1254b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1255b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1256b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void setViewFinder(int w, int h, boolean startPreview) {
1257b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mPausing)
1258b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            return;
1259b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1260b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mPreviewing &&
1261b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                w == mViewFinderWidth &&
1262b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                h == mViewFinderHeight) {
1263b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            return;
1264b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1265b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1266b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (!ensureCameraDevice())
1267b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            return;
1268b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1269b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mSurfaceHolder == null)
1270b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            return;
1271b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1272b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (isFinishing())
1273b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            return;
1274b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1275b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mPausing)
1276b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            return;
1277b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1278b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // remember view finder size
1279b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mViewFinderWidth = w;
1280b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mViewFinderHeight = h;
1281b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mOriginalViewFinderHeight == 0) {
1282b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mOriginalViewFinderWidth = w;
1283b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mOriginalViewFinderHeight = h;
1284b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1285b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1286b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (startPreview == false)
1287b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            return;
1288b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1289b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        /*
1290b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project         * start the preview if we're asked to...
1291b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project         */
1292b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1293b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // we want to start the preview and we're previewing already,
1294b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // stop the preview first (this will blank the screen).
1295b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mPreviewing)
1296b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            stopPreview();
1297b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1298b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // this blanks the screen if the surface changed, no-op otherwise
1299b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        try {
1300b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mCameraDevice.setPreviewDisplay(mSurfaceHolder);
1301b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } catch (IOException exception) {
1302b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mCameraDevice.release();
1303b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mCameraDevice = null;
1304b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // TODO: add more exception handling logic here
1305b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            return;
1306b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1307b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1308b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // request the preview size, the hardware may not honor it,
1309b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // if we depended on it we would have to query the size again
1310b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mParameters = mCameraDevice.getParameters();
1311b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mParameters.setPreviewSize(w, h);
1312b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        try {
1313b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mCameraDevice.setParameters(mParameters);
1314b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } catch (IllegalArgumentException e) {
1315b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // Ignore this error, it happens in the simulator.
1316b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1317b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1318b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1319b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        final long wallTimeStart = SystemClock.elapsedRealtime();
1320b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        final long threadTimeStart = Debug.threadCpuTimeNanos();
1321b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1322b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        final Object watchDogSync = new Object();
1323b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Thread watchDog = new Thread(new Runnable() {
1324b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            public void run() {
1325b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                int next_warning = 1;
1326b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                while (true) {
1327b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    try {
1328b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        synchronized (watchDogSync) {
1329b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            watchDogSync.wait(1000);
1330b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        }
1331b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    } catch (InterruptedException ex) {
1332b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        //
1333b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    }
1334b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    if (mPreviewing)
1335b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        break;
1336b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1337b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    int delay = (int) (SystemClock.elapsedRealtime() - wallTimeStart) / 1000;
1338b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    if (delay >= next_warning) {
1339b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        if (delay < 120) {
1340b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            Log.e(TAG, "preview hasn't started yet in " + delay + " seconds");
1341b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        } else {
1342b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            Log.e(TAG, "preview hasn't started yet in " + (delay / 60) + " minutes");
1343b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        }
1344b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        if (next_warning < 60) {
1345b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            next_warning <<= 1;
1346b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            if (next_warning == 16) {
1347b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                                next_warning = 15;
1348b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            }
1349b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        } else {
1350b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                            next_warning += 60;
1351b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        }
1352b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    }
1353b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
1354b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
1355b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        });
1356b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1357b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        watchDog.start();
1358b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1359b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (Config.LOGV)
1360b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Log.v(TAG, "calling mCameraDevice.startPreview");
1361b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        try {
1362b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mCameraDevice.startPreview();
1363b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } catch (Throwable e) {
1364b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // TODO: change Throwable to IOException once android.hardware.Camera.startPreview
1365b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // properly declares that it throws IOException.
1366b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1367b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mPreviewing = true;
1368b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1369b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        synchronized (watchDogSync) {
1370b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            watchDogSync.notify();
1371b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1372b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1373b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        long threadTimeEnd = Debug.threadCpuTimeNanos();
1374b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        long wallTimeEnd = SystemClock.elapsedRealtime();
1375b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if ((wallTimeEnd - wallTimeStart) > 3000) {
1376b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Log.w(TAG, "startPreview() to " + (wallTimeEnd - wallTimeStart) + " ms. Thread time was"
1377b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    + (threadTimeEnd - threadTimeStart) / 1000000 + " ms.");
1378b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1379b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1380b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1381b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void stopPreview() {
1382b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mCameraDevice != null && mPreviewing) {
1383b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mCameraDevice.stopPreview();
1384b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1385b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mPreviewing = false;
13868d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project        // If auto focus was in progress, it would have been canceled.
1387de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project        clearFocusState();
1388b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1389b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1390b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    void gotoGallery() {
1391b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        MenuHelper.gotoCameraImageGallery(this);
1392b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1393b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1394b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void viewLastImage() {
13959bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (mThumbController.isUriValid()) {
13969bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang            Uri targetUri = mThumbController.getUri();
1397b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            targetUri = targetUri.buildUpon().
1398b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                appendQueryParameter("bucketId", ImageManager.CAMERA_IMAGE_BUCKET_ID).build();
1399b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Intent intent = new Intent(Intent.ACTION_VIEW, targetUri);
1400b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            intent.putExtra(MediaStore.EXTRA_SCREEN_ORIENTATION,
1401b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
1402b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            intent.putExtra(MediaStore.EXTRA_FULL_SCREEN, true);
1403b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            intent.putExtra(MediaStore.EXTRA_SHOW_ACTION_ICONS, true);
1404b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            intent.putExtra("com.android.camera.ReviewMode", true);
1405b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1406b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            try {
1407b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                startActivity(intent);
1408b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } catch (android.content.ActivityNotFoundException ex) {
1409b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                // ignore.
1410b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
1411b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } else {
1412b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            Log.e(TAG, "Can't view last image.");
1413b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1414b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1415b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1416b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    void keep() {
1417b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mCaptureObject != null) {
14189a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project            mCaptureObject.dismissFreezeFrame();
1419b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1420b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    };
1421b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1422b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private ImageManager.IImage getImageForURI(Uri uri) {
1423b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        ImageManager.IImageList list = ImageManager.instance().allImages(
1424b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                this,
1425b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mContentResolver,
1426b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                dataLocation(),
1427b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                ImageManager.INCLUDE_IMAGES,
1428b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                ImageManager.SORT_ASCENDING);
1429b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        ImageManager.IImage image = list.getImageForUri(uri);
1430b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        list.deactivate();
1431b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return image;
1432b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1433b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1434b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1435b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void startReceivingLocationUpdates() {
1436b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mLocationManager != null) {
1437b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            try {
1438b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mLocationManager.requestLocationUpdates(
1439b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        LocationManager.NETWORK_PROVIDER,
1440b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        1000,
1441b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        0F,
1442b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        mLocationListeners[1]);
1443b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } catch (java.lang.SecurityException ex) {
1444b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                // ok
1445b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } catch (IllegalArgumentException ex) {
1446b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                if (Config.LOGD) {
1447b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    Log.d(TAG, "provider does not exist " + ex.getMessage());
1448b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
1449b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
1450b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            try {
1451b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                mLocationManager.requestLocationUpdates(
1452b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        LocationManager.GPS_PROVIDER,
1453b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        1000,
1454b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        0F,
1455b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                        mLocationListeners[0]);
1456b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } catch (java.lang.SecurityException ex) {
1457b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                // ok
1458b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            } catch (IllegalArgumentException ex) {
1459b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                if (Config.LOGD) {
1460b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    Log.d(TAG, "provider does not exist " + ex.getMessage());
1461b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
1462b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
1463b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1464b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1465b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1466b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void stopReceivingLocationUpdates() {
1467b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mLocationManager != null) {
1468b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            for (int i = 0; i < mLocationListeners.length; i++) {
1469b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                try {
1470b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    mLocationManager.removeUpdates(mLocationListeners[i]);
1471b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                } catch (Exception ex) {
1472b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    // ok
1473b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
1474b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
1475b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1476b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1477b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1478b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private Location getCurrentLocation() {
1479b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        Location l = null;
1480b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1481b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        // go in best to worst order
1482b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        for (int i = 0; i < mLocationListeners.length; i++) {
1483b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            l = mLocationListeners[i].current();
1484b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (l != null)
1485b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                break;
1486b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1487b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1488b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return l;
1489b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1490b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1491b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
1492b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public void onOptionsMenuClosed(Menu menu) {
1493b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        super.onOptionsMenuClosed(menu);
14949a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project        if (mImageSavingItem) {
1495b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // save the image if we presented the "advanced" menu
1496b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // which happens if "menu" is pressed while in
1497b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // SNAPSHOT_IN_PROGRESS  or SNAPSHOT_COMPLETED modes
1498b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            keep();
1499b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mHandler.sendEmptyMessage(RESTART_PREVIEW);
1500b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1501b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1502b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1503b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
1504b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public boolean onMenuOpened(int featureId, Menu menu) {
1505b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (featureId == Window.FEATURE_OPTIONS_PANEL) {
1506b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (mStatus == SNAPSHOT_IN_PROGRESS) {
1507b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                cancelAutomaticPreviewRestart();
1508b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
1509b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1510b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return super.onMenuOpened(featureId, menu);
1511b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1512b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1513b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
1514b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public boolean onPrepareOptionsMenu(Menu menu) {
1515b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        super.onPrepareOptionsMenu(menu);
1516b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1517b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        for (int i = 1; i <= MenuHelper.MENU_ITEM_MAX; i++) {
1518b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            if (i != MenuHelper.GENERIC_ITEM) {
1519b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                menu.setGroupVisible(i, false);
1520b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
1521b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1522b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1523b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        if (mStatus == SNAPSHOT_IN_PROGRESS || mStatus == SNAPSHOT_COMPLETED) {
1524b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            menu.setGroupVisible(MenuHelper.IMAGE_SAVING_ITEM, true);
1525b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mImageSavingItem = true;
1526b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } else {
1527b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            menu.setGroupVisible(MenuHelper.IMAGE_MODE_ITEM, true);
1528b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mImageSavingItem = false;
1529b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1530b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1531b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return true;
1532b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1533b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1534b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void cancelAutomaticPreviewRestart() {
1535b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mKeepAndRestartPreview = false;
1536b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mHandler.removeMessages(RESTART_PREVIEW);
1537b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1538b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1539b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private boolean isImageCaptureIntent() {
1540b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        String action = getIntent().getAction();
1541b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return (MediaStore.ACTION_IMAGE_CAPTURE.equals(action));
1542b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1543b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1544b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void showPostCaptureAlert() {
15459bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (mIsImageCaptureIntent) {
1546b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mPostCaptureAlert.setVisibility(View.VISIBLE);
1547b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            int[] pickIds = {R.id.attach, R.id.cancel};
1548b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            for(int id : pickIds) {
1549b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                View view = mPostCaptureAlert.findViewById(id);
1550b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                view.setOnClickListener(this);
1551b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                Animation animation = new AlphaAnimation(0F, 1F);
1552b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                animation.setDuration(500);
1553b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                view.setAnimation(animation);
1554b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
1555b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1556b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1557b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1558b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void hidePostCaptureAlert() {
15599bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (mIsImageCaptureIntent) {
1560b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mPostCaptureAlert.setVisibility(View.INVISIBLE);
1561b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1562b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1563b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1564b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    @Override
1565b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    public boolean onCreateOptionsMenu(Menu menu) {
1566b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        super.onCreateOptionsMenu(menu);
1567b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
15689bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang        if (mIsImageCaptureIntent) {
1569b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            // No options menu for attach mode.
1570b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            return false;
1571b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        } else {
1572b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            addBaseMenuItems(menu);
1573b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1574b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return true;
1575b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1576b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1577b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    SelectedImageGetter mSelectedImageGetter =
1578b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        new SelectedImageGetter() {
1579b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            public ImageManager.IImage getCurrentImage() {
1580b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                return getImageForURI(getCurrentImageUri());
1581b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
1582b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            public Uri getCurrentImageUri() {
1583b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                keep();
1584b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                return mCaptureObject.getLastCaptureUri();
1585b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
1586b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        };
1587b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1588b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private int calculatePicturesRemaining() {
1589b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        mPicturesRemaining = MenuHelper.calculatePicturesRemaining();
1590b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        return mPicturesRemaining;
1591b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1592b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1593b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    private void addBaseMenuItems(Menu menu) {
1594b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        MenuHelper.addSwitchModeMenuItem(menu, this, true);
1595b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        {
1596b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            MenuItem gallery = menu.add(MenuHelper.IMAGE_MODE_ITEM, MENU_GALLERY_PHOTOS, 0, R.string.camera_gallery_photos_text).setOnMenuItemClickListener(new OnMenuItemClickListener() {
1597b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                public boolean onMenuItemClick(MenuItem item) {
1598b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    gotoGallery();
1599b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    return true;
1600b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
1601b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            });
1602b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            gallery.setIcon(android.R.drawable.ic_menu_gallery);
1603b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mGalleryItems.add(gallery);
1604b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1605b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        {
1606b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            MenuItem gallery = menu.add(MenuHelper.VIDEO_MODE_ITEM, MENU_GALLERY_VIDEOS, 0, R.string.camera_gallery_photos_text).setOnMenuItemClickListener(new OnMenuItemClickListener() {
1607b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                public boolean onMenuItemClick(MenuItem item) {
1608b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    gotoGallery();
1609b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                    return true;
1610b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                }
1611b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            });
1612b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            gallery.setIcon(android.R.drawable.ic_menu_gallery);
1613b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            mGalleryItems.add(gallery);
1614b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        }
1615b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1616b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        MenuItem item = menu.add(MenuHelper.GENERIC_ITEM, MENU_SETTINGS, 0, R.string.settings).setOnMenuItemClickListener(new OnMenuItemClickListener() {
1617b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            public boolean onMenuItemClick(MenuItem item) {
1618b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                Intent intent = new Intent();
1619b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                intent.setClass(Camera.this, CameraSettings.class);
1620b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                startActivity(intent);
1621b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project                return true;
1622b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project            }
1623b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        });
1624b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project        item.setIcon(android.R.drawable.ic_menu_preferences);
1625b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project    }
1626b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project}
1627b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project
1628