ActivityBase.java revision e14d9149a501183d3b785f4f4aa484c4b85192d1
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 19b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Changimport android.content.BroadcastReceiver; 20c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Liimport android.content.ContentResolver; 21b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Changimport android.content.Context; 225df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Liimport android.content.Intent; 23b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Changimport android.content.IntentFilter; 24c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Liimport android.graphics.Bitmap; 25195f07f83be795b2dfc0cdd12636a2eb4afedd86Wu-cheng Liimport android.graphics.BitmapFactory; 2678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Changimport android.graphics.Rect; 27296d27772b9543d55820e1d24d900fea959f1b7aPin Tingimport android.hardware.Camera.Parameters; 2888e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Liimport android.net.Uri; 29c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Liimport android.os.AsyncTask; 308608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Changimport android.os.Bundle; 31844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescuimport android.os.Handler; 32844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescuimport android.os.Message; 33b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Changimport android.support.v4.content.LocalBroadcastManager; 347d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Millerimport android.util.Log; 354c7b291018e08dbb4bc1712d95117a294fa1416cWu-cheng Liimport android.view.KeyEvent; 36c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Liimport android.view.View; 37a6b966047b6215b02c502a3f143106070abf6009Angus Kongimport android.view.Window; 38892781804513066b68b4a2fa6f846e862dac252aOwen Linimport android.view.WindowManager; 39525667ff4b93a577298085fe45660a2d15b0bd06Angus Kongimport android.view.animation.AlphaAnimation; 40525667ff4b93a577298085fe45660a2d15b0bd06Angus Kongimport android.view.animation.Animation; 41a029bd9976ebb618f321e8740c86b0f5d681d241Owen Linimport android.view.animation.DecelerateInterpolator; 42892781804513066b68b4a2fa6f846e862dac252aOwen Lin 43d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Liimport com.android.camera.ui.CameraPicker; 44525667ff4b93a577298085fe45660a2d15b0bd06Angus Kongimport com.android.camera.ui.LayoutChangeNotifier; 45892781804513066b68b4a2fa6f846e862dac252aOwen Linimport com.android.camera.ui.PopupManager; 46892781804513066b68b4a2fa6f846e862dac252aOwen Linimport com.android.camera.ui.RotateImageView; 47a6b966047b6215b02c502a3f143106070abf6009Angus Kongimport com.android.gallery3d.app.AbstractGalleryActivity; 4878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Changimport com.android.gallery3d.app.AppBridge; 49a6b966047b6215b02c502a3f143106070abf6009Angus Kongimport com.android.gallery3d.app.GalleryActionBar; 50a029bd9976ebb618f321e8740c86b0f5d681d241Owen Linimport com.android.gallery3d.app.PhotoPage; 51c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Liimport com.android.gallery3d.common.ApiHelper; 5278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Changimport com.android.gallery3d.ui.ScreenNail; 53a6b966047b6215b02c502a3f143106070abf6009Angus Kongimport com.android.gallery3d.util.MediaSetUtils; 544d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang 55aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Liimport java.io.File; 56aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li 5777c1cdc8f2cda250b1db842204efb49f87e094aeChih-Chung Chang/** 587673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li * Superclass of Camera and VideoCamera activities. 5977c1cdc8f2cda250b1db842204efb49f87e094aeChih-Chung Chang */ 60525667ff4b93a577298085fe45660a2d15b0bd06Angus Kongpublic abstract class ActivityBase extends AbstractGalleryActivity 61525667ff4b93a577298085fe45660a2d15b0bd06Angus Kong implements LayoutChangeNotifier.Listener { 62a6b966047b6215b02c502a3f143106070abf6009Angus Kong 637d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller private static final String TAG = "ActivityBase"; 64c38faeb66a3f2cc96e4c5e951228d9b01e12edb3Chih-Chung Chang private static final int CAMERA_APP_VIEW_TOGGLE_TIME = 100; // milliseconds 65b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang private static final String ACTION_DELETE_PICTURE = 66b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang "com.android.gallery3d.action.DELETE_PICTURE"; 6788e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li private static final String INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE = 6888e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li "android.media.action.STILL_IMAGE_CAMERA_SECURE"; 6953b11253fde509b01851ba022d9178c7c6f13ddeWu-cheng Li public static final String ACTION_IMAGE_CAPTURE_SECURE = 70ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li "android.media.action.IMAGE_CAPTURE_SECURE"; 7188e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li // The intent extra for camera from secure lock screen. True if the gallery 7288e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li // should only show newly captured pictures. sSecureAlbumId does not 7388e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li // increment. This is used when switching between camera, camcorder, and 7488e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li // panorama. If the extra is not set, it is in the normal camera mode. 7588e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li public static final String SECURE_CAMERA_EXTRA = "secure_camera"; 7647a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang 775df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li private int mResultCodeForTesting; 785df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li private Intent mResultDataForTesting; 794edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong private OnScreenHint mStorageHint; 80bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li private View mSingleTapArea; 81a6b966047b6215b02c502a3f143106070abf6009Angus Kong 82c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // The bitmap of the last captured picture thumbnail and the URI of the 83c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // original picture. 84c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li protected Thumbnail mThumbnail; 858a674bebfba0c4dd4b01018276d20f198f65f19eWu-cheng Li protected int mThumbnailViewWidth; // layout width of the thumbnail 86c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li protected AsyncTask<Void, Void, Thumbnail> mLoadThumbnailTask; 87d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li // An imageview showing the last captured picture thumbnail. 88d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li protected RotateImageView mThumbnailView; 89d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li protected CameraPicker mCameraPicker; 90d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li 91475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting protected boolean mOpenCameraFail; 92475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting protected boolean mCameraDisabled; 93475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting protected CameraManager.CameraProxy mCameraDevice; 94296d27772b9543d55820e1d24d900fea959f1b7aPin Ting protected Parameters mParameters; 955c17d7a077acd1f84bdcb7579f7d02a1094602bcWu-cheng Li // The activity is paused. The classes that extend this class should set 965c17d7a077acd1f84bdcb7579f7d02a1094602bcWu-cheng Li // mPaused the first thing in onResume/onPause. 975c17d7a077acd1f84bdcb7579f7d02a1094602bcWu-cheng Li protected boolean mPaused; 98a6b966047b6215b02c502a3f143106070abf6009Angus Kong protected GalleryActionBar mActionBar; 99475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting 100475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting // multiple cameras support 101475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting protected int mNumberOfCameras; 102475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting protected int mCameraId; 103d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li // The activity is going to switch to the specified camera id. This is 104d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li // needed because texture copy is done in GL thread. -1 means camera is not 105d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li // switching. 106d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li protected int mPendingSwitchCameraId = -1; 107475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting 10878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang protected MyAppBridge mAppBridge; 109c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li protected ScreenNail mCameraScreenNail; // This shows camera preview. 110a6b966047b6215b02c502a3f143106070abf6009Angus Kong // The view containing only camera related widgets like control panel, 111a6b966047b6215b02c502a3f143106070abf6009Angus Kong // indicator bar, focus indicator and etc. 112a6b966047b6215b02c502a3f143106070abf6009Angus Kong protected View mCameraAppView; 1131cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li protected boolean mShowCameraAppView = true; 11447a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang private Animation mCameraAppViewFadeIn; 11547a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang private Animation mCameraAppViewFadeOut; 11688e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li // Secure album id. This should be incremented every time the camera is 11788e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li // launched from the secure lock screen. The id should be the same when 11888e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li // switching between camera, camcorder, and panorama. 11988e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li protected static int sSecureAlbumId; 120ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li // True if the camera is started from secure lock screen. 12188e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li protected boolean mSecureCamera; 1227717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li private static boolean sFirstStartAfterScreenOn = true; 12347a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang 124844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu private long mStorageSpace = Storage.LOW_STORAGE_THRESHOLD; 125844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu private static final int UPDATE_STORAGE_HINT = 0; 126844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu private final Handler mHandler = new Handler() { 127844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu @Override 128844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu public void handleMessage(Message msg) { 129844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu switch (msg.what) { 130844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu case UPDATE_STORAGE_HINT: 131844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu updateStorageHint(); 132844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu return; 133844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu } 134844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu } 135844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu }; 136844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu 137844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 138844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu @Override 139844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu public void onReceive(Context context, Intent intent) { 140844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu String action = intent.getAction(); 141844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu if (action.equals(Intent.ACTION_MEDIA_MOUNTED) 142844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu || action.equals(Intent.ACTION_MEDIA_UNMOUNTED) 143844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu || action.equals(Intent.ACTION_MEDIA_CHECKING) 144844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu || action.equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) { 145844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu updateStorageSpaceAndHint(); 146844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu } 147844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu } 148844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu }; 149844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu 150b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang private boolean mUpdateThumbnailDelayed; 151b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang private IntentFilter mDeletePictureFilter = 152b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang new IntentFilter(ACTION_DELETE_PICTURE); 153b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang private BroadcastReceiver mDeletePictureReceiver = 154b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang new BroadcastReceiver() { 155b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang @Override 156b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang public void onReceive(Context context, Intent intent) { 157b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang if (mShowCameraAppView) { 158b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang getLastThumbnailUncached(); 159b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang } else { 160b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang mUpdateThumbnailDelayed = true; 161b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang } 162b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang } 163b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang }; 164a6b966047b6215b02c502a3f143106070abf6009Angus Kong 165d80b2cd48dd5958a0e9f370ce28c483b3a1dd166Wu-cheng Li // close activity when screen turns off 166d80b2cd48dd5958a0e9f370ce28c483b3a1dd166Wu-cheng Li private BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() { 167d80b2cd48dd5958a0e9f370ce28c483b3a1dd166Wu-cheng Li @Override 168d80b2cd48dd5958a0e9f370ce28c483b3a1dd166Wu-cheng Li public void onReceive(Context context, Intent intent) { 169d80b2cd48dd5958a0e9f370ce28c483b3a1dd166Wu-cheng Li finish(); 170d80b2cd48dd5958a0e9f370ce28c483b3a1dd166Wu-cheng Li } 171d80b2cd48dd5958a0e9f370ce28c483b3a1dd166Wu-cheng Li }; 172d80b2cd48dd5958a0e9f370ce28c483b3a1dd166Wu-cheng Li 1737717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li private static BroadcastReceiver sScreenOffReceiver; 1747717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li private static class ScreenOffReceiver extends BroadcastReceiver { 1757717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li @Override 1767717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li public void onReceive(Context context, Intent intent) { 1777717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li sFirstStartAfterScreenOn = true; 1787717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li } 1797717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li } 1807717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li 1817717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li public static boolean isFirstStartAfterScreenOn() { 1827717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li return sFirstStartAfterScreenOn; 1837717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li } 1847717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li 1857717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li public static void resetFirstStartAfterScreenOn() { 1867717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li sFirstStartAfterScreenOn = false; 1877717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li } 1887717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li 189475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting protected class CameraOpenThread extends Thread { 190475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting @Override 191475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting public void run() { 192475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting try { 193475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting mCameraDevice = Util.openCamera(ActivityBase.this, mCameraId); 194296d27772b9543d55820e1d24d900fea959f1b7aPin Ting mParameters = mCameraDevice.getParameters(); 195475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting } catch (CameraHardwareException e) { 196475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting mOpenCameraFail = true; 197475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting } catch (CameraDisabledException e) { 198475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting mCameraDisabled = true; 199475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting } 200475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting } 201475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting } 2025df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li 2034d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang @Override 2048608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Chang public void onCreate(Bundle icicle) { 2056a4a72b643929701c5d7c8b68b91d762c7277c20Wu-cheng Li super.disableToggleStatusBar(); 206a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin // Set a theme with action bar. It is not specified in manifest because 207a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin // we want to hide it by default. setTheme must happen before 208a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin // setContentView. 209a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin // 210a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin // This must be set before we call super.onCreate(), where the window's 211a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin // background is removed. 212a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin setTheme(R.style.Theme_Gallery); 213a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); 214ae8b4eecd123aae8593b620b9e0783a03a907a98Ahbong Chang if (ApiHelper.HAS_ACTION_BAR) { 215ae8b4eecd123aae8593b620b9e0783a03a907a98Ahbong Chang requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY); 216ae8b4eecd123aae8593b620b9e0783a03a907a98Ahbong Chang } else { 217ae8b4eecd123aae8593b620b9e0783a03a907a98Ahbong Chang requestWindowFeature(Window.FEATURE_NO_TITLE); 218ae8b4eecd123aae8593b620b9e0783a03a907a98Ahbong Chang } 219a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin 22088e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li // Check if this is in the secure camera mode. 22188e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li Intent intent = getIntent(); 222ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li String action = intent.getAction(); 223ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li if (INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE.equals(action)) { 22488e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li mSecureCamera = true; 22588e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li // Use a new album when this is started from the lock screen. 22688e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li sSecureAlbumId++; 227ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li } else if (ACTION_IMAGE_CAPTURE_SECURE.equals(action)) { 228ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li mSecureCamera = true; 22988e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li } else { 23088e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li mSecureCamera = intent.getBooleanExtra(SECURE_CAMERA_EXTRA, false); 23188e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li } 232d80b2cd48dd5958a0e9f370ce28c483b3a1dd166Wu-cheng Li if (mSecureCamera) { 2337717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF); 2347717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li registerReceiver(mScreenOffReceiver, filter); 2357717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li if (sScreenOffReceiver == null) { 2367717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li sScreenOffReceiver = new ScreenOffReceiver(); 2377717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li getApplicationContext().registerReceiver(sScreenOffReceiver, filter); 2387717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li } 239d80b2cd48dd5958a0e9f370ce28c483b3a1dd166Wu-cheng Li } 2408608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Chang super.onCreate(icicle); 2418608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Chang } 2428608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Chang 24305e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong public boolean isPanoramaActivity() { 24405e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong return false; 24505e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong } 24605e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong 2478608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Chang @Override 248b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang protected void onResume() { 249b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang super.onResume(); 250b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang LocalBroadcastManager manager = LocalBroadcastManager.getInstance(this); 251b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang manager.registerReceiver(mDeletePictureReceiver, mDeletePictureFilter); 252844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu 253844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu installIntentFilter(); 254844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu if(updateStorageHintOnResume()) { 255844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu updateStorageSpace(); 256844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu mHandler.sendEmptyMessageDelayed(UPDATE_STORAGE_HINT, 200); 257844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu } 258b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang } 259b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang 260b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang @Override 2617d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller protected void onPause() { 2625c17d7a077acd1f84bdcb7579f7d02a1094602bcWu-cheng Li super.onPause(); 263b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang LocalBroadcastManager manager = LocalBroadcastManager.getInstance(this); 264b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang manager.unregisterReceiver(mDeletePictureReceiver); 265b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang 266aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li saveThumbnailToFile(); 2674edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong 268c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li if (mLoadThumbnailTask != null) { 269c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mLoadThumbnailTask.cancel(true); 270c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mLoadThumbnailTask = null; 271c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 272c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li 2734edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong if (mStorageHint != null) { 2744edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong mStorageHint.cancel(); 2754edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong mStorageHint = null; 2764edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } 277844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu 278844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu unregisterReceiver(mReceiver); 2797d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller } 2807d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller 2817d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller @Override 28272fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li public void setContentView(int layoutResID) { 28372fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li super.setContentView(layoutResID); 28472fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li // getActionBar() should be after setContentView 28572fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li mActionBar = new GalleryActionBar(this); 28672fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li mActionBar.hide(); 28772fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li } 28872fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li 28972fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li @Override 2904d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang public boolean onSearchRequested() { 2914d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang return false; 2924d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang } 2937673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li 2947673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li @Override 2957673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li public boolean onKeyDown(int keyCode, KeyEvent event) { 2967673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li // Prevent software keyboard or voice search from showing up. 2977673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li if (keyCode == KeyEvent.KEYCODE_SEARCH 2987673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li || keyCode == KeyEvent.KEYCODE_MENU) { 2997673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li if (event.isLongPress()) return true; 3007673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li } 3010703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu if (keyCode == KeyEvent.KEYCODE_MENU && mShowCameraAppView) { 3020703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu return true; 3030703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu } 3047673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li 3057673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li return super.onKeyDown(keyCode, event); 3067673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li } 3075df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li 3080703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu @Override 3090703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu public boolean onKeyUp(int keyCode, KeyEvent event) { 3100703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu if (keyCode == KeyEvent.KEYCODE_MENU && mShowCameraAppView) { 3110703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu return true; 3120703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu } 3130703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu return super.onKeyUp(keyCode, event); 3140703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu } 3150703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu 3165df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li protected void setResultEx(int resultCode) { 3175df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li mResultCodeForTesting = resultCode; 3185df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li setResult(resultCode); 3195df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li } 3205df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li 3215df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li protected void setResultEx(int resultCode, Intent data) { 3225df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li mResultCodeForTesting = resultCode; 3235df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li mResultDataForTesting = data; 3245df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li setResult(resultCode, data); 3255df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li } 3265df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li 3275df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li public int getResultCode() { 3285df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li return mResultCodeForTesting; 3295df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li } 3305df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li 3315df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li public Intent getResultData() { 3325df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li return mResultDataForTesting; 3335df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li } 3345f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang 3355f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang @Override 3365f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang protected void onDestroy() { 3375f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang PopupManager.removeInstance(this); 338d80b2cd48dd5958a0e9f370ce28c483b3a1dd166Wu-cheng Li if (mSecureCamera) unregisterReceiver(mScreenOffReceiver); 3395f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang super.onDestroy(); 3405f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang } 3417d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller 342844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu protected void installIntentFilter() { 343844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu // install an intent filter to receive SD card related events. 344844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu IntentFilter intentFilter = 345844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu new IntentFilter(Intent.ACTION_MEDIA_MOUNTED); 346844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED); 347844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED); 348844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu intentFilter.addAction(Intent.ACTION_MEDIA_CHECKING); 349844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu intentFilter.addDataScheme("file"); 350844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu registerReceiver(mReceiver, intentFilter); 351844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu } 352844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu 353844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu protected void updateStorageSpace() { 354844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu mStorageSpace = Storage.getAvailableSpace(); 355844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu } 356844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu 357844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu protected long getStorageSpace() { 358844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu return mStorageSpace; 359844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu } 360844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu 361844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu protected void updateStorageSpaceAndHint() { 362844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu updateStorageSpace(); 363844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu updateStorageHint(mStorageSpace); 364844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu } 365844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu 366844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu protected void updateStorageHint() { 367844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu updateStorageHint(mStorageSpace); 368844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu } 369844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu 370844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu protected boolean updateStorageHintOnResume() { 371844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu return true; 372844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu } 373844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu 3744edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong protected void updateStorageHint(long storageSpace) { 3754edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong String message = null; 3764edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong if (storageSpace == Storage.UNAVAILABLE) { 3774edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong message = getString(R.string.no_storage); 3784edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } else if (storageSpace == Storage.PREPARING) { 3794edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong message = getString(R.string.preparing_sd); 3804edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } else if (storageSpace == Storage.UNKNOWN_SIZE) { 3814edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong message = getString(R.string.access_sd_fail); 382844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu } else if (storageSpace <= Storage.LOW_STORAGE_THRESHOLD) { 3834edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong message = getString(R.string.spaceIsLow_content); 3844edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } 3854edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong 3864edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong if (message != null) { 3874edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong if (mStorageHint == null) { 3884edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong mStorageHint = OnScreenHint.makeText(this, message); 3894edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } else { 3904edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong mStorageHint.setText(message); 3914edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } 3924edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong mStorageHint.show(); 3934edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } else if (mStorageHint != null) { 3944edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong mStorageHint.cancel(); 3954edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong mStorageHint = null; 3964edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } 3974edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } 398c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li 399a0b7c6b3c61b68db7f4eb33d81c886fb4e095f2cPin Ting protected void updateThumbnailView() { 400d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb if (mThumbnail != null && mThumbnailView != null) { 401c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mThumbnailView.setBitmap(mThumbnail.getBitmap()); 402c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mThumbnailView.setVisibility(View.VISIBLE); 403d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb } else if (mThumbnailView != null) { 404c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mThumbnailView.setBitmap(null); 405c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mThumbnailView.setVisibility(View.GONE); 406c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 407c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 408c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li 409c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li protected void getLastThumbnail() { 410c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mThumbnail = ThumbnailHolder.getLastThumbnail(getContentResolver()); 411c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // Suppose users tap the thumbnail view, go to the gallery, delete the 412c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // image, and coming back to the camera. Thumbnail file will be invalid. 413c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // Since the new thumbnail will be loaded in another thread later, the 414c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // view should be set to gone to prevent from opening the invalid image. 415c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li updateThumbnailView(); 416c1f6c073113e20fd0dbeae6d26dcc651c9049fd7Wu-cheng Li if (mThumbnail == null && !mSecureCamera) { 417b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang mLoadThumbnailTask = new LoadThumbnailTask(true).execute(); 418c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 419c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 420c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li 421b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang protected void getLastThumbnailUncached() { 422c1f6c073113e20fd0dbeae6d26dcc651c9049fd7Wu-cheng Li if (mSecureCamera) { 423c1f6c073113e20fd0dbeae6d26dcc651c9049fd7Wu-cheng Li // Check if the thumbnail is valid. 424c1f6c073113e20fd0dbeae6d26dcc651c9049fd7Wu-cheng Li if (mThumbnail != null && !Util.isUriValid( 425c1f6c073113e20fd0dbeae6d26dcc651c9049fd7Wu-cheng Li mThumbnail.getUri(), getContentResolver())) { 426c1f6c073113e20fd0dbeae6d26dcc651c9049fd7Wu-cheng Li mThumbnail = null; 427c1f6c073113e20fd0dbeae6d26dcc651c9049fd7Wu-cheng Li updateThumbnailView(); 428c1f6c073113e20fd0dbeae6d26dcc651c9049fd7Wu-cheng Li } 429c1f6c073113e20fd0dbeae6d26dcc651c9049fd7Wu-cheng Li } else { 430c1f6c073113e20fd0dbeae6d26dcc651c9049fd7Wu-cheng Li if (mLoadThumbnailTask != null) mLoadThumbnailTask.cancel(true); 431c1f6c073113e20fd0dbeae6d26dcc651c9049fd7Wu-cheng Li mLoadThumbnailTask = new LoadThumbnailTask(false).execute(); 432c1f6c073113e20fd0dbeae6d26dcc651c9049fd7Wu-cheng Li } 433b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang } 434b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang 435aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li private class LoadThumbnailTask extends AsyncTask<Void, Void, Thumbnail> { 436b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang private boolean mLookAtCache; 437b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang 438b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang public LoadThumbnailTask(boolean lookAtCache) { 439b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang mLookAtCache = lookAtCache; 440b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang } 441b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang 442c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li @Override 443c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li protected Thumbnail doInBackground(Void... params) { 444c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // Load the thumbnail from the file. 445c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li ContentResolver resolver = getContentResolver(); 446b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang Thumbnail t = null; 447b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang if (mLookAtCache) { 448b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang t = Thumbnail.getLastThumbnailFromFile(getFilesDir(), resolver); 449b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang } 450c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li 451c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li if (isCancelled()) return null; 452c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li 453c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li if (t == null) { 454b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang Thumbnail result[] = new Thumbnail[1]; 455c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // Load the thumbnail from the media provider. 456b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang int code = Thumbnail.getLastThumbnailFromContentResolver( 457b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang resolver, result); 458b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang switch (code) { 459b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang case Thumbnail.THUMBNAIL_FOUND: 460b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang return result[0]; 461b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang case Thumbnail.THUMBNAIL_NOT_FOUND: 462b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang return null; 463b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang case Thumbnail.THUMBNAIL_DELETED: 464b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang cancel(true); 465b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang return null; 466b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang } 467c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 468c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li return t; 469c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 470c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li 471c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li @Override 472c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li protected void onPostExecute(Thumbnail thumbnail) { 473b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang if (isCancelled()) return; 474c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mThumbnail = thumbnail; 475c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li updateThumbnailView(); 476c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 477c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 478aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li 4796899a30e3a89ad4b455978140682d5ba871c1b33Pin Ting protected void gotoGallery() { 480252da3c55a35c77fa4be4d51f79dac4aaf7cdb77Pin Ting // Move the next picture with capture animation. "1" means next. 481252da3c55a35c77fa4be4d51f79dac4aaf7cdb77Pin Ting mAppBridge.switchWithCaptureAnimation(1); 4826899a30e3a89ad4b455978140682d5ba871c1b33Pin Ting } 4836899a30e3a89ad4b455978140682d5ba871c1b33Pin Ting 484aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li protected void saveThumbnailToFile() { 485aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li if (mThumbnail != null && !mThumbnail.fromFile()) { 486aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li new SaveThumbnailTask().execute(mThumbnail); 487aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li } 488aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li } 489aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li 490aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li private class SaveThumbnailTask extends AsyncTask<Thumbnail, Void, Void> { 491aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li @Override 492aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li protected Void doInBackground(Thumbnail... params) { 493aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li final int n = params.length; 494aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li final File filesDir = getFilesDir(); 495aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li for (int i = 0; i < n; i++) { 496aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li params[i].saveLastThumbnailToFile(filesDir); 497aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li } 498aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li return null; 499aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li } 500aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li } 501a6b966047b6215b02c502a3f143106070abf6009Angus Kong 502a6b966047b6215b02c502a3f143106070abf6009Angus Kong // Call this after setContentView. 503e14d9149a501183d3b785f4f4aa484c4b85192d1George Mount public ScreenNail createCameraScreenNail(boolean getPictures) { 504a6b966047b6215b02c502a3f143106070abf6009Angus Kong mCameraAppView = findViewById(R.id.camera_app_root); 505a6b966047b6215b02c502a3f143106070abf6009Angus Kong Bundle data = new Bundle(); 50688e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li String path; 507ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li if (getPictures) { 508ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li if (mSecureCamera) { 509ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li path = "/secure/all/" + sSecureAlbumId; 510ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li } else { 511ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li path = "/local/all/" + MediaSetUtils.CAMERA_BUCKET_ID; 512ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li } 51388e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li } else { 514ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li path = "/local/all/0"; // Use 0 so gallery does not show anything. 51588e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li } 516a6b966047b6215b02c502a3f143106070abf6009Angus Kong data.putString(PhotoPage.KEY_MEDIA_SET_PATH, path); 517a6b966047b6215b02c502a3f143106070abf6009Angus Kong data.putString(PhotoPage.KEY_MEDIA_ITEM_PATH, path); 518ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li data.putBoolean(PhotoPage.KEY_SHOW_WHEN_LOCKED, mSecureCamera); 519a6b966047b6215b02c502a3f143106070abf6009Angus Kong 52078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang // Send an AppBridge to gallery to enable the camera preview. 52178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang mAppBridge = new MyAppBridge(); 52278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang data.putParcelable(PhotoPage.KEY_APP_BRIDGE, mAppBridge); 5238e887b3911f3c182011c20d709832755d96a5959Doris Liu if (getStateManager().getStateCount() == 0) { 5248e887b3911f3c182011c20d709832755d96a5959Doris Liu getStateManager().startState(PhotoPage.class, data); 5258e887b3911f3c182011c20d709832755d96a5959Doris Liu } else { 5268e887b3911f3c182011c20d709832755d96a5959Doris Liu getStateManager().switchState(getStateManager().getTopState(), 5278e887b3911f3c182011c20d709832755d96a5959Doris Liu PhotoPage.class, data); 5288e887b3911f3c182011c20d709832755d96a5959Doris Liu } 52978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang mCameraScreenNail = mAppBridge.getCameraScreenNail(); 530e14d9149a501183d3b785f4f4aa484c4b85192d1George Mount return mCameraScreenNail; 531a6b966047b6215b02c502a3f143106070abf6009Angus Kong } 532a6b966047b6215b02c502a3f143106070abf6009Angus Kong 533d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb // Call this after setContentView. 534e14d9149a501183d3b785f4f4aa484c4b85192d1George Mount protected ScreenNail reuseCameraScreenNail(boolean getPictures) { 535d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb mCameraAppView = findViewById(R.id.camera_app_root); 536d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb Bundle data = new Bundle(); 537d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb String path; 538ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li if (getPictures) { 539ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li if (mSecureCamera) { 540ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li path = "/secure/all/" + sSecureAlbumId; 541ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li } else { 542ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li path = "/local/all/" + MediaSetUtils.CAMERA_BUCKET_ID; 543ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li } 544d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb } else { 545ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li path = "/local/all/0"; // Use 0 so gallery does not show anything. 546d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb } 547d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb data.putString(PhotoPage.KEY_MEDIA_SET_PATH, path); 548d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb data.putString(PhotoPage.KEY_MEDIA_ITEM_PATH, path); 549ce51afce8c74f2c68e386b2a8f35c4be6772b760Wu-cheng Li data.putBoolean(PhotoPage.KEY_SHOW_WHEN_LOCKED, mSecureCamera); 550d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb 551d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb // Send an AppBridge to gallery to enable the camera preview. 552d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb if (mAppBridge == null) { 553d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb mAppBridge = new MyAppBridge(); 554d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb } 555d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb data.putParcelable(PhotoPage.KEY_APP_BRIDGE, mAppBridge); 556d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb if (getStateManager().getStateCount() == 0) { 557d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb getStateManager().startState(PhotoPage.class, data); 558d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb } 559d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb mCameraScreenNail = mAppBridge.getCameraScreenNail(); 560e14d9149a501183d3b785f4f4aa484c4b85192d1George Mount return mCameraScreenNail; 561d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb } 562d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb 56347a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang private class HideCameraAppView implements Animation.AnimationListener { 5641cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li @Override 56547a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang public void onAnimationEnd(Animation animation) { 566f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang // We cannot set this as GONE because we want to receive the 567f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang // onLayoutChange() callback even when we are invisible. 568f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang mCameraAppView.setVisibility(View.INVISIBLE); 5691cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li } 57047a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang 57147a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang @Override 57247a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang public void onAnimationRepeat(Animation animation) { 57347a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang } 57447a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang 57547a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang @Override 57647a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang public void onAnimationStart(Animation animation) { 57747a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang } 5781cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li } 57978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 580c94cd4a5206b05541de0dc8a4821c64d0edba352Angus Kong protected void updateCameraAppView() { 58147a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang // Initialize the animation. 58247a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang if (mCameraAppViewFadeIn == null) { 58347a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang mCameraAppViewFadeIn = new AlphaAnimation(0f, 1f); 58447a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang mCameraAppViewFadeIn.setDuration(CAMERA_APP_VIEW_TOGGLE_TIME); 58547a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang mCameraAppViewFadeIn.setInterpolator(new DecelerateInterpolator()); 58647a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang 58747a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang mCameraAppViewFadeOut = new AlphaAnimation(1f, 0f); 58847a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang mCameraAppViewFadeOut.setDuration(CAMERA_APP_VIEW_TOGGLE_TIME); 58947a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang mCameraAppViewFadeOut.setInterpolator(new DecelerateInterpolator()); 59047a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang mCameraAppViewFadeOut.setAnimationListener(new HideCameraAppView()); 59147a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang } 59247a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang 59378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang if (mShowCameraAppView) { 59478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang mCameraAppView.setVisibility(View.VISIBLE); 595d20805f3162b8004cc840230bc8d9c864b114401Wu-cheng Li // The "transparent region" is not recomputed when a sibling of 596d20805f3162b8004cc840230bc8d9c864b114401Wu-cheng Li // SurfaceView changes visibility (unless it involves GONE). It's 597d20805f3162b8004cc840230bc8d9c864b114401Wu-cheng Li // been broken since 1.0. Call requestLayout to work around it. 598d20805f3162b8004cc840230bc8d9c864b114401Wu-cheng Li mCameraAppView.requestLayout(); 59947a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang mCameraAppView.startAnimation(mCameraAppViewFadeIn); 60078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } else { 60147a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang mCameraAppView.startAnimation(mCameraAppViewFadeOut); 602a6b966047b6215b02c502a3f143106070abf6009Angus Kong } 603a6b966047b6215b02c502a3f143106070abf6009Angus Kong } 604a6b966047b6215b02c502a3f143106070abf6009Angus Kong 6058e3ccacccd2b128734322877561b8b78a70e103bWu-cheng Li protected void onFullScreenChanged(boolean full) { 60678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang if (mShowCameraAppView == full) return; 60778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang mShowCameraAppView = full; 60878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang if (mPaused || isFinishing()) return; 60978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang updateCameraAppView(); 610b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang 611b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang // If we received DELETE_PICTURE broadcasts while the Camera UI is 612b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang // hidden, we update the thumbnail now. 613b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang if (full && mUpdateThumbnailDelayed) { 614b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang getLastThumbnailUncached(); 615b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang mUpdateThumbnailDelayed = false; 616b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang } 617a6b966047b6215b02c502a3f143106070abf6009Angus Kong } 618a6b966047b6215b02c502a3f143106070abf6009Angus Kong 619a6b966047b6215b02c502a3f143106070abf6009Angus Kong @Override 620a6b966047b6215b02c502a3f143106070abf6009Angus Kong public GalleryActionBar getGalleryActionBar() { 621a6b966047b6215b02c502a3f143106070abf6009Angus Kong return mActionBar; 622a6b966047b6215b02c502a3f143106070abf6009Angus Kong } 6238a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li 62478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang // Preview frame layout has changed. 6258a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li @Override 626525667ff4b93a577298085fe45660a2d15b0bd06Angus Kong public void onLayoutChange(View v, int left, int top, int right, int bottom) { 62778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang if (mAppBridge == null) return; 62878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 62940d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li int width = right - left; 63040d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li int height = bottom - top; 631c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li if (ApiHelper.HAS_SURFACE_TEXTURE) { 632c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li CameraScreenNail screenNail = (CameraScreenNail) mCameraScreenNail; 633c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li if (Util.getDisplayRotation(this) % 180 == 0) { 634c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li screenNail.setPreviewFrameLayoutSize(width, height); 635c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li } else { 636c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li // Swap the width and height. Camera screen nail draw() is based on 637c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li // natural orientation, not the view system orientation. 638c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li screenNail.setPreviewFrameLayoutSize(height, width); 639c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li } 64040d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li } 64176507a9fd2581694942a662a57fbdd46d7a20036Wu-cheng Li 64278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang // Find out the coordinates of the preview frame relative to GL 6438a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li // root view. 6448a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li View root = (View) getGLRoot(); 6458a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li int[] rootLocation = new int[2]; 6468a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li int[] viewLocation = new int[2]; 6478a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li root.getLocationInWindow(rootLocation); 6488a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li v.getLocationInWindow(viewLocation); 64978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 65078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang int l = viewLocation[0] - rootLocation[0]; 65178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang int t = viewLocation[1] - rootLocation[1]; 65240d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li int r = l + width; 65340d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li int b = t + height; 654f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang Rect frame = new Rect(l, t, r, b); 655f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang Log.d(TAG, "set CameraRelativeFrame as " + frame); 656f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang mAppBridge.setCameraRelativeFrame(frame); 6578a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li } 658bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li 659bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li protected void setSingleTapUpListener(View singleTapArea) { 660bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li mSingleTapArea = singleTapArea; 661bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li } 662bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li 66378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang private boolean onSingleTapUp(int x, int y) { 66417de506c16816a9874a5417be402345b9882e0a4Wu-cheng Li // Ignore if listener is null or the camera control is invisible. 66517de506c16816a9874a5417be402345b9882e0a4Wu-cheng Li if (mSingleTapArea == null || !mShowCameraAppView) return false; 666bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li 667bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li int[] relativeLocation = Util.getRelativeLocation((View) getGLRoot(), 668bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li mSingleTapArea); 669bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li x -= relativeLocation[0]; 670bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li y -= relativeLocation[1]; 671bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li if (x >= 0 && x < mSingleTapArea.getWidth() && y >= 0 672bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li && y < mSingleTapArea.getHeight()) { 673bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li onSingleTapUp(mSingleTapArea, x, y); 674bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li return true; 675bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li } 676bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li return false; 677bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li } 678bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li 679bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li protected void onSingleTapUp(View view, int x, int y) { 680bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li } 68178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 682cfbf201b06095591a2ae91af2aa4b97a9c4ae9a5George Mount public void setSwipingEnabled(boolean enabled) { 683d03d34ac9f50857f38034749607ce07c161d5120Chih-Chung Chang mAppBridge.setSwipingEnabled(enabled); 68478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 68578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 686e14d9149a501183d3b785f4f4aa484c4b85192d1George Mount public void notifyScreenNailChanged() { 687a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang mAppBridge.notifyScreenNailChanged(); 688a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang } 689a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang 690a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li protected void onPreviewTextureCopied() { 691a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li } 69278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 69388e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li protected void addSecureAlbumItemIfNeeded(boolean isVideo, Uri uri) { 69488e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li if (mSecureCamera) { 69588e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li int id = Integer.parseInt(uri.getLastPathSegment()); 69688e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li mAppBridge.addSecureAlbumItem(isVideo, id); 69788e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li } 69888e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li } 69988e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li 7007717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li public boolean isSecureCamera() { 7017717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li return mSecureCamera; 7027717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li } 7037717d2f0fc0e1393971cab44b3bba8a0f1297835Wu-cheng Li 70478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang ////////////////////////////////////////////////////////////////////////// 70578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang // The is the communication interface between the Camera Application and 70678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang // the Gallery PhotoPage. 70778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang ////////////////////////////////////////////////////////////////////////// 70878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 709a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li class MyAppBridge extends AppBridge implements CameraScreenNail.Listener { 710dac1bb32531f7f4d49622bd38c82dde9333c38acAhbong Chang @SuppressWarnings("hiding") 711c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li private ScreenNail mCameraScreenNail; 71278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang private Server mServer; 71378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 71478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang @Override 71578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang public ScreenNail attachScreenNail() { 716a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang if (mCameraScreenNail == null) { 717c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li if (ApiHelper.HAS_SURFACE_TEXTURE) { 718c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li mCameraScreenNail = new CameraScreenNail(this); 719c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li } else { 720195f07f83be795b2dfc0cdd12636a2eb4afedd86Wu-cheng Li Bitmap b = BitmapFactory.decodeResource(getResources(), 721195f07f83be795b2dfc0cdd12636a2eb4afedd86Wu-cheng Li R.drawable.wallpaper_picker_preview); 722195f07f83be795b2dfc0cdd12636a2eb4afedd86Wu-cheng Li mCameraScreenNail = new StaticBitmapScreenNail(b); 723c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li } 724a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang } 72578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang return mCameraScreenNail; 72678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 72778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 72878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang @Override 72978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang public void detachScreenNail() { 73078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang mCameraScreenNail = null; 73178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 73278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 733c82461e017eed0c8bf73a646d782be3bb4f8d817Wu-cheng Li public ScreenNail getCameraScreenNail() { 73478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang return mCameraScreenNail; 73578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 73678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 73778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang // Return true if the tap is consumed. 73878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang @Override 73978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang public boolean onSingleTapUp(int x, int y) { 74078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang return ActivityBase.this.onSingleTapUp(x, y); 74178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 74278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 74378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang // This is used to notify that the screen nail will be drawn in full screen 74478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang // or not in next draw() call. 74578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang @Override 74678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang public void onFullScreenChanged(boolean full) { 74778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang ActivityBase.this.onFullScreenChanged(full); 74878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 74978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 75078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang @Override 75178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang public void requestRender() { 75278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang getGLRoot().requestRender(); 75378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 75478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 75578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang @Override 756a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li public void onPreviewTextureCopied() { 757a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li ActivityBase.this.onPreviewTextureCopied(); 758a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li } 759a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li 760a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li @Override 76178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang public void setServer(Server s) { 76278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang mServer = s; 76378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 76478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 76505e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong @Override 76605e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong public boolean isPanorama() { 76705e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong return ActivityBase.this.isPanoramaActivity(); 76805e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong } 76905e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong 770a96d8603560c2131d1555df82b8f64c6eb06909cWu-cheng Li @Override 771a96d8603560c2131d1555df82b8f64c6eb06909cWu-cheng Li public boolean isStaticCamera() { 772a96d8603560c2131d1555df82b8f64c6eb06909cWu-cheng Li return !ApiHelper.HAS_SURFACE_TEXTURE; 773a96d8603560c2131d1555df82b8f64c6eb06909cWu-cheng Li } 774a96d8603560c2131d1555df82b8f64c6eb06909cWu-cheng Li 77588e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li public void addSecureAlbumItem(boolean isVideo, int id) { 77688e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li if (mServer != null) mServer.addSecureAlbumItem(isVideo, id); 77788e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li } 77888e9e4f88caeddac4343638eb72684c70ef3d797Wu-cheng Li 779f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang private void setCameraRelativeFrame(Rect frame) { 780f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang if (mServer != null) mServer.setCameraRelativeFrame(frame); 78178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 78278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 78378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang private void switchWithCaptureAnimation(int offset) { 78478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang if (mServer != null) mServer.switchWithCaptureAnimation(offset); 78578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 786d03d34ac9f50857f38034749607ce07c161d5120Chih-Chung Chang 787d03d34ac9f50857f38034749607ce07c161d5120Chih-Chung Chang private void setSwipingEnabled(boolean enabled) { 788d03d34ac9f50857f38034749607ce07c161d5120Chih-Chung Chang if (mServer != null) mServer.setSwipingEnabled(enabled); 789d03d34ac9f50857f38034749607ce07c161d5120Chih-Chung Chang } 790a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang 791a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang private void notifyScreenNailChanged() { 792a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang if (mServer != null) mServer.notifyScreenNailChanged(); 793a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang } 79478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 7954d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang} 796