ActivityBase.java revision 1cc3a3466c8e9f30f13b81a88d8b2f31050c599c
14d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang/* 24d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang * Copyright (C) 2009 The Android Open Source Project 34d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang * 44d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang * Licensed under the Apache License, Version 2.0 (the "License"); 54d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang * you may not use this file except in compliance with the License. 64d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang * You may obtain a copy of the License at 74d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang * 84d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang * http://www.apache.org/licenses/LICENSE-2.0 94d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang * 104d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang * Unless required by applicable law or agreed to in writing, software 114d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang * distributed under the License is distributed on an "AS IS" BASIS, 124d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang * See the License for the specific language governing permissions and 144d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang * limitations under the License. 154d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang */ 164d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang 174d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Changpackage com.android.camera; 184d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang 197d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Millerimport android.app.KeyguardManager; 20c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Liimport android.content.ContentResolver; 21892781804513066b68b4a2fa6f846e862dac252aOwen Linimport android.content.Context; 225df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Liimport android.content.Intent; 234c7b291018e08dbb4bc1712d95117a294fa1416cWu-cheng Liimport android.content.pm.ActivityInfo; 24296d27772b9543d55820e1d24d900fea959f1b7aPin Tingimport android.hardware.Camera.Parameters; 25c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Liimport android.os.AsyncTask; 268608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Changimport android.os.Bundle; 277d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Millerimport android.util.Log; 281cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Liimport android.view.animation.DecelerateInterpolator; 294c7b291018e08dbb4bc1712d95117a294fa1416cWu-cheng Liimport android.view.KeyEvent; 30c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Liimport android.view.View; 31a6b966047b6215b02c502a3f143106070abf6009Angus Kongimport android.view.Window; 32892781804513066b68b4a2fa6f846e862dac252aOwen Linimport android.view.WindowManager; 33892781804513066b68b4a2fa6f846e862dac252aOwen Lin 34892781804513066b68b4a2fa6f846e862dac252aOwen Linimport com.android.camera.ui.PopupManager; 35892781804513066b68b4a2fa6f846e862dac252aOwen Linimport com.android.camera.ui.RotateImageView; 36a6b966047b6215b02c502a3f143106070abf6009Angus Kongimport com.android.gallery3d.app.AbstractGalleryActivity; 37a6b966047b6215b02c502a3f143106070abf6009Angus Kongimport com.android.gallery3d.app.PhotoPage; 38a6b966047b6215b02c502a3f143106070abf6009Angus Kongimport com.android.gallery3d.app.GalleryActionBar; 39a6b966047b6215b02c502a3f143106070abf6009Angus Kongimport com.android.gallery3d.util.MediaSetUtils; 404d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang 41aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Liimport java.io.File; 42aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li 4377c1cdc8f2cda250b1db842204efb49f87e094aeChih-Chung Chang/** 447673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li * Superclass of Camera and VideoCamera activities. 4577c1cdc8f2cda250b1db842204efb49f87e094aeChih-Chung Chang */ 46a6b966047b6215b02c502a3f143106070abf6009Angus Kongabstract public class ActivityBase extends AbstractGalleryActivity 47a6b966047b6215b02c502a3f143106070abf6009Angus Kong implements CameraScreenNail.PositionChangedListener { 48a6b966047b6215b02c502a3f143106070abf6009Angus Kong 497d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller private static final String TAG = "ActivityBase"; 507d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller private static boolean LOGV = false; 515df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li private int mResultCodeForTesting; 527d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller private boolean mOnResumePending; 535df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li private Intent mResultDataForTesting; 544edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong private OnScreenHint mStorageHint; 551cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li private UpdateCameraAppView mUpdateCameraAppView; 561cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li private HideCameraAppView mHideCameraAppView; 57a6b966047b6215b02c502a3f143106070abf6009Angus Kong 58c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // The bitmap of the last captured picture thumbnail and the URI of the 59c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // original picture. 60c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li protected Thumbnail mThumbnail; 61c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // An imageview showing showing the last captured picture thumbnail. 62c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li protected RotateImageView mThumbnailView; 638a674bebfba0c4dd4b01018276d20f198f65f19eWu-cheng Li protected int mThumbnailViewWidth; // layout width of the thumbnail 64c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li protected AsyncTask<Void, Void, Thumbnail> mLoadThumbnailTask; 65475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting protected boolean mOpenCameraFail; 66475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting protected boolean mCameraDisabled; 67475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting protected CameraManager.CameraProxy mCameraDevice; 68296d27772b9543d55820e1d24d900fea959f1b7aPin Ting protected Parameters mParameters; 699833a3328025552a3a176dc4d054cde63ef11885Wu-cheng Li protected boolean mPaused; // The activity is paused. 70a6b966047b6215b02c502a3f143106070abf6009Angus Kong protected GalleryActionBar mActionBar; 71475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting 72475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting // multiple cameras support 73475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting protected int mNumberOfCameras; 74475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting protected int mCameraId; 75475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting 76a6b966047b6215b02c502a3f143106070abf6009Angus Kong protected CameraScreenNail mCameraScreenNail; // This shows camera preview. 77a6b966047b6215b02c502a3f143106070abf6009Angus Kong // The view containing only camera related widgets like control panel, 78a6b966047b6215b02c502a3f143106070abf6009Angus Kong // indicator bar, focus indicator and etc. 79a6b966047b6215b02c502a3f143106070abf6009Angus Kong protected View mCameraAppView; 801cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li protected boolean mShowCameraAppView = true; 81a6b966047b6215b02c502a3f143106070abf6009Angus Kong 82475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting protected class CameraOpenThread extends Thread { 83475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting @Override 84475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting public void run() { 85475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting try { 86475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting mCameraDevice = Util.openCamera(ActivityBase.this, mCameraId); 87296d27772b9543d55820e1d24d900fea959f1b7aPin Ting mParameters = mCameraDevice.getParameters(); 88475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting } catch (CameraHardwareException e) { 89475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting mOpenCameraFail = true; 90475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting } catch (CameraDisabledException e) { 91475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting mCameraDisabled = true; 92475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting } 93475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting } 94475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting } 955df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li 964d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang @Override 978608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Chang public void onCreate(Bundle icicle) { 984c7b291018e08dbb4bc1712d95117a294fa1416cWu-cheng Li if (Util.isTabletUI()) { 994c7b291018e08dbb4bc1712d95117a294fa1416cWu-cheng Li setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 100d33109730e0ab81230f84e2bd35599e8e24fc4baChung-yih Wang } else { 101d33109730e0ab81230f84e2bd35599e8e24fc4baChung-yih Wang setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 1024c7b291018e08dbb4bc1712d95117a294fa1416cWu-cheng Li } 103a6b966047b6215b02c502a3f143106070abf6009Angus Kong requestWindowFeature(Window.FEATURE_ACTION_BAR); 104a6b966047b6215b02c502a3f143106070abf6009Angus Kong requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY); 105a6b966047b6215b02c502a3f143106070abf6009Angus Kong requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); 106e5b6a36e64ef2c2cb1435c138a5fc179e9a6bc9aWu-cheng Li getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE); 1078608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Chang super.onCreate(icicle); 108a6b966047b6215b02c502a3f143106070abf6009Angus Kong // The full screen mode might be turned off previously. Add the flag again. 109a6b966047b6215b02c502a3f143106070abf6009Angus Kong getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); 110a6b966047b6215b02c502a3f143106070abf6009Angus Kong mActionBar = new GalleryActionBar(this); 1118608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Chang } 1128608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Chang 1138608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Chang @Override 1147d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller public void onWindowFocusChanged(boolean hasFocus) { 1157d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller if (LOGV) Log.v(TAG, "onWindowFocusChanged.hasFocus=" + hasFocus 1167d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller + ".mOnResumePending=" + mOnResumePending); 1177d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller if (hasFocus && mOnResumePending) { 1189833a3328025552a3a176dc4d054cde63ef11885Wu-cheng Li mPaused = false; 1197d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller doOnResume(); 1207d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller mOnResumePending = false; 1217d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller } 1227d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller } 1237d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller 1247d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller @Override 1257d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller protected void onResume() { 1267d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller super.onResume(); 1277d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller // Don't grab the camera if in use by lockscreen. For example, face 1287d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller // unlock may be using the camera. Camera may be already opened in 1297d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller // onCreate. doOnResume should continue if mCameraDevice != null. 1308853039421ae9b129ef40c8e71a347eac321d921Wu-cheng Li // Suppose camera app is in the foreground. If users turn off and turn 1318853039421ae9b129ef40c8e71a347eac321d921Wu-cheng Li // on the screen very fast, camera app can still have the focus when the 132475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting // lock screen shows up. The keyguard takes input focus, so the camera 1338853039421ae9b129ef40c8e71a347eac321d921Wu-cheng Li // app will lose focus when it is displayed. 1348853039421ae9b129ef40c8e71a347eac321d921Wu-cheng Li if (LOGV) Log.v(TAG, "onResume. hasWindowFocus()=" + hasWindowFocus()); 1358853039421ae9b129ef40c8e71a347eac321d921Wu-cheng Li if (mCameraDevice == null && isKeyguardLocked()) { 1368853039421ae9b129ef40c8e71a347eac321d921Wu-cheng Li if (LOGV) Log.v(TAG, "onResume. mOnResumePending=true"); 1377d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller mOnResumePending = true; 1387d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller } else { 1398853039421ae9b129ef40c8e71a347eac321d921Wu-cheng Li if (LOGV) Log.v(TAG, "onResume. mOnResumePending=false"); 1409833a3328025552a3a176dc4d054cde63ef11885Wu-cheng Li mPaused = false; 1417d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller doOnResume(); 1427d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller mOnResumePending = false; 1437d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller } 1447d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller } 1457d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller 1467d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller @Override 1477d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller protected void onPause() { 1489833a3328025552a3a176dc4d054cde63ef11885Wu-cheng Li mPaused = true; 1497d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller if (LOGV) Log.v(TAG, "onPause"); 150aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li saveThumbnailToFile(); 1517d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller super.onPause(); 1524edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong 153c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li if (mLoadThumbnailTask != null) { 154c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mLoadThumbnailTask.cancel(true); 155c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mLoadThumbnailTask = null; 156c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 157c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li 1584edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong if (mStorageHint != null) { 1594edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong mStorageHint.cancel(); 1604edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong mStorageHint = null; 1614edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } 1624edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong 1637d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller mOnResumePending = false; 1647d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller } 1657d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller 1667d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller // Put the code of onResume in this method. 1677d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller abstract protected void doOnResume(); 1687d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller 1697d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller @Override 1704d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang public boolean onSearchRequested() { 1714d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang return false; 1724d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang } 1737673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li 1747673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li @Override 1757673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li public boolean onKeyDown(int keyCode, KeyEvent event) { 1767673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li // Prevent software keyboard or voice search from showing up. 1777673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li if (keyCode == KeyEvent.KEYCODE_SEARCH 1787673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li || keyCode == KeyEvent.KEYCODE_MENU) { 1797673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li if (event.isLongPress()) return true; 1807673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li } 1817673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li 1827673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li return super.onKeyDown(keyCode, event); 1837673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li } 1845df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li 1855df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li protected void setResultEx(int resultCode) { 1865df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li mResultCodeForTesting = resultCode; 1875df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li setResult(resultCode); 1885df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li } 1895df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li 1905df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li protected void setResultEx(int resultCode, Intent data) { 1915df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li mResultCodeForTesting = resultCode; 1925df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li mResultDataForTesting = data; 1935df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li setResult(resultCode, data); 1945df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li } 1955df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li 1965df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li public int getResultCode() { 1975df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li return mResultCodeForTesting; 1985df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li } 1995df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li 2005df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li public Intent getResultData() { 2015df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li return mResultDataForTesting; 2025df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li } 2035f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang 2045f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang @Override 2055f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang protected void onDestroy() { 2065f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang PopupManager.removeInstance(this); 2075f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang super.onDestroy(); 2085f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang } 2097d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller 2107d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller private boolean isKeyguardLocked() { 2117d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller KeyguardManager kgm = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE); 2128853039421ae9b129ef40c8e71a347eac321d921Wu-cheng Li if (LOGV) { 2138853039421ae9b129ef40c8e71a347eac321d921Wu-cheng Li if (kgm != null) { 2148853039421ae9b129ef40c8e71a347eac321d921Wu-cheng Li Log.v(TAG, "kgm.isKeyguardLocked()="+kgm.isKeyguardLocked() 2158853039421ae9b129ef40c8e71a347eac321d921Wu-cheng Li + ". kgm.isKeyguardSecure()="+kgm.isKeyguardSecure()); 2168853039421ae9b129ef40c8e71a347eac321d921Wu-cheng Li } 2178853039421ae9b129ef40c8e71a347eac321d921Wu-cheng Li } 2187d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller // isKeyguardSecure excludes the slide lock case. 2197d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller return (kgm != null) && kgm.isKeyguardLocked() && kgm.isKeyguardSecure(); 2207d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller } 2214edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong 2224edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong protected void updateStorageHint(long storageSpace) { 2234edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong String message = null; 2244edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong if (storageSpace == Storage.UNAVAILABLE) { 2254edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong message = getString(R.string.no_storage); 2264edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } else if (storageSpace == Storage.PREPARING) { 2274edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong message = getString(R.string.preparing_sd); 2284edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } else if (storageSpace == Storage.UNKNOWN_SIZE) { 2294edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong message = getString(R.string.access_sd_fail); 2304edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } else if (storageSpace < Storage.LOW_STORAGE_THRESHOLD) { 2314edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong message = getString(R.string.spaceIsLow_content); 2324edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } 2334edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong 2344edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong if (message != null) { 2354edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong if (mStorageHint == null) { 2364edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong mStorageHint = OnScreenHint.makeText(this, message); 2374edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } else { 2384edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong mStorageHint.setText(message); 2394edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } 2404edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong mStorageHint.show(); 2414edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } else if (mStorageHint != null) { 2424edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong mStorageHint.cancel(); 2434edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong mStorageHint = null; 2444edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } 2454edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } 246c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li 247c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li private void updateThumbnailView() { 248c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li if (mThumbnail != null) { 249c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mThumbnailView.setBitmap(mThumbnail.getBitmap()); 250c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mThumbnailView.setVisibility(View.VISIBLE); 251c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } else { 252c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mThumbnailView.setBitmap(null); 253c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mThumbnailView.setVisibility(View.GONE); 254c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 255c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 256c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li 257c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li protected void getLastThumbnail() { 258c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mThumbnail = ThumbnailHolder.getLastThumbnail(getContentResolver()); 259c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // Suppose users tap the thumbnail view, go to the gallery, delete the 260c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // image, and coming back to the camera. Thumbnail file will be invalid. 261c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // Since the new thumbnail will be loaded in another thread later, the 262c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // view should be set to gone to prevent from opening the invalid image. 263c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li updateThumbnailView(); 264c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li if (mThumbnail == null) { 265c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mLoadThumbnailTask = new LoadThumbnailTask().execute(); 266c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 267c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 268c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li 269aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li private class LoadThumbnailTask extends AsyncTask<Void, Void, Thumbnail> { 270c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li @Override 271c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li protected Thumbnail doInBackground(Void... params) { 272c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // Load the thumbnail from the file. 273c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li ContentResolver resolver = getContentResolver(); 274c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li Thumbnail t = Thumbnail.getLastThumbnailFromFile(getFilesDir(), resolver); 275c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li 276c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li if (isCancelled()) return null; 277c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li 278c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li if (t == null) { 279c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // Load the thumbnail from the media provider. 280c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li t = Thumbnail.getLastThumbnailFromContentResolver(resolver); 281c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 282c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li return t; 283c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 284c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li 285c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li @Override 286c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li protected void onPostExecute(Thumbnail thumbnail) { 287c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mThumbnail = thumbnail; 288c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li updateThumbnailView(); 289c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 290c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 291aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li 2926899a30e3a89ad4b455978140682d5ba871c1b33Pin Ting protected void gotoGallery() { 2936899a30e3a89ad4b455978140682d5ba871c1b33Pin Ting Util.viewUri(mThumbnail.getUri(), this); 2946899a30e3a89ad4b455978140682d5ba871c1b33Pin Ting } 2956899a30e3a89ad4b455978140682d5ba871c1b33Pin Ting 296aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li protected void saveThumbnailToFile() { 297aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li if (mThumbnail != null && !mThumbnail.fromFile()) { 298aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li new SaveThumbnailTask().execute(mThumbnail); 299aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li } 300aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li } 301aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li 302aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li private class SaveThumbnailTask extends AsyncTask<Thumbnail, Void, Void> { 303aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li @Override 304aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li protected Void doInBackground(Thumbnail... params) { 305aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li final int n = params.length; 306aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li final File filesDir = getFilesDir(); 307aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li for (int i = 0; i < n; i++) { 308aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li params[i].saveLastThumbnailToFile(filesDir); 309aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li } 310aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li return null; 311aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li } 312aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li } 313a6b966047b6215b02c502a3f143106070abf6009Angus Kong 314a6b966047b6215b02c502a3f143106070abf6009Angus Kong // Call this after setContentView. 315a6b966047b6215b02c502a3f143106070abf6009Angus Kong protected void createCameraScreenNail(boolean getPictures) { 316a6b966047b6215b02c502a3f143106070abf6009Angus Kong mCameraAppView = findViewById(R.id.camera_app_root); 317a6b966047b6215b02c502a3f143106070abf6009Angus Kong Bundle data = new Bundle(); 318a6b966047b6215b02c502a3f143106070abf6009Angus Kong String path = "/local/all/"; 319a6b966047b6215b02c502a3f143106070abf6009Angus Kong // Intent mode does not show camera roll. Use 0 as a work around for 320a6b966047b6215b02c502a3f143106070abf6009Angus Kong // invalid bucket id. 321a6b966047b6215b02c502a3f143106070abf6009Angus Kong // TODO: add support of empty media set in gallery. 322a6b966047b6215b02c502a3f143106070abf6009Angus Kong path += (getPictures ? MediaSetUtils.CAMERA_BUCKET_ID : "0"); 323a6b966047b6215b02c502a3f143106070abf6009Angus Kong data.putString(PhotoPage.KEY_MEDIA_SET_PATH, path); 324a6b966047b6215b02c502a3f143106070abf6009Angus Kong data.putString(PhotoPage.KEY_MEDIA_ITEM_PATH, path); 325a6b966047b6215b02c502a3f143106070abf6009Angus Kong 326a6b966047b6215b02c502a3f143106070abf6009Angus Kong // Send a CameraScreenNail to gallery to enable the camera preview. 327a6b966047b6215b02c502a3f143106070abf6009Angus Kong CameraScreenNailHolder holder = new CameraScreenNailHolder(this); 328a6b966047b6215b02c502a3f143106070abf6009Angus Kong data.putParcelable(PhotoPage.KEY_SCREENNAIL_HOLDER, holder); 329a6b966047b6215b02c502a3f143106070abf6009Angus Kong getStateManager().startState(PhotoPage.class, data); 330a6b966047b6215b02c502a3f143106070abf6009Angus Kong mCameraScreenNail = holder.getCameraScreenNail(); 331a6b966047b6215b02c502a3f143106070abf6009Angus Kong mCameraScreenNail.setPositionChangedListener(this); 332a6b966047b6215b02c502a3f143106070abf6009Angus Kong } 333a6b966047b6215b02c502a3f143106070abf6009Angus Kong 3341cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li private class HideCameraAppView implements Runnable { 3351cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li @Override 3361cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li public void run() { 3371cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li mCameraAppView.setVisibility(View.GONE); 3381cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li } 3391cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li } 340a6b966047b6215b02c502a3f143106070abf6009Angus Kong private class UpdateCameraAppView implements Runnable { 341a6b966047b6215b02c502a3f143106070abf6009Angus Kong @Override 342a6b966047b6215b02c502a3f143106070abf6009Angus Kong public void run() { 3431cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li if (mShowCameraAppView) { 344a6b966047b6215b02c502a3f143106070abf6009Angus Kong mCameraAppView.setVisibility(View.VISIBLE); 3451cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li mCameraAppView.animate().withLayer().alpha(1); 3461cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li } else { 3471cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li mCameraAppView.animate().withLayer().alpha(0).withEndAction(mHideCameraAppView); 348a6b966047b6215b02c502a3f143106070abf6009Angus Kong } 349a6b966047b6215b02c502a3f143106070abf6009Angus Kong } 350a6b966047b6215b02c502a3f143106070abf6009Angus Kong } 351a6b966047b6215b02c502a3f143106070abf6009Angus Kong 352a6b966047b6215b02c502a3f143106070abf6009Angus Kong @Override 3531cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li public void onPositionChanged(int x, int y, int width, int height, boolean visible) { 354a6b966047b6215b02c502a3f143106070abf6009Angus Kong if (!mPaused && !isFinishing()) { 3551cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li View rootView = (View) getGLRoot(); 3561cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li int rootWidth = rootView.getWidth(); 3571cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li int rootHeight = rootView.getHeight(); 3581cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li boolean showCameraAppView; 3591cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li // Check if the camera preview is in the center. 3601cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li if (visible && (x == 0 && width == rootWidth) || 3611cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li (y == 0 && height == rootHeight && Math.abs(x - (rootWidth - width) / 2) <= 1)) { 3621cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li showCameraAppView = true; 363a6b966047b6215b02c502a3f143106070abf6009Angus Kong } else { 3641cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li showCameraAppView = false; 3651cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li } 3661cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li 3671cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li if (mShowCameraAppView != showCameraAppView) { 3681cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li mShowCameraAppView = showCameraAppView; 3691cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li // Initialize the animation. 3701cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li if (mUpdateCameraAppView == null) { 3711cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li mUpdateCameraAppView = new UpdateCameraAppView(); 3721cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li mHideCameraAppView = new HideCameraAppView(); 3731cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li mCameraAppView.animate().setDuration(300) 3741cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li .setInterpolator(new DecelerateInterpolator()); 3751cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li } 3761cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li runOnUiThread(mUpdateCameraAppView); 377a6b966047b6215b02c502a3f143106070abf6009Angus Kong } 378a6b966047b6215b02c502a3f143106070abf6009Angus Kong } 379a6b966047b6215b02c502a3f143106070abf6009Angus Kong } 380a6b966047b6215b02c502a3f143106070abf6009Angus Kong 381a6b966047b6215b02c502a3f143106070abf6009Angus Kong @Override 382a6b966047b6215b02c502a3f143106070abf6009Angus Kong public GalleryActionBar getGalleryActionBar() { 383a6b966047b6215b02c502a3f143106070abf6009Angus Kong return mActionBar; 384a6b966047b6215b02c502a3f143106070abf6009Angus Kong } 3854d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang} 386