ActivityBase.java revision 8e3ccacccd2b128734322877561b8b78a70e103b
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; 2478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Changimport android.graphics.Rect; 25296d27772b9543d55820e1d24d900fea959f1b7aPin Tingimport android.hardware.Camera.Parameters; 26c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Liimport android.os.AsyncTask; 278608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Changimport android.os.Bundle; 28844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescuimport android.os.Handler; 29844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescuimport android.os.Message; 30b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Changimport android.support.v4.content.LocalBroadcastManager; 317d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Millerimport android.util.Log; 324c7b291018e08dbb4bc1712d95117a294fa1416cWu-cheng Liimport android.view.KeyEvent; 33c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Liimport android.view.View; 34a6b966047b6215b02c502a3f143106070abf6009Angus Kongimport android.view.Window; 35892781804513066b68b4a2fa6f846e862dac252aOwen Linimport android.view.WindowManager; 36525667ff4b93a577298085fe45660a2d15b0bd06Angus Kongimport android.view.animation.AlphaAnimation; 37525667ff4b93a577298085fe45660a2d15b0bd06Angus Kongimport android.view.animation.Animation; 38a029bd9976ebb618f321e8740c86b0f5d681d241Owen Linimport android.view.animation.DecelerateInterpolator; 39892781804513066b68b4a2fa6f846e862dac252aOwen Lin 40d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Liimport com.android.camera.ui.CameraPicker; 41525667ff4b93a577298085fe45660a2d15b0bd06Angus Kongimport com.android.camera.ui.LayoutChangeNotifier; 42892781804513066b68b4a2fa6f846e862dac252aOwen Linimport com.android.camera.ui.PopupManager; 43892781804513066b68b4a2fa6f846e862dac252aOwen Linimport com.android.camera.ui.RotateImageView; 44a6b966047b6215b02c502a3f143106070abf6009Angus Kongimport com.android.gallery3d.app.AbstractGalleryActivity; 4578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Changimport com.android.gallery3d.app.AppBridge; 46a6b966047b6215b02c502a3f143106070abf6009Angus Kongimport com.android.gallery3d.app.GalleryActionBar; 47a029bd9976ebb618f321e8740c86b0f5d681d241Owen Linimport com.android.gallery3d.app.PhotoPage; 4878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Changimport com.android.gallery3d.ui.ScreenNail; 49a6b966047b6215b02c502a3f143106070abf6009Angus Kongimport com.android.gallery3d.util.MediaSetUtils; 504d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang 51aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Liimport java.io.File; 52aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li 5377c1cdc8f2cda250b1db842204efb49f87e094aeChih-Chung Chang/** 547673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li * Superclass of Camera and VideoCamera activities. 5577c1cdc8f2cda250b1db842204efb49f87e094aeChih-Chung Chang */ 56525667ff4b93a577298085fe45660a2d15b0bd06Angus Kongpublic abstract class ActivityBase extends AbstractGalleryActivity 57525667ff4b93a577298085fe45660a2d15b0bd06Angus Kong implements LayoutChangeNotifier.Listener { 58a6b966047b6215b02c502a3f143106070abf6009Angus Kong 597d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller private static final String TAG = "ActivityBase"; 6076507a9fd2581694942a662a57fbdd46d7a20036Wu-cheng Li private static final boolean LOGV = false; 61c38faeb66a3f2cc96e4c5e951228d9b01e12edb3Chih-Chung Chang private static final int CAMERA_APP_VIEW_TOGGLE_TIME = 100; // milliseconds 62b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang private static final String ACTION_DELETE_PICTURE = 63b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang "com.android.gallery3d.action.DELETE_PICTURE"; 6447a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang 655df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li private int mResultCodeForTesting; 665df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li private Intent mResultDataForTesting; 674edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong private OnScreenHint mStorageHint; 68bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li private View mSingleTapArea; 69a6b966047b6215b02c502a3f143106070abf6009Angus Kong 70c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // The bitmap of the last captured picture thumbnail and the URI of the 71c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // original picture. 72c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li protected Thumbnail mThumbnail; 738a674bebfba0c4dd4b01018276d20f198f65f19eWu-cheng Li protected int mThumbnailViewWidth; // layout width of the thumbnail 74c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li protected AsyncTask<Void, Void, Thumbnail> mLoadThumbnailTask; 75d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li // An imageview showing the last captured picture thumbnail. 76d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li protected RotateImageView mThumbnailView; 77d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li protected CameraPicker mCameraPicker; 78d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li 79475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting protected boolean mOpenCameraFail; 80475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting protected boolean mCameraDisabled; 81475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting protected CameraManager.CameraProxy mCameraDevice; 82296d27772b9543d55820e1d24d900fea959f1b7aPin Ting protected Parameters mParameters; 835c17d7a077acd1f84bdcb7579f7d02a1094602bcWu-cheng Li // The activity is paused. The classes that extend this class should set 845c17d7a077acd1f84bdcb7579f7d02a1094602bcWu-cheng Li // mPaused the first thing in onResume/onPause. 855c17d7a077acd1f84bdcb7579f7d02a1094602bcWu-cheng Li protected boolean mPaused; 86a6b966047b6215b02c502a3f143106070abf6009Angus Kong protected GalleryActionBar mActionBar; 87475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting 88475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting // multiple cameras support 89475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting protected int mNumberOfCameras; 90475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting protected int mCameraId; 91d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li // The activity is going to switch to the specified camera id. This is 92d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li // needed because texture copy is done in GL thread. -1 means camera is not 93d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li // switching. 94d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li protected int mPendingSwitchCameraId = -1; 95475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting 9678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang protected MyAppBridge mAppBridge; 97a6b966047b6215b02c502a3f143106070abf6009Angus Kong protected CameraScreenNail mCameraScreenNail; // This shows camera preview. 98a6b966047b6215b02c502a3f143106070abf6009Angus Kong // The view containing only camera related widgets like control panel, 99a6b966047b6215b02c502a3f143106070abf6009Angus Kong // indicator bar, focus indicator and etc. 100a6b966047b6215b02c502a3f143106070abf6009Angus Kong protected View mCameraAppView; 1011cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li protected boolean mShowCameraAppView = true; 10247a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang private Animation mCameraAppViewFadeIn; 10347a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang private Animation mCameraAppViewFadeOut; 10447a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang 105844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu private long mStorageSpace = Storage.LOW_STORAGE_THRESHOLD; 106844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu private static final int UPDATE_STORAGE_HINT = 0; 107844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu private final Handler mHandler = new Handler() { 108844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu @Override 109844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu public void handleMessage(Message msg) { 110844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu switch (msg.what) { 111844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu case UPDATE_STORAGE_HINT: 112844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu updateStorageHint(); 113844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu return; 114844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu } 115844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu } 116844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu }; 117844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu 118844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 119844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu @Override 120844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu public void onReceive(Context context, Intent intent) { 121844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu String action = intent.getAction(); 122844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu if (action.equals(Intent.ACTION_MEDIA_MOUNTED) 123844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu || action.equals(Intent.ACTION_MEDIA_UNMOUNTED) 124844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu || action.equals(Intent.ACTION_MEDIA_CHECKING) 125844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu || action.equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) { 126844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu updateStorageSpaceAndHint(); 127844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu } 128844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu } 129844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu }; 130844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu 131b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang private boolean mUpdateThumbnailDelayed; 132b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang private IntentFilter mDeletePictureFilter = 133b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang new IntentFilter(ACTION_DELETE_PICTURE); 134b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang private BroadcastReceiver mDeletePictureReceiver = 135b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang new BroadcastReceiver() { 136b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang @Override 137b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang public void onReceive(Context context, Intent intent) { 138b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang if (mShowCameraAppView) { 139b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang getLastThumbnailUncached(); 140b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang } else { 141b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang mUpdateThumbnailDelayed = true; 142b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang } 143b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang } 144b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang }; 145a6b966047b6215b02c502a3f143106070abf6009Angus Kong 146475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting protected class CameraOpenThread extends Thread { 147475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting @Override 148475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting public void run() { 149475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting try { 150475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting mCameraDevice = Util.openCamera(ActivityBase.this, mCameraId); 151296d27772b9543d55820e1d24d900fea959f1b7aPin Ting mParameters = mCameraDevice.getParameters(); 152475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting } catch (CameraHardwareException e) { 153475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting mOpenCameraFail = true; 154475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting } catch (CameraDisabledException e) { 155475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting mCameraDisabled = true; 156475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting } 157475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting } 158475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting } 1595df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li 1604d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang @Override 1618608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Chang public void onCreate(Bundle icicle) { 162e5b6a36e64ef2c2cb1435c138a5fc179e9a6bc9aWu-cheng Li getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE); 1636a4a72b643929701c5d7c8b68b91d762c7277c20Wu-cheng Li super.disableToggleStatusBar(); 164a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin // Set a theme with action bar. It is not specified in manifest because 165a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin // we want to hide it by default. setTheme must happen before 166a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin // setContentView. 167a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin // 168a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin // This must be set before we call super.onCreate(), where the window's 169a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin // background is removed. 170a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin setTheme(R.style.Theme_Gallery); 171a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); 172a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY); 173a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin 1748608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Chang super.onCreate(icicle); 1758608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Chang } 1768608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Chang 17705e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong public boolean isPanoramaActivity() { 17805e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong return false; 17905e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong } 18005e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong 1818608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Chang @Override 182b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang protected void onResume() { 183b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang super.onResume(); 184b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang LocalBroadcastManager manager = LocalBroadcastManager.getInstance(this); 185b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang manager.registerReceiver(mDeletePictureReceiver, mDeletePictureFilter); 186844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu 187844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu installIntentFilter(); 188844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu if(updateStorageHintOnResume()) { 189844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu updateStorageSpace(); 190844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu mHandler.sendEmptyMessageDelayed(UPDATE_STORAGE_HINT, 200); 191844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu } 192b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang } 193b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang 194b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang @Override 1957d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller protected void onPause() { 1965c17d7a077acd1f84bdcb7579f7d02a1094602bcWu-cheng Li super.onPause(); 197b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang LocalBroadcastManager manager = LocalBroadcastManager.getInstance(this); 198b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang manager.unregisterReceiver(mDeletePictureReceiver); 199b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang 2007d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller if (LOGV) Log.v(TAG, "onPause"); 201aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li saveThumbnailToFile(); 2024edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong 203c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li if (mLoadThumbnailTask != null) { 204c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mLoadThumbnailTask.cancel(true); 205c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mLoadThumbnailTask = null; 206c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 207c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li 2084edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong if (mStorageHint != null) { 2094edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong mStorageHint.cancel(); 2104edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong mStorageHint = null; 2114edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } 212844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu 213844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu unregisterReceiver(mReceiver); 2147d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller } 2157d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller 2167d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller @Override 21772fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li public void setContentView(int layoutResID) { 21872fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li super.setContentView(layoutResID); 21972fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li // getActionBar() should be after setContentView 22072fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li mActionBar = new GalleryActionBar(this); 22172fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li mActionBar.hide(); 22272fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li } 22372fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li 22472fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li @Override 2254d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang public boolean onSearchRequested() { 2264d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang return false; 2274d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang } 2287673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li 2297673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li @Override 2307673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li public boolean onKeyDown(int keyCode, KeyEvent event) { 2317673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li // Prevent software keyboard or voice search from showing up. 2327673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li if (keyCode == KeyEvent.KEYCODE_SEARCH 2337673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li || keyCode == KeyEvent.KEYCODE_MENU) { 2347673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li if (event.isLongPress()) return true; 2357673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li } 2360703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu if (keyCode == KeyEvent.KEYCODE_MENU && mShowCameraAppView) { 2370703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu return true; 2380703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu } 2397673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li 2407673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li return super.onKeyDown(keyCode, event); 2417673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li } 2425df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li 2430703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu @Override 2440703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu public boolean onKeyUp(int keyCode, KeyEvent event) { 2450703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu if (keyCode == KeyEvent.KEYCODE_MENU && mShowCameraAppView) { 2460703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu return true; 2470703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu } 2480703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu return super.onKeyUp(keyCode, event); 2490703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu } 2500703fec905d13cff403955fdffdd99b1ce17113fBobby Georgescu 2515df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li protected void setResultEx(int resultCode) { 2525df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li mResultCodeForTesting = resultCode; 2535df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li setResult(resultCode); 2545df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li } 2555df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li 2565df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li protected void setResultEx(int resultCode, Intent data) { 2575df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li mResultCodeForTesting = resultCode; 2585df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li mResultDataForTesting = data; 2595df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li setResult(resultCode, data); 2605df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li } 2615df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li 2625df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li public int getResultCode() { 2635df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li return mResultCodeForTesting; 2645df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li } 2655df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li 2665df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li public Intent getResultData() { 2675df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li return mResultDataForTesting; 2685df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li } 2695f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang 2705f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang @Override 2715f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang protected void onDestroy() { 2725f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang PopupManager.removeInstance(this); 2735f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang super.onDestroy(); 2745f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang } 2757d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller 276844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu protected void installIntentFilter() { 277844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu // install an intent filter to receive SD card related events. 278844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu IntentFilter intentFilter = 279844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu new IntentFilter(Intent.ACTION_MEDIA_MOUNTED); 280844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED); 281844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED); 282844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu intentFilter.addAction(Intent.ACTION_MEDIA_CHECKING); 283844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu intentFilter.addDataScheme("file"); 284844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu registerReceiver(mReceiver, intentFilter); 285844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu } 286844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu 287844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu protected void updateStorageSpace() { 288844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu mStorageSpace = Storage.getAvailableSpace(); 289844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu } 290844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu 291844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu protected long getStorageSpace() { 292844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu return mStorageSpace; 293844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu } 294844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu 295844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu protected void updateStorageSpaceAndHint() { 296844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu updateStorageSpace(); 297844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu updateStorageHint(mStorageSpace); 298844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu } 299844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu 300844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu protected void updateStorageHint() { 301844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu updateStorageHint(mStorageSpace); 302844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu } 303844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu 304844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu protected boolean updateStorageHintOnResume() { 305844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu return true; 306844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu } 307844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu 3084edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong protected void updateStorageHint(long storageSpace) { 3094edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong String message = null; 3104edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong if (storageSpace == Storage.UNAVAILABLE) { 3114edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong message = getString(R.string.no_storage); 3124edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } else if (storageSpace == Storage.PREPARING) { 3134edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong message = getString(R.string.preparing_sd); 3144edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } else if (storageSpace == Storage.UNKNOWN_SIZE) { 3154edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong message = getString(R.string.access_sd_fail); 316844d5d3043103f968beb77a6aa857d5f904d8fccBobby Georgescu } else if (storageSpace <= Storage.LOW_STORAGE_THRESHOLD) { 3174edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong message = getString(R.string.spaceIsLow_content); 3184edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } 3194edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong 3204edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong if (message != null) { 3214edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong if (mStorageHint == null) { 3224edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong mStorageHint = OnScreenHint.makeText(this, message); 3234edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } else { 3244edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong mStorageHint.setText(message); 3254edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } 3264edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong mStorageHint.show(); 3274edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } else if (mStorageHint != null) { 3284edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong mStorageHint.cancel(); 3294edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong mStorageHint = null; 3304edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } 3314edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } 332c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li 333a0b7c6b3c61b68db7f4eb33d81c886fb4e095f2cPin Ting protected void updateThumbnailView() { 334c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li if (mThumbnail != null) { 335c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mThumbnailView.setBitmap(mThumbnail.getBitmap()); 336c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mThumbnailView.setVisibility(View.VISIBLE); 337c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } else { 338c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mThumbnailView.setBitmap(null); 339c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mThumbnailView.setVisibility(View.GONE); 340c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 341c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 342c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li 343c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li protected void getLastThumbnail() { 344c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mThumbnail = ThumbnailHolder.getLastThumbnail(getContentResolver()); 345c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // Suppose users tap the thumbnail view, go to the gallery, delete the 346c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // image, and coming back to the camera. Thumbnail file will be invalid. 347c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // Since the new thumbnail will be loaded in another thread later, the 348c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // view should be set to gone to prevent from opening the invalid image. 349c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li updateThumbnailView(); 350c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li if (mThumbnail == null) { 351b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang mLoadThumbnailTask = new LoadThumbnailTask(true).execute(); 352c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 353c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 354c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li 355b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang protected void getLastThumbnailUncached() { 356b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang if (mLoadThumbnailTask != null) mLoadThumbnailTask.cancel(true); 357b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang mLoadThumbnailTask = new LoadThumbnailTask(false).execute(); 358b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang } 359b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang 360aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li private class LoadThumbnailTask extends AsyncTask<Void, Void, Thumbnail> { 361b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang private boolean mLookAtCache; 362b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang 363b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang public LoadThumbnailTask(boolean lookAtCache) { 364b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang mLookAtCache = lookAtCache; 365b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang } 366b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang 367c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li @Override 368c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li protected Thumbnail doInBackground(Void... params) { 369c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // Load the thumbnail from the file. 370c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li ContentResolver resolver = getContentResolver(); 371b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang Thumbnail t = null; 372b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang if (mLookAtCache) { 373b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang t = Thumbnail.getLastThumbnailFromFile(getFilesDir(), resolver); 374b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang } 375c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li 376c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li if (isCancelled()) return null; 377c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li 378c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li if (t == null) { 379b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang Thumbnail result[] = new Thumbnail[1]; 380c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // Load the thumbnail from the media provider. 381b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang int code = Thumbnail.getLastThumbnailFromContentResolver( 382b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang resolver, result); 383b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang switch (code) { 384b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang case Thumbnail.THUMBNAIL_FOUND: 385b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang return result[0]; 386b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang case Thumbnail.THUMBNAIL_NOT_FOUND: 387b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang return null; 388b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang case Thumbnail.THUMBNAIL_DELETED: 389b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang cancel(true); 390b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang return null; 391b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang } 392c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 393c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li return t; 394c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 395c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li 396c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li @Override 397c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li protected void onPostExecute(Thumbnail thumbnail) { 398b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang if (isCancelled()) return; 399c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mThumbnail = thumbnail; 400c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li updateThumbnailView(); 401c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 402c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 403aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li 4046899a30e3a89ad4b455978140682d5ba871c1b33Pin Ting protected void gotoGallery() { 405252da3c55a35c77fa4be4d51f79dac4aaf7cdb77Pin Ting // Move the next picture with capture animation. "1" means next. 406252da3c55a35c77fa4be4d51f79dac4aaf7cdb77Pin Ting mAppBridge.switchWithCaptureAnimation(1); 4076899a30e3a89ad4b455978140682d5ba871c1b33Pin Ting } 4086899a30e3a89ad4b455978140682d5ba871c1b33Pin Ting 409aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li protected void saveThumbnailToFile() { 410aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li if (mThumbnail != null && !mThumbnail.fromFile()) { 411aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li new SaveThumbnailTask().execute(mThumbnail); 412aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li } 413aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li } 414aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li 415aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li private class SaveThumbnailTask extends AsyncTask<Thumbnail, Void, Void> { 416aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li @Override 417aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li protected Void doInBackground(Thumbnail... params) { 418aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li final int n = params.length; 419aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li final File filesDir = getFilesDir(); 420aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li for (int i = 0; i < n; i++) { 421aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li params[i].saveLastThumbnailToFile(filesDir); 422aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li } 423aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li return null; 424aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li } 425aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li } 426a6b966047b6215b02c502a3f143106070abf6009Angus Kong 427a6b966047b6215b02c502a3f143106070abf6009Angus Kong // Call this after setContentView. 428a6b966047b6215b02c502a3f143106070abf6009Angus Kong protected void createCameraScreenNail(boolean getPictures) { 429a6b966047b6215b02c502a3f143106070abf6009Angus Kong mCameraAppView = findViewById(R.id.camera_app_root); 430a6b966047b6215b02c502a3f143106070abf6009Angus Kong Bundle data = new Bundle(); 431a6b966047b6215b02c502a3f143106070abf6009Angus Kong String path = "/local/all/"; 432a6b966047b6215b02c502a3f143106070abf6009Angus Kong // Intent mode does not show camera roll. Use 0 as a work around for 433a6b966047b6215b02c502a3f143106070abf6009Angus Kong // invalid bucket id. 434a6b966047b6215b02c502a3f143106070abf6009Angus Kong // TODO: add support of empty media set in gallery. 435a6b966047b6215b02c502a3f143106070abf6009Angus Kong path += (getPictures ? MediaSetUtils.CAMERA_BUCKET_ID : "0"); 436a6b966047b6215b02c502a3f143106070abf6009Angus Kong data.putString(PhotoPage.KEY_MEDIA_SET_PATH, path); 437a6b966047b6215b02c502a3f143106070abf6009Angus Kong data.putString(PhotoPage.KEY_MEDIA_ITEM_PATH, path); 438a6b966047b6215b02c502a3f143106070abf6009Angus Kong 43978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang // Send an AppBridge to gallery to enable the camera preview. 44078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang mAppBridge = new MyAppBridge(); 44178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang data.putParcelable(PhotoPage.KEY_APP_BRIDGE, mAppBridge); 442a6b966047b6215b02c502a3f143106070abf6009Angus Kong getStateManager().startState(PhotoPage.class, data); 44378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang mCameraScreenNail = mAppBridge.getCameraScreenNail(); 444a6b966047b6215b02c502a3f143106070abf6009Angus Kong } 445a6b966047b6215b02c502a3f143106070abf6009Angus Kong 44647a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang private class HideCameraAppView implements Animation.AnimationListener { 4471cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li @Override 44847a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang public void onAnimationEnd(Animation animation) { 449f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang // We cannot set this as GONE because we want to receive the 450f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang // onLayoutChange() callback even when we are invisible. 451f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang mCameraAppView.setVisibility(View.INVISIBLE); 4521cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li } 45347a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang 45447a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang @Override 45547a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang public void onAnimationRepeat(Animation animation) { 45647a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang } 45747a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang 45847a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang @Override 45947a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang public void onAnimationStart(Animation animation) { 46047a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang } 4611cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li } 46278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 463c94cd4a5206b05541de0dc8a4821c64d0edba352Angus Kong protected void updateCameraAppView() { 46447a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang // Initialize the animation. 46547a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang if (mCameraAppViewFadeIn == null) { 46647a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang mCameraAppViewFadeIn = new AlphaAnimation(0f, 1f); 46747a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang mCameraAppViewFadeIn.setDuration(CAMERA_APP_VIEW_TOGGLE_TIME); 46847a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang mCameraAppViewFadeIn.setInterpolator(new DecelerateInterpolator()); 46947a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang 47047a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang mCameraAppViewFadeOut = new AlphaAnimation(1f, 0f); 47147a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang mCameraAppViewFadeOut.setDuration(CAMERA_APP_VIEW_TOGGLE_TIME); 47247a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang mCameraAppViewFadeOut.setInterpolator(new DecelerateInterpolator()); 47347a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang mCameraAppViewFadeOut.setAnimationListener(new HideCameraAppView()); 47447a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang } 47547a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang 47678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang if (mShowCameraAppView) { 47778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang mCameraAppView.setVisibility(View.VISIBLE); 478d20805f3162b8004cc840230bc8d9c864b114401Wu-cheng Li // The "transparent region" is not recomputed when a sibling of 479d20805f3162b8004cc840230bc8d9c864b114401Wu-cheng Li // SurfaceView changes visibility (unless it involves GONE). It's 480d20805f3162b8004cc840230bc8d9c864b114401Wu-cheng Li // been broken since 1.0. Call requestLayout to work around it. 481d20805f3162b8004cc840230bc8d9c864b114401Wu-cheng Li mCameraAppView.requestLayout(); 48247a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang mCameraAppView.startAnimation(mCameraAppViewFadeIn); 48378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } else { 48447a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang mCameraAppView.startAnimation(mCameraAppViewFadeOut); 485a6b966047b6215b02c502a3f143106070abf6009Angus Kong } 486a6b966047b6215b02c502a3f143106070abf6009Angus Kong } 487a6b966047b6215b02c502a3f143106070abf6009Angus Kong 4888e3ccacccd2b128734322877561b8b78a70e103bWu-cheng Li protected void onFullScreenChanged(boolean full) { 48978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang if (mShowCameraAppView == full) return; 49078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang mShowCameraAppView = full; 49178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang if (mPaused || isFinishing()) return; 49278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang updateCameraAppView(); 493b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang 494b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang // If we received DELETE_PICTURE broadcasts while the Camera UI is 495b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang // hidden, we update the thumbnail now. 496b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang if (full && mUpdateThumbnailDelayed) { 497b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang getLastThumbnailUncached(); 498b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang mUpdateThumbnailDelayed = false; 499b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang } 500a6b966047b6215b02c502a3f143106070abf6009Angus Kong } 501a6b966047b6215b02c502a3f143106070abf6009Angus Kong 502a6b966047b6215b02c502a3f143106070abf6009Angus Kong @Override 503a6b966047b6215b02c502a3f143106070abf6009Angus Kong public GalleryActionBar getGalleryActionBar() { 504a6b966047b6215b02c502a3f143106070abf6009Angus Kong return mActionBar; 505a6b966047b6215b02c502a3f143106070abf6009Angus Kong } 5068a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li 50778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang // Preview frame layout has changed. 5088a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li @Override 509525667ff4b93a577298085fe45660a2d15b0bd06Angus Kong public void onLayoutChange(View v, int left, int top, int right, int bottom) { 51078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang if (mAppBridge == null) return; 51178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 51240d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li int width = right - left; 51340d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li int height = bottom - top; 51440d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li if (Util.getDisplayRotation(this) % 180 == 0) { 51540d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li mCameraScreenNail.setPreviewFrameLayoutSize(width, height); 51640d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li } else { 51740d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li // Swap the width and height. Camera screen nail draw() is based on 51840d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li // natural orientation, not the view system orientation. 51940d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li mCameraScreenNail.setPreviewFrameLayoutSize(height, width); 52040d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li } 52176507a9fd2581694942a662a57fbdd46d7a20036Wu-cheng Li 52278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang // Find out the coordinates of the preview frame relative to GL 5238a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li // root view. 5248a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li View root = (View) getGLRoot(); 5258a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li int[] rootLocation = new int[2]; 5268a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li int[] viewLocation = new int[2]; 5278a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li root.getLocationInWindow(rootLocation); 5288a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li v.getLocationInWindow(viewLocation); 52978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 53078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang int l = viewLocation[0] - rootLocation[0]; 53178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang int t = viewLocation[1] - rootLocation[1]; 53240d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li int r = l + width; 53340d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li int b = t + height; 534f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang Rect frame = new Rect(l, t, r, b); 535f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang Log.d(TAG, "set CameraRelativeFrame as " + frame); 536f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang mAppBridge.setCameraRelativeFrame(frame); 5378a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li } 538bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li 539bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li protected void setSingleTapUpListener(View singleTapArea) { 540bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li mSingleTapArea = singleTapArea; 541bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li } 542bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li 54378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang private boolean onSingleTapUp(int x, int y) { 54417de506c16816a9874a5417be402345b9882e0a4Wu-cheng Li // Ignore if listener is null or the camera control is invisible. 54517de506c16816a9874a5417be402345b9882e0a4Wu-cheng Li if (mSingleTapArea == null || !mShowCameraAppView) return false; 546bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li 547bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li int[] relativeLocation = Util.getRelativeLocation((View) getGLRoot(), 548bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li mSingleTapArea); 549bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li x -= relativeLocation[0]; 550bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li y -= relativeLocation[1]; 551bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li if (x >= 0 && x < mSingleTapArea.getWidth() && y >= 0 552bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li && y < mSingleTapArea.getHeight()) { 553bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li onSingleTapUp(mSingleTapArea, x, y); 554bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li return true; 555bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li } 556bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li return false; 557bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li } 558bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li 559bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li protected void onSingleTapUp(View view, int x, int y) { 560bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li } 56178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 562d03d34ac9f50857f38034749607ce07c161d5120Chih-Chung Chang protected void setSwipingEnabled(boolean enabled) { 563d03d34ac9f50857f38034749607ce07c161d5120Chih-Chung Chang mAppBridge.setSwipingEnabled(enabled); 56478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 56578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 566a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang protected void notifyScreenNailChanged() { 567a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang mAppBridge.notifyScreenNailChanged(); 568a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang } 569a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang 570a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li protected void onPreviewTextureCopied() { 571a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li } 57278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 57378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang ////////////////////////////////////////////////////////////////////////// 57478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang // The is the communication interface between the Camera Application and 57578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang // the Gallery PhotoPage. 57678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang ////////////////////////////////////////////////////////////////////////// 57778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 578a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li class MyAppBridge extends AppBridge implements CameraScreenNail.Listener { 579dac1bb32531f7f4d49622bd38c82dde9333c38acAhbong Chang @SuppressWarnings("hiding") 58078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang private CameraScreenNail mCameraScreenNail; 58178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang private Server mServer; 58278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 58378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang @Override 58478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang public ScreenNail attachScreenNail() { 585a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang if (mCameraScreenNail == null) { 586a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang mCameraScreenNail = new CameraScreenNail(this); 587a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang } 58878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang return mCameraScreenNail; 58978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 59078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 59178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang @Override 59278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang public void detachScreenNail() { 59378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang mCameraScreenNail = null; 59478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 59578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 59678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang public CameraScreenNail getCameraScreenNail() { 59778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang return mCameraScreenNail; 59878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 59978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 60078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang // Return true if the tap is consumed. 60178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang @Override 60278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang public boolean onSingleTapUp(int x, int y) { 60378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang return ActivityBase.this.onSingleTapUp(x, y); 60478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 60578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 60678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang // This is used to notify that the screen nail will be drawn in full screen 60778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang // or not in next draw() call. 60878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang @Override 60978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang public void onFullScreenChanged(boolean full) { 61078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang ActivityBase.this.onFullScreenChanged(full); 61178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 61278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 61378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang @Override 61478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang public void requestRender() { 61578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang getGLRoot().requestRender(); 61678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 61778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 61878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang @Override 619a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li public void onPreviewTextureCopied() { 620a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li ActivityBase.this.onPreviewTextureCopied(); 621a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li } 622a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li 623a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li @Override 62478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang public void setServer(Server s) { 62578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang mServer = s; 62678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 62778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 62805e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong @Override 62905e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong public boolean isPanorama() { 63005e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong return ActivityBase.this.isPanoramaActivity(); 63105e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong } 63205e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong 633f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang private void setCameraRelativeFrame(Rect frame) { 634f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang if (mServer != null) mServer.setCameraRelativeFrame(frame); 63578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 63678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 63778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang private void switchWithCaptureAnimation(int offset) { 63878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang if (mServer != null) mServer.switchWithCaptureAnimation(offset); 63978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 640d03d34ac9f50857f38034749607ce07c161d5120Chih-Chung Chang 641d03d34ac9f50857f38034749607ce07c161d5120Chih-Chung Chang private void setSwipingEnabled(boolean enabled) { 642d03d34ac9f50857f38034749607ce07c161d5120Chih-Chung Chang if (mServer != null) mServer.setSwipingEnabled(enabled); 643d03d34ac9f50857f38034749607ce07c161d5120Chih-Chung Chang } 644a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang 645a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang private void notifyScreenNailChanged() { 646a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang if (mServer != null) mServer.notifyScreenNailChanged(); 647a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang } 64878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 6494d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang} 650