ActivityBase.java revision 525667ff4b93a577298085fe45660a2d15b0bd06
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; 28b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Changimport android.support.v4.content.LocalBroadcastManager; 297d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Millerimport android.util.Log; 304c7b291018e08dbb4bc1712d95117a294fa1416cWu-cheng Liimport android.view.KeyEvent; 3124e4e6cc25b7628ef15eff703f70b2872575a4ccWu-cheng Liimport android.view.Menu; 32c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Liimport android.view.View; 33a6b966047b6215b02c502a3f143106070abf6009Angus Kongimport android.view.Window; 34892781804513066b68b4a2fa6f846e862dac252aOwen Linimport android.view.WindowManager; 35525667ff4b93a577298085fe45660a2d15b0bd06Angus Kongimport android.view.animation.AlphaAnimation; 36525667ff4b93a577298085fe45660a2d15b0bd06Angus Kongimport android.view.animation.Animation; 37a029bd9976ebb618f321e8740c86b0f5d681d241Owen Linimport android.view.animation.DecelerateInterpolator; 38892781804513066b68b4a2fa6f846e862dac252aOwen Lin 39d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Liimport com.android.camera.ui.CameraPicker; 40525667ff4b93a577298085fe45660a2d15b0bd06Angus Kongimport com.android.camera.ui.LayoutChangeNotifier; 41892781804513066b68b4a2fa6f846e862dac252aOwen Linimport com.android.camera.ui.PopupManager; 42892781804513066b68b4a2fa6f846e862dac252aOwen Linimport com.android.camera.ui.RotateImageView; 43a6b966047b6215b02c502a3f143106070abf6009Angus Kongimport com.android.gallery3d.app.AbstractGalleryActivity; 4478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Changimport com.android.gallery3d.app.AppBridge; 45a6b966047b6215b02c502a3f143106070abf6009Angus Kongimport com.android.gallery3d.app.GalleryActionBar; 46a029bd9976ebb618f321e8740c86b0f5d681d241Owen Linimport com.android.gallery3d.app.PhotoPage; 4778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Changimport com.android.gallery3d.ui.ScreenNail; 48a6b966047b6215b02c502a3f143106070abf6009Angus Kongimport com.android.gallery3d.util.MediaSetUtils; 494d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang 50aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Liimport java.io.File; 51aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li 5277c1cdc8f2cda250b1db842204efb49f87e094aeChih-Chung Chang/** 537673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li * Superclass of Camera and VideoCamera activities. 5477c1cdc8f2cda250b1db842204efb49f87e094aeChih-Chung Chang */ 55525667ff4b93a577298085fe45660a2d15b0bd06Angus Kongpublic abstract class ActivityBase extends AbstractGalleryActivity 56525667ff4b93a577298085fe45660a2d15b0bd06Angus Kong implements LayoutChangeNotifier.Listener { 57a6b966047b6215b02c502a3f143106070abf6009Angus Kong 587d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller private static final String TAG = "ActivityBase"; 5976507a9fd2581694942a662a57fbdd46d7a20036Wu-cheng Li private static final boolean LOGV = false; 60c38faeb66a3f2cc96e4c5e951228d9b01e12edb3Chih-Chung Chang private static final int CAMERA_APP_VIEW_TOGGLE_TIME = 100; // milliseconds 61b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang private static final String ACTION_DELETE_PICTURE = 62b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang "com.android.gallery3d.action.DELETE_PICTURE"; 6347a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang 645df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li private int mResultCodeForTesting; 655df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li private Intent mResultDataForTesting; 664edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong private OnScreenHint mStorageHint; 67bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li private View mSingleTapArea; 68a6b966047b6215b02c502a3f143106070abf6009Angus Kong 69c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // The bitmap of the last captured picture thumbnail and the URI of the 70c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // original picture. 71c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li protected Thumbnail mThumbnail; 728a674bebfba0c4dd4b01018276d20f198f65f19eWu-cheng Li protected int mThumbnailViewWidth; // layout width of the thumbnail 73c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li protected AsyncTask<Void, Void, Thumbnail> mLoadThumbnailTask; 74d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li // An imageview showing the last captured picture thumbnail. 75d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li protected RotateImageView mThumbnailView; 76d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li protected CameraPicker mCameraPicker; 77d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li 78475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting protected boolean mOpenCameraFail; 79475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting protected boolean mCameraDisabled; 80475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting protected CameraManager.CameraProxy mCameraDevice; 81296d27772b9543d55820e1d24d900fea959f1b7aPin Ting protected Parameters mParameters; 825c17d7a077acd1f84bdcb7579f7d02a1094602bcWu-cheng Li // The activity is paused. The classes that extend this class should set 835c17d7a077acd1f84bdcb7579f7d02a1094602bcWu-cheng Li // mPaused the first thing in onResume/onPause. 845c17d7a077acd1f84bdcb7579f7d02a1094602bcWu-cheng Li protected boolean mPaused; 85a6b966047b6215b02c502a3f143106070abf6009Angus Kong protected GalleryActionBar mActionBar; 86475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting 87475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting // multiple cameras support 88475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting protected int mNumberOfCameras; 89475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting protected int mCameraId; 90d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li // The activity is going to switch to the specified camera id. This is 91d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li // needed because texture copy is done in GL thread. -1 means camera is not 92d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li // switching. 93d97ddcbe7e765b45e68e157af7ac0c873a165aa9Wu-cheng Li protected int mPendingSwitchCameraId = -1; 94475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting 9578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang protected MyAppBridge mAppBridge; 96a6b966047b6215b02c502a3f143106070abf6009Angus Kong protected CameraScreenNail mCameraScreenNail; // This shows camera preview. 97a6b966047b6215b02c502a3f143106070abf6009Angus Kong // The view containing only camera related widgets like control panel, 98a6b966047b6215b02c502a3f143106070abf6009Angus Kong // indicator bar, focus indicator and etc. 99a6b966047b6215b02c502a3f143106070abf6009Angus Kong protected View mCameraAppView; 1001cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li protected boolean mShowCameraAppView = true; 10147a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang private Animation mCameraAppViewFadeIn; 10247a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang private Animation mCameraAppViewFadeOut; 10347a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang 104b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang private boolean mUpdateThumbnailDelayed; 105b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang private IntentFilter mDeletePictureFilter = 106b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang new IntentFilter(ACTION_DELETE_PICTURE); 107b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang private BroadcastReceiver mDeletePictureReceiver = 108b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang new BroadcastReceiver() { 109b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang @Override 110b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang public void onReceive(Context context, Intent intent) { 111b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang if (mShowCameraAppView) { 112b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang getLastThumbnailUncached(); 113b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang } else { 114b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang mUpdateThumbnailDelayed = true; 115b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang } 116b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang } 117b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang }; 118a6b966047b6215b02c502a3f143106070abf6009Angus Kong 119475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting protected class CameraOpenThread extends Thread { 120475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting @Override 121475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting public void run() { 122475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting try { 123475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting mCameraDevice = Util.openCamera(ActivityBase.this, mCameraId); 124296d27772b9543d55820e1d24d900fea959f1b7aPin Ting mParameters = mCameraDevice.getParameters(); 125475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting } catch (CameraHardwareException e) { 126475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting mOpenCameraFail = true; 127475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting } catch (CameraDisabledException e) { 128475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting mCameraDisabled = true; 129475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting } 130475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting } 131475b4c6eca6f7e7ca0e4b3ee0ee234c6fe079687Pin Ting } 1325df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li 1334d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang @Override 1348608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Chang public void onCreate(Bundle icicle) { 135e5b6a36e64ef2c2cb1435c138a5fc179e9a6bc9aWu-cheng Li getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE); 1366a4a72b643929701c5d7c8b68b91d762c7277c20Wu-cheng Li super.disableToggleStatusBar(); 137a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin // Set a theme with action bar. It is not specified in manifest because 138a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin // we want to hide it by default. setTheme must happen before 139a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin // setContentView. 140a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin // 141a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin // This must be set before we call super.onCreate(), where the window's 142a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin // background is removed. 143a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin setTheme(R.style.Theme_Gallery); 144a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); 145a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY); 146a029bd9976ebb618f321e8740c86b0f5d681d241Owen Lin 1478608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Chang super.onCreate(icicle); 1488608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Chang } 1498608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Chang 15005e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong public boolean isPanoramaActivity() { 15105e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong return false; 15205e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong } 15305e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong 1548608b577921acf67a5a7b7968cb3633b8f94714dChih-Chung Chang @Override 155b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang protected void onResume() { 156b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang super.onResume(); 157b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang LocalBroadcastManager manager = LocalBroadcastManager.getInstance(this); 158b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang manager.registerReceiver(mDeletePictureReceiver, mDeletePictureFilter); 159b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang } 160b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang 161b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang @Override 1627d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller protected void onPause() { 1635c17d7a077acd1f84bdcb7579f7d02a1094602bcWu-cheng Li super.onPause(); 164b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang LocalBroadcastManager manager = LocalBroadcastManager.getInstance(this); 165b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang manager.unregisterReceiver(mDeletePictureReceiver); 166b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang 1677d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller if (LOGV) Log.v(TAG, "onPause"); 168aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li saveThumbnailToFile(); 1694edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong 170c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li if (mLoadThumbnailTask != null) { 171c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mLoadThumbnailTask.cancel(true); 172c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mLoadThumbnailTask = null; 173c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 174c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li 1754edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong if (mStorageHint != null) { 1764edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong mStorageHint.cancel(); 1774edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong mStorageHint = null; 1784edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } 1797d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller } 1807d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller 1817d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller @Override 18272fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li public void setContentView(int layoutResID) { 18372fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li super.setContentView(layoutResID); 18472fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li // getActionBar() should be after setContentView 18572fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li mActionBar = new GalleryActionBar(this); 18672fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li mActionBar.hide(); 18772fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li } 18872fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li 18972fe79a040df8f01b03a39bec2473f7b0de8228dWu-cheng Li @Override 1904d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang public boolean onSearchRequested() { 1914d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang return false; 1924d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang } 1937673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li 1947673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li @Override 1957673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li public boolean onKeyDown(int keyCode, KeyEvent event) { 1967673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li // Prevent software keyboard or voice search from showing up. 1977673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li if (keyCode == KeyEvent.KEYCODE_SEARCH 1987673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li || keyCode == KeyEvent.KEYCODE_MENU) { 1997673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li if (event.isLongPress()) return true; 2007673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li } 2017673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li 2027673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li return super.onKeyDown(keyCode, event); 2037673ada94b5e2263e7190ca246694cdee31ed03eWu-cheng Li } 2045df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li 2055df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li protected void setResultEx(int resultCode) { 2065df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li mResultCodeForTesting = resultCode; 2075df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li setResult(resultCode); 2085df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li } 2095df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li 2105df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li protected void setResultEx(int resultCode, Intent data) { 2115df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li mResultCodeForTesting = resultCode; 2125df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li mResultDataForTesting = data; 2135df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li setResult(resultCode, data); 2145df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li } 2155df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li 2165df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li public int getResultCode() { 2175df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li return mResultCodeForTesting; 2185df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li } 2195df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li 2205df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li public Intent getResultData() { 2215df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li return mResultDataForTesting; 2225df067af93e6b386167f11cdf12701b7905ee444Wu-cheng Li } 2235f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang 2245f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang @Override 2255f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang protected void onDestroy() { 2265f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang PopupManager.removeInstance(this); 2275f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang super.onDestroy(); 2285f6e354a6e2a77aa935fcefeb33a9baa67d48aafChung-yih Wang } 2297d9eadd0c6c38b3761b7e8d3fa3658d194810d60Jim Miller 23024e4e6cc25b7628ef15eff703f70b2872575a4ccWu-cheng Li @Override 23124e4e6cc25b7628ef15eff703f70b2872575a4ccWu-cheng Li public boolean onCreateOptionsMenu(Menu menu) { 23224e4e6cc25b7628ef15eff703f70b2872575a4ccWu-cheng Li super.onCreateOptionsMenu(menu); 23324e4e6cc25b7628ef15eff703f70b2872575a4ccWu-cheng Li return getStateManager().createOptionsMenu(menu); 23424e4e6cc25b7628ef15eff703f70b2872575a4ccWu-cheng Li } 23524e4e6cc25b7628ef15eff703f70b2872575a4ccWu-cheng Li 2364edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong protected void updateStorageHint(long storageSpace) { 2374edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong String message = null; 2384edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong if (storageSpace == Storage.UNAVAILABLE) { 2394edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong message = getString(R.string.no_storage); 2404edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } else if (storageSpace == Storage.PREPARING) { 2414edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong message = getString(R.string.preparing_sd); 2424edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } else if (storageSpace == Storage.UNKNOWN_SIZE) { 2434edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong message = getString(R.string.access_sd_fail); 2444edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } else if (storageSpace < Storage.LOW_STORAGE_THRESHOLD) { 2454edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong message = getString(R.string.spaceIsLow_content); 2464edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } 2474edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong 2484edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong if (message != null) { 2494edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong if (mStorageHint == null) { 2504edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong mStorageHint = OnScreenHint.makeText(this, message); 2514edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } else { 2524edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong mStorageHint.setText(message); 2534edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } 2544edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong mStorageHint.show(); 2554edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } else if (mStorageHint != null) { 2564edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong mStorageHint.cancel(); 2574edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong mStorageHint = null; 2584edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } 2594edaf0cbbb5d9cfeae786b6fd0560240947f6585Angus Kong } 260c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li 261a0b7c6b3c61b68db7f4eb33d81c886fb4e095f2cPin Ting protected void updateThumbnailView() { 262c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li if (mThumbnail != null) { 263c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mThumbnailView.setBitmap(mThumbnail.getBitmap()); 264c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mThumbnailView.setVisibility(View.VISIBLE); 265c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } else { 266c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mThumbnailView.setBitmap(null); 267c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mThumbnailView.setVisibility(View.GONE); 268c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 269c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 270c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li 271c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li protected void getLastThumbnail() { 272c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mThumbnail = ThumbnailHolder.getLastThumbnail(getContentResolver()); 273c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // Suppose users tap the thumbnail view, go to the gallery, delete the 274c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // image, and coming back to the camera. Thumbnail file will be invalid. 275c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // Since the new thumbnail will be loaded in another thread later, the 276c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // view should be set to gone to prevent from opening the invalid image. 277c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li updateThumbnailView(); 278c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li if (mThumbnail == null) { 279b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang mLoadThumbnailTask = new LoadThumbnailTask(true).execute(); 280c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 281c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 282c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li 283b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang protected void getLastThumbnailUncached() { 284b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang if (mLoadThumbnailTask != null) mLoadThumbnailTask.cancel(true); 285b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang mLoadThumbnailTask = new LoadThumbnailTask(false).execute(); 286b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang } 287b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang 288aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li private class LoadThumbnailTask extends AsyncTask<Void, Void, Thumbnail> { 289b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang private boolean mLookAtCache; 290b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang 291b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang public LoadThumbnailTask(boolean lookAtCache) { 292b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang mLookAtCache = lookAtCache; 293b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang } 294b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang 295c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li @Override 296c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li protected Thumbnail doInBackground(Void... params) { 297c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // Load the thumbnail from the file. 298c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li ContentResolver resolver = getContentResolver(); 299b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang Thumbnail t = null; 300b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang if (mLookAtCache) { 301b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang t = Thumbnail.getLastThumbnailFromFile(getFilesDir(), resolver); 302b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang } 303c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li 304c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li if (isCancelled()) return null; 305c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li 306c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li if (t == null) { 307b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang Thumbnail result[] = new Thumbnail[1]; 308c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li // Load the thumbnail from the media provider. 309b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang int code = Thumbnail.getLastThumbnailFromContentResolver( 310b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang resolver, result); 311b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang switch (code) { 312b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang case Thumbnail.THUMBNAIL_FOUND: 313b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang return result[0]; 314b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang case Thumbnail.THUMBNAIL_NOT_FOUND: 315b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang return null; 316b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang case Thumbnail.THUMBNAIL_DELETED: 317b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang cancel(true); 318b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang return null; 319b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang } 320c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 321c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li return t; 322c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 323c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li 324c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li @Override 325c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li protected void onPostExecute(Thumbnail thumbnail) { 326b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang if (isCancelled()) return; 327c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li mThumbnail = thumbnail; 328c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li updateThumbnailView(); 329c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 330c24a2a83df9b54297995c5270d015bb7fdd85fabWu-cheng Li } 331aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li 3326899a30e3a89ad4b455978140682d5ba871c1b33Pin Ting protected void gotoGallery() { 333252da3c55a35c77fa4be4d51f79dac4aaf7cdb77Pin Ting // Move the next picture with capture animation. "1" means next. 334252da3c55a35c77fa4be4d51f79dac4aaf7cdb77Pin Ting mAppBridge.switchWithCaptureAnimation(1); 3356899a30e3a89ad4b455978140682d5ba871c1b33Pin Ting } 3366899a30e3a89ad4b455978140682d5ba871c1b33Pin Ting 337aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li protected void saveThumbnailToFile() { 338aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li if (mThumbnail != null && !mThumbnail.fromFile()) { 339aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li new SaveThumbnailTask().execute(mThumbnail); 340aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li } 341aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li } 342aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li 343aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li private class SaveThumbnailTask extends AsyncTask<Thumbnail, Void, Void> { 344aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li @Override 345aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li protected Void doInBackground(Thumbnail... params) { 346aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li final int n = params.length; 347aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li final File filesDir = getFilesDir(); 348aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li for (int i = 0; i < n; i++) { 349aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li params[i].saveLastThumbnailToFile(filesDir); 350aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li } 351aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li return null; 352aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li } 353aef5310d25537494679f9ec6b9d7a1a9cb60887dWu-cheng Li } 354a6b966047b6215b02c502a3f143106070abf6009Angus Kong 355a6b966047b6215b02c502a3f143106070abf6009Angus Kong // Call this after setContentView. 356a6b966047b6215b02c502a3f143106070abf6009Angus Kong protected void createCameraScreenNail(boolean getPictures) { 357a6b966047b6215b02c502a3f143106070abf6009Angus Kong mCameraAppView = findViewById(R.id.camera_app_root); 358a6b966047b6215b02c502a3f143106070abf6009Angus Kong Bundle data = new Bundle(); 359a6b966047b6215b02c502a3f143106070abf6009Angus Kong String path = "/local/all/"; 360a6b966047b6215b02c502a3f143106070abf6009Angus Kong // Intent mode does not show camera roll. Use 0 as a work around for 361a6b966047b6215b02c502a3f143106070abf6009Angus Kong // invalid bucket id. 362a6b966047b6215b02c502a3f143106070abf6009Angus Kong // TODO: add support of empty media set in gallery. 363a6b966047b6215b02c502a3f143106070abf6009Angus Kong path += (getPictures ? MediaSetUtils.CAMERA_BUCKET_ID : "0"); 364a6b966047b6215b02c502a3f143106070abf6009Angus Kong data.putString(PhotoPage.KEY_MEDIA_SET_PATH, path); 365a6b966047b6215b02c502a3f143106070abf6009Angus Kong data.putString(PhotoPage.KEY_MEDIA_ITEM_PATH, path); 366a6b966047b6215b02c502a3f143106070abf6009Angus Kong 36778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang // Send an AppBridge to gallery to enable the camera preview. 36878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang mAppBridge = new MyAppBridge(); 36978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang data.putParcelable(PhotoPage.KEY_APP_BRIDGE, mAppBridge); 370a6b966047b6215b02c502a3f143106070abf6009Angus Kong getStateManager().startState(PhotoPage.class, data); 37178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang mCameraScreenNail = mAppBridge.getCameraScreenNail(); 372a6b966047b6215b02c502a3f143106070abf6009Angus Kong } 373a6b966047b6215b02c502a3f143106070abf6009Angus Kong 37447a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang private class HideCameraAppView implements Animation.AnimationListener { 3751cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li @Override 37647a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang public void onAnimationEnd(Animation animation) { 377f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang // We cannot set this as GONE because we want to receive the 378f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang // onLayoutChange() callback even when we are invisible. 379f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang mCameraAppView.setVisibility(View.INVISIBLE); 3801cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li } 38147a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang 38247a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang @Override 38347a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang public void onAnimationRepeat(Animation animation) { 38447a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang } 38547a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang 38647a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang @Override 38747a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang public void onAnimationStart(Animation animation) { 38847a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang } 3891cc3a3466c8e9f30f13b81a88d8b2f31050c599cWu-cheng Li } 39078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 391c94cd4a5206b05541de0dc8a4821c64d0edba352Angus Kong protected void updateCameraAppView() { 39247a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang // Initialize the animation. 39347a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang if (mCameraAppViewFadeIn == null) { 39447a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang mCameraAppViewFadeIn = new AlphaAnimation(0f, 1f); 39547a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang mCameraAppViewFadeIn.setDuration(CAMERA_APP_VIEW_TOGGLE_TIME); 39647a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang mCameraAppViewFadeIn.setInterpolator(new DecelerateInterpolator()); 39747a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang 39847a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang mCameraAppViewFadeOut = new AlphaAnimation(1f, 0f); 39947a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang mCameraAppViewFadeOut.setDuration(CAMERA_APP_VIEW_TOGGLE_TIME); 40047a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang mCameraAppViewFadeOut.setInterpolator(new DecelerateInterpolator()); 40147a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang mCameraAppViewFadeOut.setAnimationListener(new HideCameraAppView()); 40247a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang } 40347a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang 40478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang if (mShowCameraAppView) { 40578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang mCameraAppView.setVisibility(View.VISIBLE); 406d20805f3162b8004cc840230bc8d9c864b114401Wu-cheng Li // The "transparent region" is not recomputed when a sibling of 407d20805f3162b8004cc840230bc8d9c864b114401Wu-cheng Li // SurfaceView changes visibility (unless it involves GONE). It's 408d20805f3162b8004cc840230bc8d9c864b114401Wu-cheng Li // been broken since 1.0. Call requestLayout to work around it. 409d20805f3162b8004cc840230bc8d9c864b114401Wu-cheng Li mCameraAppView.requestLayout(); 41047a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang mCameraAppView.startAnimation(mCameraAppViewFadeIn); 41178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } else { 41247a563b623a468f736779da7e21ef69665fc5b80Chih-Yu Huang mCameraAppView.startAnimation(mCameraAppViewFadeOut); 413a6b966047b6215b02c502a3f143106070abf6009Angus Kong } 414a6b966047b6215b02c502a3f143106070abf6009Angus Kong } 415a6b966047b6215b02c502a3f143106070abf6009Angus Kong 41678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang private void onFullScreenChanged(boolean full) { 41778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang if (mShowCameraAppView == full) return; 41878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang mShowCameraAppView = full; 41978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang if (mPaused || isFinishing()) return; 42078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang updateCameraAppView(); 421b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang 422b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang // If we received DELETE_PICTURE broadcasts while the Camera UI is 423b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang // hidden, we update the thumbnail now. 424b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang if (full && mUpdateThumbnailDelayed) { 425b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang getLastThumbnailUncached(); 426b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang mUpdateThumbnailDelayed = false; 427b2838c064ed33d8abd2e6dc7ea38659a3bb686f9Chih-Chung Chang } 428a6b966047b6215b02c502a3f143106070abf6009Angus Kong } 429a6b966047b6215b02c502a3f143106070abf6009Angus Kong 430a6b966047b6215b02c502a3f143106070abf6009Angus Kong @Override 431a6b966047b6215b02c502a3f143106070abf6009Angus Kong public GalleryActionBar getGalleryActionBar() { 432a6b966047b6215b02c502a3f143106070abf6009Angus Kong return mActionBar; 433a6b966047b6215b02c502a3f143106070abf6009Angus Kong } 4348a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li 43578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang // Preview frame layout has changed. 4368a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li @Override 437525667ff4b93a577298085fe45660a2d15b0bd06Angus Kong public void onLayoutChange(View v, int left, int top, int right, int bottom) { 43878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang if (mAppBridge == null) return; 43978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 44040d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li int width = right - left; 44140d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li int height = bottom - top; 44240d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li if (Util.getDisplayRotation(this) % 180 == 0) { 44340d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li mCameraScreenNail.setPreviewFrameLayoutSize(width, height); 44440d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li } else { 44540d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li // Swap the width and height. Camera screen nail draw() is based on 44640d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li // natural orientation, not the view system orientation. 44740d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li mCameraScreenNail.setPreviewFrameLayoutSize(height, width); 44840d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li } 44976507a9fd2581694942a662a57fbdd46d7a20036Wu-cheng Li 45078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang // Find out the coordinates of the preview frame relative to GL 4518a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li // root view. 4528a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li View root = (View) getGLRoot(); 4538a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li int[] rootLocation = new int[2]; 4548a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li int[] viewLocation = new int[2]; 4558a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li root.getLocationInWindow(rootLocation); 4568a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li v.getLocationInWindow(viewLocation); 45778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 45878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang int l = viewLocation[0] - rootLocation[0]; 45978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang int t = viewLocation[1] - rootLocation[1]; 46040d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li int r = l + width; 46140d99c1258ef297c18bf0857860b326d517bf4aaWu-cheng Li int b = t + height; 462f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang Rect frame = new Rect(l, t, r, b); 463f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang Log.d(TAG, "set CameraRelativeFrame as " + frame); 464f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang mAppBridge.setCameraRelativeFrame(frame); 4658a79ddc5827de54a33d8fbef0e467da2266342cbWu-cheng Li } 466bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li 467bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li protected void setSingleTapUpListener(View singleTapArea) { 468bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li mSingleTapArea = singleTapArea; 469bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li } 470bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li 47178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang private boolean onSingleTapUp(int x, int y) { 47217de506c16816a9874a5417be402345b9882e0a4Wu-cheng Li // Ignore if listener is null or the camera control is invisible. 47317de506c16816a9874a5417be402345b9882e0a4Wu-cheng Li if (mSingleTapArea == null || !mShowCameraAppView) return false; 474bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li 475bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li int[] relativeLocation = Util.getRelativeLocation((View) getGLRoot(), 476bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li mSingleTapArea); 477bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li x -= relativeLocation[0]; 478bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li y -= relativeLocation[1]; 479bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li if (x >= 0 && x < mSingleTapArea.getWidth() && y >= 0 480bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li && y < mSingleTapArea.getHeight()) { 481bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li onSingleTapUp(mSingleTapArea, x, y); 482bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li return true; 483bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li } 484bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li return false; 485bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li } 486bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li 487bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li protected void onSingleTapUp(View view, int x, int y) { 488bfaab736a344641a63170ebdcd9d5377779d3a15Wu-cheng Li } 48978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 490d03d34ac9f50857f38034749607ce07c161d5120Chih-Chung Chang protected void setSwipingEnabled(boolean enabled) { 491d03d34ac9f50857f38034749607ce07c161d5120Chih-Chung Chang mAppBridge.setSwipingEnabled(enabled); 49278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 49378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 494a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang protected void notifyScreenNailChanged() { 495a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang mAppBridge.notifyScreenNailChanged(); 496a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang } 497a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang 498a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li protected void onPreviewTextureCopied() { 499a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li } 50078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 50178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang ////////////////////////////////////////////////////////////////////////// 50278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang // The is the communication interface between the Camera Application and 50378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang // the Gallery PhotoPage. 50478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang ////////////////////////////////////////////////////////////////////////// 50578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 506a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li class MyAppBridge extends AppBridge implements CameraScreenNail.Listener { 50778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang private CameraScreenNail mCameraScreenNail; 50878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang private Server mServer; 50978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 51078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang @Override 51178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang public ScreenNail attachScreenNail() { 512a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang if (mCameraScreenNail == null) { 513a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang mCameraScreenNail = new CameraScreenNail(this); 514a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang } 51578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang return mCameraScreenNail; 51678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 51778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 51878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang @Override 51978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang public void detachScreenNail() { 52078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang mCameraScreenNail = null; 52178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 52278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 52378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang public CameraScreenNail getCameraScreenNail() { 52478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang return mCameraScreenNail; 52578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 52678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 52778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang // Return true if the tap is consumed. 52878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang @Override 52978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang public boolean onSingleTapUp(int x, int y) { 53078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang return ActivityBase.this.onSingleTapUp(x, y); 53178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 53278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 53378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang // This is used to notify that the screen nail will be drawn in full screen 53478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang // or not in next draw() call. 53578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang @Override 53678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang public void onFullScreenChanged(boolean full) { 53778b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang ActivityBase.this.onFullScreenChanged(full); 53878b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 53978b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 54078b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang @Override 54178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang public void requestRender() { 54278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang getGLRoot().requestRender(); 54378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 54478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 54578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang @Override 546a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li public void onPreviewTextureCopied() { 547a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li ActivityBase.this.onPreviewTextureCopied(); 548a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li } 549a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li 550a1fb83c0f18518013c3b1d4ab8c0f78a7bc0710fWu-cheng Li @Override 55178b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang public void setServer(Server s) { 55278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang mServer = s; 55378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 55478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 55505e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong @Override 55605e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong public boolean isPanorama() { 55705e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong return ActivityBase.this.isPanoramaActivity(); 55805e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong } 55905e0d1744d7325621170aff167cb65b7dfdf18f2Angus Kong 560f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang private void setCameraRelativeFrame(Rect frame) { 561f3c71bf38a4f0c529d076ef93b2fae3aa59dbf4eChih-Chung Chang if (mServer != null) mServer.setCameraRelativeFrame(frame); 56278b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 56378b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang 56478b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang private void switchWithCaptureAnimation(int offset) { 56578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang if (mServer != null) mServer.switchWithCaptureAnimation(offset); 56678b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 567d03d34ac9f50857f38034749607ce07c161d5120Chih-Chung Chang 568d03d34ac9f50857f38034749607ce07c161d5120Chih-Chung Chang private void setSwipingEnabled(boolean enabled) { 569d03d34ac9f50857f38034749607ce07c161d5120Chih-Chung Chang if (mServer != null) mServer.setSwipingEnabled(enabled); 570d03d34ac9f50857f38034749607ce07c161d5120Chih-Chung Chang } 571a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang 572a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang private void notifyScreenNailChanged() { 573a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang if (mServer != null) mServer.notifyScreenNailChanged(); 574a60436f0df6fc4189473b5ed27887edbba30312cChih-Chung Chang } 57578b7bc5fe8e47bc422daf3b4e83cc7b241b210fdChih-Chung Chang } 5764d2aefbe7c108bae9e4ae735c7cd230792201098Chih-Chung Chang} 577