CameraActivity.java revision 15125661ad968cf4d40989a9bc88d11189beb0b3
18872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb/*
28872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * Copyright (C) 2012 The Android Open Source Project
38872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb *
48872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * Licensed under the Apache License, Version 2.0 (the "License");
58872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * you may not use this file except in compliance with the License.
68872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * You may obtain a copy of the License at
78872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb *
88872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb *      http://www.apache.org/licenses/LICENSE-2.0
98872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb *
108872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * Unless required by applicable law or agreed to in writing, software
118872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * distributed under the License is distributed on an "AS IS" BASIS,
128872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * See the License for the specific language governing permissions and
148872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * limitations under the License.
158872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb */
168872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
178872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbpackage com.android.camera;
188872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
19742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liuimport android.animation.Animator;
20fa9e2cc9ccbcd746f5765cb7a0afebcdb60e2973ztenghuiimport android.app.ActionBar;
216432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.app.Activity;
224f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kongimport android.app.AlertDialog;
23b84b9738c855a525dc1944165983cc3c342ce446Doris Liuimport android.content.BroadcastReceiver;
2486d36313d88fe96354f2cdd4f378e5ff8397c458Angus Kongimport android.content.ComponentName;
256432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.content.ContentResolver;
2608650187c1f1a2d1ef7f754be0f479a29958daaaMichael Kolbimport android.content.Context;
274f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kongimport android.content.DialogInterface;
288872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.content.Intent;
29b84b9738c855a525dc1944165983cc3c342ce446Doris Liuimport android.content.IntentFilter;
3086d36313d88fe96354f2cdd4f378e5ff8397c458Angus Kongimport android.content.ServiceConnection;
312654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberlingimport android.content.SharedPreferences;
323cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liuimport android.content.pm.ActivityInfo;
338872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.content.res.Configuration;
346432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.graphics.drawable.ColorDrawable;
356432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.net.Uri;
366f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberlingimport android.os.AsyncTask;
378872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.os.Bundle;
386432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.os.Handler;
3986d36313d88fe96354f2cdd4f378e5ff8397c458Angus Kongimport android.os.IBinder;
402654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberlingimport android.preference.PreferenceManager;
412a7f44cac888de5683d05bef5708f846ee950f43Doris Liuimport android.provider.MediaStore;
423cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liuimport android.provider.Settings;
4337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberlingimport android.util.Log;
448872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.view.KeyEvent;
456432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.view.LayoutInflater;
460353ca2e048543bd6e233b4c2110a1df1070cd3fztenghuiimport android.view.Menu;
470353ca2e048543bd6e233b4c2110a1df1070cd3fztenghuiimport android.view.MenuInflater;
480353ca2e048543bd6e233b4c2110a1df1070cd3fztenghuiimport android.view.MenuItem;
49742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liuimport android.view.MotionEvent;
508872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.view.OrientationEventListener;
518872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.view.View;
526432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.view.ViewGroup;
5308650187c1f1a2d1ef7f754be0f479a29958daaaMichael Kolbimport android.view.Window;
5408650187c1f1a2d1ef7f754be0f479a29958daaaMichael Kolbimport android.view.WindowManager;
55653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kongimport android.widget.FrameLayout;
566432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.widget.ImageView;
5737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberlingimport android.widget.ProgressBar;
58cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiwareimport android.widget.ShareActionProvider;
598872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
60ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport com.android.camera.app.AppManagerFactory;
61ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport com.android.camera.app.PanoramaStitchingManager;
626432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport com.android.camera.data.CameraDataAdapter;
638e5e4eedb25a4589342660b928935acca4375fc7Angus Kongimport com.android.camera.data.CameraPreviewData;
648e5e4eedb25a4589342660b928935acca4375fc7Angus Kongimport com.android.camera.data.FixedFirstDataAdapter;
658e5e4eedb25a4589342660b928935acca4375fc7Angus Kongimport com.android.camera.data.FixedLastDataAdapter;
666432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport com.android.camera.data.LocalData;
678e5e4eedb25a4589342660b928935acca4375fc7Angus Kongimport com.android.camera.data.LocalDataAdapter;
686f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberlingimport com.android.camera.data.MediaDetails;
69bd26069d391830856c57c2141cd2efbc8423d871Angus Kongimport com.android.camera.data.SimpleViewData;
70a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberlingimport com.android.camera.tinyplanet.TinyPlanetFragment;
71ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport com.android.camera.ui.ModuleSwitcher;
726f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberlingimport com.android.camera.ui.DetailsDialog;
736432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport com.android.camera.ui.FilmStripView;
7488ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberlingimport com.android.camera.util.ApiHelper;
75b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kongimport com.android.camera.util.CameraUtil;
7637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberlingimport com.android.camera.util.PhotoSphereHelper;
7788ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberlingimport com.android.camera.util.PhotoSphereHelper.PanoramaViewHelper;
788e963a5a6016d246184ed65906f9d103e92b17e2Sascha Haeberlingimport com.android.camera2.R;
798872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
804f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kongimport static com.android.camera.CameraManager.CameraOpenErrorCallback;
814f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong
826432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liupublic class CameraActivity extends Activity
83a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        implements ModuleSwitcher.ModuleSwitchListener {
846432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
856432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private static final String TAG = "CAM_Activity";
866432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
876432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private static final String INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE =
886432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            "android.media.action.STILL_IMAGE_CAMERA_SECURE";
896432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public static final String ACTION_IMAGE_CAPTURE_SECURE =
906432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            "android.media.action.IMAGE_CAPTURE_SECURE";
916b9203214d828d72758943aca55adceab684a862ztenghui    public static final String ACTION_TRIM_VIDEO =
926b9203214d828d72758943aca55adceab684a862ztenghui            "com.android.camera.action.TRIM";
936b9203214d828d72758943aca55adceab684a862ztenghui    public static final String MEDIA_ITEM_PATH = "media-item-path";
946432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
952654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling    private static final String PREF_STARTUP_MODULE_INDEX = "camera.startup_module";
962654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling
976432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    // The intent extra for camera from secure lock screen. True if the gallery
986432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    // should only show newly captured pictures. sSecureAlbumId does not
996432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    // increment. This is used when switching between camera, camcorder, and
1006432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    // panorama. If the extra is not set, it is in the normal camera mode.
1016432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public static final String SECURE_CAMERA_EXTRA = "secure_camera";
1026432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
103b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    /**
104b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling     * Request code from an activity we started that indicated that we do not
105b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling     * want to reset the view to the preview in onResume.
106b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling     */
107b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    public static final int REQ_CODE_DONT_SWITCH_TO_PREVIEW = 142;
108b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling
109b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    /** Request code for external image editor activities. */
110b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    private static final int REQ_CODE_EDIT = 1;
111b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling
112b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling
113b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    /** Whether onResume should reset the view to the preview. */
114b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    private boolean mResetToPreviewOnResume = true;
115b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling
1160353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    // Supported operations at FilmStripView. Different data has different
1170353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    // set of supported operations.
1180353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private static final int SUPPORT_DELETE = 1 << 0;
1190353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private static final int SUPPORT_ROTATE = 1 << 1;
1200353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private static final int SUPPORT_INFO = 1 << 2;
1210353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private static final int SUPPORT_CROP = 1 << 3;
1220353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private static final int SUPPORT_SETAS = 1 << 4;
1230353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private static final int SUPPORT_EDIT = 1 << 5;
1240353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private static final int SUPPORT_TRIM = 1 << 6;
125cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private static final int SUPPORT_SHARE = 1 << 7;
126cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private static final int SUPPORT_SHARE_PANORAMA360 = 1 << 8;
127cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private static final int SUPPORT_SHOW_ON_MAP = 1 << 9;
1280353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private static final int SUPPORT_ALL = 0xffffffff;
1290353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui
1306f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling    /** This data adapter is used by FilmStripView. */
1318e5e4eedb25a4589342660b928935acca4375fc7Angus Kong    private LocalDataAdapter mDataAdapter;
1328e5e4eedb25a4589342660b928935acca4375fc7Angus Kong    /** This data adapter represents the real local camera data. */
1338e5e4eedb25a4589342660b928935acca4375fc7Angus Kong    private LocalDataAdapter mWrappedDataAdapter;
1348e5e4eedb25a4589342660b928935acca4375fc7Angus Kong
1356798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong    private PanoramaStitchingManager mPanoramaManager;
1368872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private int mCurrentModuleIndex;
1376432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private CameraModule mCurrentModule;
138653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong    private FrameLayout mAboveFilmstripControlLayout;
139653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong    private View mCameraModuleRootView;
1406432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private FilmStripView mFilmStripView;
14137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    private ProgressBar mBottomProgress;
14237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    private View mPanoStitchingPanel;
1436432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private int mResultCodeForTesting;
1446432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private Intent mResultDataForTesting;
1456432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private OnScreenHint mStorageHint;
1466432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private long mStorageSpace = Storage.LOW_STORAGE_THRESHOLD;
1473cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu    private boolean mAutoRotateScreen;
1486432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private boolean mSecureCamera;
1496a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    // This is a hack to speed up the start of SecureCamera.
1506a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    private static boolean sFirstStartAfterScreenOn = true;
1516432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private int mLastRawOrientation;
1528872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private MyOrientationEventListener mOrientationListener;
1536432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private Handler mMainHandler;
154f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling    private PanoramaViewHelper mPanoramaViewHelper;
1558e5e4eedb25a4589342660b928935acca4375fc7Angus Kong    private CameraPreviewData mCameraPreviewData;
156fa9e2cc9ccbcd746f5765cb7a0afebcdb60e2973ztenghui    private ActionBar mActionBar;
1570353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private Menu mActionBarMenu;
158653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong    private ViewGroup mUndoDeletionBar;
159742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    private boolean mIsUndoingDeletion = false;
1603cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu
161cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private ShareActionProvider mStandardShareActionProvider;
162cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private Intent mStandardShareIntent;
163cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private ShareActionProvider mPanoramaShareActionProvider;
164cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private Intent mPanoramaShareIntent;
165cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware
1665199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling    private final int DEFAULT_SYSTEM_UI_VISIBILITY = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
1675199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
168742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    private boolean mPendingDeletion = false;
1695199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling
17005804751ba07c8abcf422f57467d0ed3de95576cztenghui    private Intent mVideoShareIntent;
17105804751ba07c8abcf422f57467d0ed3de95576cztenghui    private Intent mImageShareIntent;
17205804751ba07c8abcf422f57467d0ed3de95576cztenghui
173734598c39e6a9d809982dae2907dc7d10e0b0e9fAngus Kong    public void gotoGallery() {
174734598c39e6a9d809982dae2907dc7d10e0b0e9fAngus Kong        mFilmStripView.getController().goToNextItem();
175734598c39e6a9d809982dae2907dc7d10e0b0e9fAngus Kong    }
176734598c39e6a9d809982dae2907dc7d10e0b0e9fAngus Kong
1778872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private class MyOrientationEventListener
178a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            extends OrientationEventListener {
1798872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        public MyOrientationEventListener(Context context) {
1808872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            super(context);
1818872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
1828872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
1838872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        @Override
1848872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        public void onOrientationChanged(int orientation) {
1858872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // We keep the last known orientation. So if the user first orient
1868872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // the camera then point the camera to floor or sky, we still have
1878872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // the correct orientation.
188a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            if (orientation == ORIENTATION_UNKNOWN) {
189a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                return;
190a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            }
1918872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            mLastRawOrientation = orientation;
1928872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            mCurrentModule.onOrientationChanged(orientation);
1938872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
1948872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
1958872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
1966432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private MediaSaveService mMediaSaveService;
1976432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private ServiceConnection mConnection = new ServiceConnection() {
198a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        @Override
199a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        public void onServiceConnected(ComponentName className, IBinder b) {
200a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            mMediaSaveService = ((MediaSaveService.LocalBinder) b).getService();
201a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            mCurrentModule.onMediaSaveServiceConnected(mMediaSaveService);
202a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        }
203a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling
204a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        @Override
205a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        public void onServiceDisconnected(ComponentName className) {
206a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            if (mMediaSaveService != null) {
207a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                mMediaSaveService.setListener(null);
208a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                mMediaSaveService = null;
2098872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            }
210a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        }
211a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling    };
212e319aeabdc825f221df5af8a6ec080c6f5d41a94John Reck
2134f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong    private CameraOpenErrorCallback mCameraOpenErrorCallback =
2144f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong            new CameraOpenErrorCallback() {
2154f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                @Override
2164f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                public void onCameraDisabled(int cameraId) {
2174f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                    CameraUtil.showErrorAndFinish(CameraActivity.this,
2184f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                            R.string.camera_disabled);
2194f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                }
2204f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong
2214f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                @Override
2224f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                public void onDeviceOpenFailure(int cameraId) {
2234f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                    CameraUtil.showErrorAndFinish(CameraActivity.this,
2244f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                            R.string.cannot_connect_camera);
2254f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                }
2264f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong
2274f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                @Override
2284f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                public void onReconnectionFailure(CameraManager mgr) {
2294f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                    CameraUtil.showErrorAndFinish(CameraActivity.this,
2304f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                            R.string.cannot_connect_camera);
2314f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                }
2324f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong            };
2334f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong
234b84b9738c855a525dc1944165983cc3c342ce446Doris Liu    // close activity when screen turns off
235b84b9738c855a525dc1944165983cc3c342ce446Doris Liu    private BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() {
236b84b9738c855a525dc1944165983cc3c342ce446Doris Liu        @Override
237b84b9738c855a525dc1944165983cc3c342ce446Doris Liu        public void onReceive(Context context, Intent intent) {
238b84b9738c855a525dc1944165983cc3c342ce446Doris Liu            finish();
239b84b9738c855a525dc1944165983cc3c342ce446Doris Liu        }
240b84b9738c855a525dc1944165983cc3c342ce446Doris Liu    };
241b84b9738c855a525dc1944165983cc3c342ce446Doris Liu
2426a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    private static BroadcastReceiver sScreenOffReceiver;
243a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling
2446a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    private static class ScreenOffReceiver extends BroadcastReceiver {
2456a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong        @Override
2466a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong        public void onReceive(Context context, Intent intent) {
2476a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong            sFirstStartAfterScreenOn = true;
2486a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong        }
2496a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    }
2506a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong
2516a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    public static boolean isFirstStartAfterScreenOn() {
2526a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong        return sFirstStartAfterScreenOn;
2536a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    }
2546a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong
2556a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    public static void resetFirstStartAfterScreenOn() {
2566a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong        sFirstStartAfterScreenOn = false;
2576a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    }
2586a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong
25937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    private FilmStripView.Listener mFilmStripListener =
26037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            new FilmStripView.Listener() {
26137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                @Override
26237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                public void onDataPromoted(int dataID) {
26337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    removeData(dataID);
26437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                }
265e319aeabdc825f221df5af8a6ec080c6f5d41a94John Reck
26637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                @Override
26737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                public void onDataDemoted(int dataID) {
26837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    removeData(dataID);
26937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                }
270e319aeabdc825f221df5af8a6ec080c6f5d41a94John Reck
27137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                @Override
27237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                public void onDataFullScreenChange(int dataID, boolean full) {
2738566dd777cd219254c945240a31ac97de28792a2ztenghui                    boolean isCameraID = isCameraPreview(dataID);
2747b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                    if (!isCameraID) {
2757b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                        setActionBarVisibilityAndLightsOut(full);
276fa9e2cc9ccbcd746f5765cb7a0afebcdb60e2973ztenghui                    }
27737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                }
27837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling
2798566dd777cd219254c945240a31ac97de28792a2ztenghui                /**
2808566dd777cd219254c945240a31ac97de28792a2ztenghui                 * Check if the local data corresponding to dataID is the camera
2818566dd777cd219254c945240a31ac97de28792a2ztenghui                 * preview.
2828566dd777cd219254c945240a31ac97de28792a2ztenghui                 *
2838566dd777cd219254c945240a31ac97de28792a2ztenghui                 * @param dataID the ID of the local data
2848566dd777cd219254c945240a31ac97de28792a2ztenghui                 * @return true if the local data is not null and it is the
2858566dd777cd219254c945240a31ac97de28792a2ztenghui                 *         camera preview.
2868566dd777cd219254c945240a31ac97de28792a2ztenghui                 */
2878566dd777cd219254c945240a31ac97de28792a2ztenghui                private boolean isCameraPreview(int dataID) {
2888566dd777cd219254c945240a31ac97de28792a2ztenghui                    LocalData localData = mDataAdapter.getLocalData(dataID);
2898566dd777cd219254c945240a31ac97de28792a2ztenghui                    if (localData == null) {
2908566dd777cd219254c945240a31ac97de28792a2ztenghui                        Log.w(TAG, "Current data ID not found.");
2918566dd777cd219254c945240a31ac97de28792a2ztenghui                        return false;
2928566dd777cd219254c945240a31ac97de28792a2ztenghui                    }
2938566dd777cd219254c945240a31ac97de28792a2ztenghui                    return localData.getLocalDataType() == LocalData.LOCAL_CAMERA_PREVIEW;
2948566dd777cd219254c945240a31ac97de28792a2ztenghui                }
2958566dd777cd219254c945240a31ac97de28792a2ztenghui
29637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                @Override
29733035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                public void onCurrentDataChanged(final int dataID, final boolean current) {
29833035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                    runOnUiThread(new Runnable() {
29933035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                        @Override
30033035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                        public void run() {
3017b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                            LocalData currentData = mDataAdapter.getLocalData(dataID);
3027b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                            if (currentData == null) {
3037b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                Log.w(TAG, "Current data ID not found.");
3047b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                hidePanoStitchingProgress();
3057b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                return;
3067b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                            }
3077b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                            boolean isCameraID = currentData.getLocalDataType() ==
3087b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                    LocalData.LOCAL_CAMERA_PREVIEW;
30933035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                            if (!current) {
3107b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                if (isCameraID) {
3117b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                    mCurrentModule.onPreviewFocusChanged(false);
3127b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                    setActionBarVisibilityAndLightsOut(false);
3137b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                }
31433035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                hidePanoStitchingProgress();
31533035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                            } else {
3167b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                if (isCameraID) {
3177b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                    mCurrentModule.onPreviewFocusChanged(true);
318a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                                    // Don't show the action bar in Camera
319a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                                    // preview.
3205199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling                                    setActionBarVisibilityAndLightsOut(true);
321742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                                    if (mPendingDeletion) {
322742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                                        performDeletion();
323742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                                    }
3241ef76d4cbd73c02cb8d02cf4cde3f4cee81548d6Alan Newberger                                } else {
3251ef76d4cbd73c02cb8d02cf4cde3f4cee81548d6Alan Newberger                                    updateActionBarMenu(dataID);
3261ef76d4cbd73c02cb8d02cf4cde3f4cee81548d6Alan Newberger                                }
32733035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware
32833035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                Uri contentUri = currentData.getContentUri();
32933035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                if (contentUri == null) {
33033035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                    hidePanoStitchingProgress();
33133035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                    return;
33233035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                }
33333035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                int panoStitchingProgress = mPanoramaManager.getTaskProgress(
334a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                                        contentUri);
33533035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                if (panoStitchingProgress < 0) {
33633035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                    hidePanoStitchingProgress();
33733035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                    return;
33833035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                }
33933035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                showPanoStitchingProgress();
34033035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                updateStitchingProgress(panoStitchingProgress);
34133035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                            }
34237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        }
34333035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                    });
34437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                }
345394023fb7e3c8d07d4aeafc30bf4b66ed481ebb7Sascha Haeberling
346394023fb7e3c8d07d4aeafc30bf4b66ed481ebb7Sascha Haeberling                @Override
3478566dd777cd219254c945240a31ac97de28792a2ztenghui                public boolean onToggleActionBarVisibility(int dataID) {
348394023fb7e3c8d07d4aeafc30bf4b66ed481ebb7Sascha Haeberling                    if (mActionBar.isShowing()) {
3495199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling                        setActionBarVisibilityAndLightsOut(true);
350394023fb7e3c8d07d4aeafc30bf4b66ed481ebb7Sascha Haeberling                    } else {
3518566dd777cd219254c945240a31ac97de28792a2ztenghui                        // Don't show the action bar if that is the camera preview.
3528566dd777cd219254c945240a31ac97de28792a2ztenghui                        boolean isCameraID = isCameraPreview(dataID);
3538566dd777cd219254c945240a31ac97de28792a2ztenghui                        if (!isCameraID) {
3545199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling                            setActionBarVisibilityAndLightsOut(false);
355fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui                        }
356394023fb7e3c8d07d4aeafc30bf4b66ed481ebb7Sascha Haeberling                    }
35788ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling                    return mActionBar.isShowing();
358394023fb7e3c8d07d4aeafc30bf4b66ed481ebb7Sascha Haeberling                }
35937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            };
36037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling
3615199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling    /**
3625199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling     * If enabled, this hides the action bar and switches the system UI to
3635199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling     * lights-out mode.
3645199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling     */
3655199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling    private void setActionBarVisibilityAndLightsOut(boolean enabled) {
3665199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling        if (enabled) {
3675199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling            mActionBar.hide();
3685199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling        } else {
3695199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling            mActionBar.show();
3705199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling        }
3715199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling        int visibility = DEFAULT_SYSTEM_UI_VISIBILITY | (enabled ? View.SYSTEM_UI_FLAG_LOW_PROFILE
3725199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling                : View.SYSTEM_UI_FLAG_VISIBLE);
3735199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling        mAboveFilmstripControlLayout
3745199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling                .setSystemUiVisibility(visibility);
3755199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling    }
3765199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling
37737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    private void hidePanoStitchingProgress() {
37837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        mPanoStitchingPanel.setVisibility(View.GONE);
37937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    }
38037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling
38137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    private void showPanoStitchingProgress() {
38237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        mPanoStitchingPanel.setVisibility(View.VISIBLE);
38337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    }
38437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling
38537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    private void updateStitchingProgress(int progress) {
38637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        mBottomProgress.setProgress(progress);
38737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    }
3888872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
389cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private void setStandardShareIntent(Uri contentUri, String mimeType) {
39005804751ba07c8abcf422f57467d0ed3de95576cztenghui        mStandardShareIntent = getShareIntentFromType(mimeType);
39105804751ba07c8abcf422f57467d0ed3de95576cztenghui        if (mStandardShareIntent != null) {
39205804751ba07c8abcf422f57467d0ed3de95576cztenghui            mStandardShareIntent.putExtra(Intent.EXTRA_STREAM, contentUri);
39305804751ba07c8abcf422f57467d0ed3de95576cztenghui            mStandardShareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
39405804751ba07c8abcf422f57467d0ed3de95576cztenghui            if (mStandardShareActionProvider != null) {
39505804751ba07c8abcf422f57467d0ed3de95576cztenghui                mStandardShareActionProvider.setShareIntent(mStandardShareIntent);
39605804751ba07c8abcf422f57467d0ed3de95576cztenghui            }
397cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        }
39805804751ba07c8abcf422f57467d0ed3de95576cztenghui    }
39905804751ba07c8abcf422f57467d0ed3de95576cztenghui
40005804751ba07c8abcf422f57467d0ed3de95576cztenghui    /**
40105804751ba07c8abcf422f57467d0ed3de95576cztenghui     * Get the share intent according to the mimeType
40205804751ba07c8abcf422f57467d0ed3de95576cztenghui     *
40305804751ba07c8abcf422f57467d0ed3de95576cztenghui     * @param mimeType The mimeType of current data.
40405804751ba07c8abcf422f57467d0ed3de95576cztenghui     * @return the video/image's ShareIntent or null if mimeType is invalid.
40505804751ba07c8abcf422f57467d0ed3de95576cztenghui     */
40605804751ba07c8abcf422f57467d0ed3de95576cztenghui    private Intent getShareIntentFromType(String mimeType) {
40705804751ba07c8abcf422f57467d0ed3de95576cztenghui        // Lazily create the intent object.
40805804751ba07c8abcf422f57467d0ed3de95576cztenghui        if (mimeType.startsWith("video/")) {
40905804751ba07c8abcf422f57467d0ed3de95576cztenghui            if (mVideoShareIntent == null) {
41005804751ba07c8abcf422f57467d0ed3de95576cztenghui                mVideoShareIntent = new Intent(Intent.ACTION_SEND);
41105804751ba07c8abcf422f57467d0ed3de95576cztenghui                mVideoShareIntent.setType("video/*");
41205804751ba07c8abcf422f57467d0ed3de95576cztenghui            }
41305804751ba07c8abcf422f57467d0ed3de95576cztenghui            return mVideoShareIntent;
41405804751ba07c8abcf422f57467d0ed3de95576cztenghui        } else if (mimeType.startsWith("image/")) {
41505804751ba07c8abcf422f57467d0ed3de95576cztenghui            if (mImageShareIntent == null) {
41605804751ba07c8abcf422f57467d0ed3de95576cztenghui                mImageShareIntent = new Intent(Intent.ACTION_SEND);
41705804751ba07c8abcf422f57467d0ed3de95576cztenghui                mImageShareIntent.setType("image/*");
41805804751ba07c8abcf422f57467d0ed3de95576cztenghui            }
41905804751ba07c8abcf422f57467d0ed3de95576cztenghui            return mImageShareIntent;
420cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        }
42105804751ba07c8abcf422f57467d0ed3de95576cztenghui        Log.w(TAG, "unsupported mimeType " + mimeType);
42205804751ba07c8abcf422f57467d0ed3de95576cztenghui        return null;
423cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    }
424cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware
425cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private void setPanoramaShareIntent(Uri contentUri) {
426cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        if (mPanoramaShareIntent == null) {
427cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware            mPanoramaShareIntent = new Intent(Intent.ACTION_SEND);
428cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        }
429cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        mPanoramaShareIntent.setType("application/vnd.google.panorama360+jpg");
430cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        mPanoramaShareIntent.putExtra(Intent.EXTRA_STREAM, contentUri);
431cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        if (mPanoramaShareActionProvider != null) {
432cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware            mPanoramaShareActionProvider.setShareIntent(mPanoramaShareIntent);
433cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        }
434cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    }
435cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware
4360353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    /**
4370353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui     * According to the data type, make the menu items for supported operations
4380353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui     * visible.
439a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     *
440fae11a165e344a38811770c7d348eda214683edcSascha Haeberling     * @param dataID the data ID of the current item.
4410353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui     */
442fae11a165e344a38811770c7d348eda214683edcSascha Haeberling    private void updateActionBarMenu(int dataID) {
443fae11a165e344a38811770c7d348eda214683edcSascha Haeberling        LocalData currentData = mDataAdapter.getLocalData(dataID);
444fae11a165e344a38811770c7d348eda214683edcSascha Haeberling        int type = currentData.getLocalDataType();
445fae11a165e344a38811770c7d348eda214683edcSascha Haeberling
4460353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        if (mActionBarMenu == null) {
4470353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            return;
4480353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        }
4490353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui
4500353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        int supported = 0;
4510353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        switch (type) {
4520353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case LocalData.LOCAL_IMAGE:
4530353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                supported |= SUPPORT_DELETE | SUPPORT_ROTATE | SUPPORT_INFO
4540353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                        | SUPPORT_CROP | SUPPORT_SETAS | SUPPORT_EDIT
455cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                        | SUPPORT_SHARE | SUPPORT_SHOW_ON_MAP;
4560353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                break;
4570353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case LocalData.LOCAL_VIDEO:
458cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                supported |= SUPPORT_DELETE | SUPPORT_INFO | SUPPORT_TRIM
459cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                        | SUPPORT_SHARE;
4600353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                break;
4610353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case LocalData.LOCAL_PHOTO_SPHERE:
4620353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                supported |= SUPPORT_DELETE | SUPPORT_ROTATE | SUPPORT_INFO
4630353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                        | SUPPORT_CROP | SUPPORT_SETAS | SUPPORT_EDIT
464cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                        | SUPPORT_SHARE | SUPPORT_SHOW_ON_MAP;
465cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                break;
466cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware            case LocalData.LOCAL_360_PHOTO_SPHERE:
467cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                supported |= SUPPORT_DELETE | SUPPORT_ROTATE | SUPPORT_INFO
468cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                        | SUPPORT_CROP | SUPPORT_SETAS | SUPPORT_EDIT
469cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                        | SUPPORT_SHARE | SUPPORT_SHARE_PANORAMA360
4700353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                        | SUPPORT_SHOW_ON_MAP;
4710353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                break;
4720353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            default:
4730353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                break;
4740353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        }
4750353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui
4760353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        setMenuItemVisible(mActionBarMenu, R.id.action_delete,
4770353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                (supported & SUPPORT_DELETE) != 0);
4780353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        setMenuItemVisible(mActionBarMenu, R.id.action_rotate_ccw,
4790353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                (supported & SUPPORT_ROTATE) != 0);
4800353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        setMenuItemVisible(mActionBarMenu, R.id.action_rotate_cw,
4810353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                (supported & SUPPORT_ROTATE) != 0);
482cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        setMenuItemVisible(mActionBarMenu, R.id.action_details,
483cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                (supported & SUPPORT_INFO) != 0);
4840353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        setMenuItemVisible(mActionBarMenu, R.id.action_crop,
4850353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                (supported & SUPPORT_CROP) != 0);
4860353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        setMenuItemVisible(mActionBarMenu, R.id.action_setas,
4870353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                (supported & SUPPORT_SETAS) != 0);
4880353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        setMenuItemVisible(mActionBarMenu, R.id.action_edit,
4890353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                (supported & SUPPORT_EDIT) != 0);
490cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        setMenuItemVisible(mActionBarMenu, R.id.action_trim,
491cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                (supported & SUPPORT_TRIM) != 0);
492cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware
49333035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        boolean standardShare = (supported & SUPPORT_SHARE) != 0;
49433035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        boolean panoramaShare = (supported & SUPPORT_SHARE_PANORAMA360) != 0;
49533035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        setMenuItemVisible(mActionBarMenu, R.id.action_share, standardShare);
49633035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        setMenuItemVisible(mActionBarMenu, R.id.action_share_panorama, panoramaShare);
49733035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware
49833035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        if (panoramaShare) {
49933035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            // For 360 PhotoSphere, relegate standard share to the overflow menu
50033035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            MenuItem item = mActionBarMenu.findItem(R.id.action_share);
50133035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            if (item != null) {
50233035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                item.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
50333035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                item.setTitle(getResources().getString(R.string.share_as_photo));
50433035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            }
50533035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            // And, promote "share as panorama" to action bar
50633035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            item = mActionBarMenu.findItem(R.id.action_share_panorama);
50733035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            if (item != null) {
50833035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
50933035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            }
510cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware            setPanoramaShareIntent(currentData.getContentUri());
511cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        }
51233035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        if (standardShare) {
51333035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            if (!panoramaShare) {
51433035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                MenuItem item = mActionBarMenu.findItem(R.id.action_share);
51533035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                if (item != null) {
51633035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                    item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
51733035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                    item.setTitle(getResources().getString(R.string.share));
51833035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                }
51933035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            }
52033035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            setStandardShareIntent(currentData.getContentUri(), currentData.getMimeType());
52133035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        }
522fae11a165e344a38811770c7d348eda214683edcSascha Haeberling
523fae11a165e344a38811770c7d348eda214683edcSascha Haeberling        boolean itemHasLocation = currentData.getLatLong() != null;
524fae11a165e344a38811770c7d348eda214683edcSascha Haeberling        setMenuItemVisible(mActionBarMenu, R.id.action_show_on_map,
525fae11a165e344a38811770c7d348eda214683edcSascha Haeberling                itemHasLocation && (supported & SUPPORT_SHOW_ON_MAP) != 0);
5260353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    }
5270353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui
5280353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private void setMenuItemVisible(Menu menu, int itemId, boolean visible) {
5290353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        MenuItem item = menu.findItem(itemId);
5300353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        if (item != null)
5310353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            item.setVisible(visible);
5320353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    }
5330353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui
5346798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong    private ImageTaskManager.TaskListener mStitchingListener =
5356798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong            new ImageTaskManager.TaskListener() {
5366798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong                @Override
53737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                public void onTaskQueued(String filePath, final Uri imageUri) {
53837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    mMainHandler.post(new Runnable() {
53937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        @Override
54037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        public void run() {
54137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            notifyNewMedia(imageUri);
54237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        }
54337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    });
5446798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong                }
5456798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong
5466798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong                @Override
54737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                public void onTaskDone(String filePath, final Uri imageUri) {
54837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    Log.v(TAG, "onTaskDone:" + filePath);
54937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    mMainHandler.post(new Runnable() {
55037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        @Override
55137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        public void run() {
55237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            int doneID = mDataAdapter.findDataByContentUri(imageUri);
55337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            int currentDataId = mFilmStripView.getCurrentId();
55437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling
55537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            if (currentDataId == doneID) {
55637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                                hidePanoStitchingProgress();
55737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                                updateStitchingProgress(0);
55837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            }
55937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling
56037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            mDataAdapter.refresh(getContentResolver(), imageUri);
56137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        }
56237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    });
5636798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong                }
5646798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong
5656798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong                @Override
5666798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong                public void onTaskProgress(
56737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        String filePath, final Uri imageUri, final int progress) {
56837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    mMainHandler.post(new Runnable() {
56937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        @Override
57037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        public void run() {
57137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            int currentDataId = mFilmStripView.getCurrentId();
57237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            if (currentDataId == -1) {
57337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                                return;
57437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            }
57537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            if (imageUri.equals(
57637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                                    mDataAdapter.getLocalData(currentDataId).getContentUri())) {
57737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                                updateStitchingProgress(progress);
57837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            }
57937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        }
58037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    });
5816798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong                }
5826798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong            };
5836798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong
5846432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public MediaSaveService getMediaSaveService() {
5856432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return mMediaSaveService;
5868872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
5878872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
5886432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void notifyNewMedia(Uri uri) {
5896432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        ContentResolver cr = getContentResolver();
5906432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        String mimeType = cr.getType(uri);
5916432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (mimeType.startsWith("video/")) {
592b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong            sendBroadcast(new Intent(CameraUtil.ACTION_NEW_VIDEO, uri));
5936432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mDataAdapter.addNewVideo(cr, uri);
5946432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else if (mimeType.startsWith("image/")) {
595b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong            CameraUtil.broadcastNewPicture(this, uri);
5966432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mDataAdapter.addNewPhoto(cr, uri);
59737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        } else if (mimeType.startsWith("application/stitching-preview")) {
59837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            mDataAdapter.addNewPhoto(cr, uri);
5996432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else {
6006432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            android.util.Log.w(TAG, "Unknown new media with MIME type:"
6016432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                    + mimeType + ", uri:" + uri);
6026432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
6038872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
6048872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
6056432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private void removeData(int dataID) {
6066432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mDataAdapter.removeData(CameraActivity.this, dataID);
607742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        if (mDataAdapter.getTotalNumber() > 1) {
608742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            showUndoDeletionBar();
609742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        } else {
610742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // If camera preview is the only view left in filmstrip,
611742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // no need to show undo bar.
612742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            performDeletion();
613742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        }
6148872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
6158872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
6166432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private void bindMediaSaveService() {
6176432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        Intent intent = new Intent(this, MediaSaveService.class);
6186432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
6198872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
6208872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
6216432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private void unbindMediaSaveService() {
6226432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (mConnection != null) {
6236432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            unbindService(mConnection);
6246432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
6258872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
6268872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
6276432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    @Override
6280353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    public boolean onCreateOptionsMenu(Menu menu) {
6290353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        // Inflate the menu items for use in the action bar
6300353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        MenuInflater inflater = getMenuInflater();
6310353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        inflater.inflate(R.menu.operations, menu);
6320353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        mActionBarMenu = menu;
633cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware
634cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        // Configure the standard share action provider
635cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        MenuItem item = menu.findItem(R.id.action_share);
636cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        mStandardShareActionProvider = (ShareActionProvider) item.getActionProvider();
63733035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        mStandardShareActionProvider.setShareHistoryFileName("standard_share_history.xml");
638cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        if (mStandardShareIntent != null) {
639cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware            mStandardShareActionProvider.setShareIntent(mStandardShareIntent);
640cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        }
641cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware
642cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        // Configure the panorama share action provider
643cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        item = menu.findItem(R.id.action_share_panorama);
644cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        mPanoramaShareActionProvider = (ShareActionProvider) item.getActionProvider();
64533035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        mPanoramaShareActionProvider.setShareHistoryFileName("panorama_share_history.xml");
646cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        if (mPanoramaShareIntent != null) {
647cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware            mPanoramaShareActionProvider.setShareIntent(mPanoramaShareIntent);
648cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        }
649cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware
6500353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        return super.onCreateOptionsMenu(menu);
6510353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    }
6520353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui
6530353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    @Override
6540353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    public boolean onOptionsItemSelected(MenuItem item) {
6556f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling        int currentDataId = mFilmStripView.getCurrentId();
6566f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling        if (currentDataId < 0) {
6576f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling            return false;
6586f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling        }
6596f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling        final LocalData localData = mDataAdapter.getLocalData(currentDataId);
6606f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling
6610353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        // Handle presses on the action bar items
6620353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        switch (item.getItemId()) {
6633f969c1735e2636bf22dfe44104d0e99924cca97Alan Newberger            case android.R.id.home:
6643f969c1735e2636bf22dfe44104d0e99924cca97Alan Newberger                // ActionBar's Up/Home button was clicked
6653f969c1735e2636bf22dfe44104d0e99924cca97Alan Newberger                mFilmStripView.getController().goToFirstItem();
6663f969c1735e2636bf22dfe44104d0e99924cca97Alan Newberger                return true;
6670353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case R.id.action_delete:
668e857cc90a98e280e2008beb03e2446bd642d2ec4Angus Kong                removeData(currentDataId);
6690353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
6700353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case R.id.action_edit:
67188ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling                launchEditor(localData);
6720353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
6730819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard            case R.id.action_trim: {
6746b9203214d828d72758943aca55adceab684a862ztenghui                // This is going to be handled by the Gallery app.
6756b9203214d828d72758943aca55adceab684a862ztenghui                Intent intent = new Intent(ACTION_TRIM_VIDEO);
6766b9203214d828d72758943aca55adceab684a862ztenghui                LocalData currentData = mDataAdapter.getLocalData(
6776b9203214d828d72758943aca55adceab684a862ztenghui                        mFilmStripView.getCurrentId());
6786b9203214d828d72758943aca55adceab684a862ztenghui                intent.setData(currentData.getContentUri());
6796b9203214d828d72758943aca55adceab684a862ztenghui                // We need the file path to wrap this into a RandomAccessFile.
6806b9203214d828d72758943aca55adceab684a862ztenghui                intent.putExtra(MEDIA_ITEM_PATH, currentData.getPath());
681b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                startActivityForResult(intent, REQ_CODE_DONT_SWITCH_TO_PREVIEW);
6820353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
6830819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard            }
6840353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case R.id.action_rotate_ccw:
685a16e7b50f3148f581439509279f242092e254309ztenghui                localData.rotate90Degrees(this, mDataAdapter, currentDataId, false);
6860353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
6870353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case R.id.action_rotate_cw:
688a16e7b50f3148f581439509279f242092e254309ztenghui                localData.rotate90Degrees(this, mDataAdapter, currentDataId, true);
6890353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
6900353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case R.id.action_crop:
6910353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                // TODO: add the functionality.
6920353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
6930819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard            case R.id.action_setas: {
6940819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard                Intent intent = new Intent(Intent.ACTION_ATTACH_DATA)
6950819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard                        .setDataAndType(localData.getContentUri(),
6960819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard                                localData.getMimeType())
6970819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard                        .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
6980819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard                intent.putExtra("mimeType", intent.getType());
699b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                startActivityForResult(Intent.createChooser(
700b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                        intent, getString(R.string.set_as)), REQ_CODE_DONT_SWITCH_TO_PREVIEW);
7010353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
7020819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard            }
7030353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case R.id.action_details:
7046f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                (new AsyncTask<Void, Void, MediaDetails>() {
7056f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                    @Override
7066f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                    protected MediaDetails doInBackground(Void... params) {
7076f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                        return localData.getMediaDetails(CameraActivity.this);
7086f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                    }
7096f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling
7106f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                    @Override
7116f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                    protected void onPostExecute(MediaDetails mediaDetails) {
7126f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                        DetailsDialog.create(CameraActivity.this, mediaDetails).show();
7136f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                    }
7146f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                }).execute();
7150353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
7160353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case R.id.action_show_on_map:
717fae11a165e344a38811770c7d348eda214683edcSascha Haeberling                double[] latLong = localData.getLatLong();
718fae11a165e344a38811770c7d348eda214683edcSascha Haeberling                if (latLong != null) {
719a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                    CameraUtil.showOnMap(this, latLong);
720fae11a165e344a38811770c7d348eda214683edcSascha Haeberling                }
7210353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
7220353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            default:
7230353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return super.onOptionsItemSelected(item);
7240353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        }
7250353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    }
7260353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui
727fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui    private boolean isCaptureIntent() {
728fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui        if (MediaStore.ACTION_VIDEO_CAPTURE.equals(getIntent().getAction())
729fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui                || MediaStore.ACTION_IMAGE_CAPTURE.equals(getIntent().getAction())
730fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui                || MediaStore.ACTION_IMAGE_CAPTURE_SECURE.equals(getIntent().getAction())) {
731fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui            return true;
732fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui        } else {
733fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui            return false;
734fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui        }
735fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui    }
736fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui
7370353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    @Override
7386432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void onCreate(Bundle state) {
7396432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        super.onCreate(state);
74050df47071c776703a36dbc4cb90ec8d1df3c0f6eztenghui        getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
7416432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        setContentView(R.layout.camera_filmstrip);
742fa9e2cc9ccbcd746f5765cb7a0afebcdb60e2973ztenghui        mActionBar = getActionBar();
743fa9e2cc9ccbcd746f5765cb7a0afebcdb60e2973ztenghui
7446432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (ApiHelper.HAS_ROTATION_ANIMATION) {
7456432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            setRotationAnimation();
7466432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
7476432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        // Check if this is in the secure camera mode.
7486432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        Intent intent = getIntent();
7496432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        String action = intent.getAction();
750b84b9738c855a525dc1944165983cc3c342ce446Doris Liu        if (INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE.equals(action)
751b84b9738c855a525dc1944165983cc3c342ce446Doris Liu                || ACTION_IMAGE_CAPTURE_SECURE.equals(action)) {
7526432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mSecureCamera = true;
7536432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else {
7546432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mSecureCamera = intent.getBooleanExtra(SECURE_CAMERA_EXTRA, false);
7558872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
756b84b9738c855a525dc1944165983cc3c342ce446Doris Liu
757b84b9738c855a525dc1944165983cc3c342ce446Doris Liu        if (mSecureCamera) {
758b84b9738c855a525dc1944165983cc3c342ce446Doris Liu            // Change the window flags so that secure camera can show when locked
759b84b9738c855a525dc1944165983cc3c342ce446Doris Liu            Window win = getWindow();
760b84b9738c855a525dc1944165983cc3c342ce446Doris Liu            WindowManager.LayoutParams params = win.getAttributes();
761b84b9738c855a525dc1944165983cc3c342ce446Doris Liu            params.flags |= WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
762b84b9738c855a525dc1944165983cc3c342ce446Doris Liu            win.setAttributes(params);
763b84b9738c855a525dc1944165983cc3c342ce446Doris Liu
764b84b9738c855a525dc1944165983cc3c342ce446Doris Liu            // Filter for screen off so that we can finish secure camera activity
765b84b9738c855a525dc1944165983cc3c342ce446Doris Liu            // when screen is off.
7666432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
7676432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            registerReceiver(mScreenOffReceiver, filter);
7686a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong            // TODO: This static screen off event receiver is a workaround to the
7696a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong            // double onResume() invocation (onResume->onPause->onResume). We should
7706a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong            // find a better solution to this.
7716a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong            if (sScreenOffReceiver == null) {
7726a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong                sScreenOffReceiver = new ScreenOffReceiver();
7736a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong                registerReceiver(sScreenOffReceiver, filter);
7746a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong            }
775b84b9738c855a525dc1944165983cc3c342ce446Doris Liu        }
776653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        mAboveFilmstripControlLayout =
777653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong                (FrameLayout) findViewById(R.id.camera_above_filmstrip_layout);
778653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        mAboveFilmstripControlLayout.setFitsSystemWindows(true);
7795199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling        // Hide action bar first since we are in full screen mode first, and
7805199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling        // switch the system UI to lights-out mode.
7815199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling        setActionBarVisibilityAndLightsOut(true);
782ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mPanoramaManager = AppManagerFactory.getInstance(this)
783ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                .getPanoramaStitchingManager();
7846798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong        mPanoramaManager.addTaskListener(mStitchingListener);
7856432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        LayoutInflater inflater = getLayoutInflater();
7866432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        View rootLayout = inflater.inflate(R.layout.camera, null, false);
787653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        mCameraModuleRootView = rootLayout.findViewById(R.id.camera_app_root);
788fa9e2cc9ccbcd746f5765cb7a0afebcdb60e2973ztenghui        mPanoStitchingPanel = findViewById(R.id.pano_stitching_progress_panel);
78937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        mBottomProgress = (ProgressBar) findViewById(R.id.pano_stitching_progress_bar);
7908e5e4eedb25a4589342660b928935acca4375fc7Angus Kong        mCameraPreviewData = new CameraPreviewData(rootLayout,
7918e5e4eedb25a4589342660b928935acca4375fc7Angus Kong                FilmStripView.ImageData.SIZE_FULL,
7928e5e4eedb25a4589342660b928935acca4375fc7Angus Kong                FilmStripView.ImageData.SIZE_FULL);
79337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        // Put a CameraPreviewData at the first position.
7948e5e4eedb25a4589342660b928935acca4375fc7Angus Kong        mWrappedDataAdapter = new FixedFirstDataAdapter(
7958e5e4eedb25a4589342660b928935acca4375fc7Angus Kong                new CameraDataAdapter(new ColorDrawable(
7968e5e4eedb25a4589342660b928935acca4375fc7Angus Kong                        getResources().getColor(R.color.photo_placeholder))),
7978e5e4eedb25a4589342660b928935acca4375fc7Angus Kong                mCameraPreviewData);
7986432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mFilmStripView = (FilmStripView) findViewById(R.id.filmstrip_view);
7996432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mFilmStripView.setViewGap(
8006432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                getResources().getDimensionPixelSize(R.dimen.camera_film_strip_gap));
801f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling        mPanoramaViewHelper = new PanoramaViewHelper(this);
802f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling        mPanoramaViewHelper.onCreate();
803f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling        mFilmStripView.setPanoramaViewHelper(mPanoramaViewHelper);
8046432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        // Set up the camera preview first so the preview shows up ASAP.
8056432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mFilmStripView.setListener(mFilmStripListener);
8062654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling
8072654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        int moduleIndex = -1;
8082a7f44cac888de5683d05bef5708f846ee950f43Doris Liu        if (MediaStore.INTENT_ACTION_VIDEO_CAMERA.equals(getIntent().getAction())
8092a7f44cac888de5683d05bef5708f846ee950f43Doris Liu                || MediaStore.ACTION_VIDEO_CAPTURE.equals(getIntent().getAction())) {
810ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            moduleIndex = ModuleSwitcher.VIDEO_MODULE_INDEX;
8112654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        } else if (MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA.equals(getIntent().getAction())
8122654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling                || MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE.equals(getIntent()
8132654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling                        .getAction())
8142654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling                || MediaStore.ACTION_IMAGE_CAPTURE.equals(getIntent().getAction())
8152654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling                || MediaStore.ACTION_IMAGE_CAPTURE_SECURE.equals(getIntent().getAction())) {
816ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            moduleIndex = ModuleSwitcher.PHOTO_MODULE_INDEX;
8172a7f44cac888de5683d05bef5708f846ee950f43Doris Liu        } else {
8182654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling            // If the activity has not been started using an explicit intent,
8192654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling            // read the module index from the last time the user changed modes
8202654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
8212654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling            moduleIndex = prefs.getInt(PREF_STARTUP_MODULE_INDEX, -1);
8222654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling            if (moduleIndex < 0) {
823ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                moduleIndex = ModuleSwitcher.PHOTO_MODULE_INDEX;
8242654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling            }
8252a7f44cac888de5683d05bef5708f846ee950f43Doris Liu        }
8262654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling
8276432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mOrientationListener = new MyOrientationEventListener(this);
828ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        setModuleFromIndex(moduleIndex);
829ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mCurrentModule.init(this, mCameraModuleRootView);
8306432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mMainHandler = new Handler(getMainLooper());
83137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling
83237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        if (!mSecureCamera) {
83337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            mDataAdapter = mWrappedDataAdapter;
834dcccc510652b835fdbd39310a07849af8203052aAngus Kong            mFilmStripView.setDataAdapter(mDataAdapter);
835a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong            if (!isCaptureIntent()) {
836a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong                mDataAdapter.requestLoad(getContentResolver());
837a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong            }
83837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        } else {
839a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            // Put a lock placeholder as the last image by setting its date to
840a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            // 0.
84137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            ImageView v = (ImageView) getLayoutInflater().inflate(
84237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    R.layout.secure_album_placeholder, null);
84337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            mDataAdapter = new FixedLastDataAdapter(
84437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    mWrappedDataAdapter,
845bd26069d391830856c57c2141cd2efbc8423d871Angus Kong                    new SimpleViewData(
84637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            v,
84737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            v.getDrawable().getIntrinsicWidth(),
84837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            v.getDrawable().getIntrinsicHeight(),
84937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            0, 0));
85037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            // Flush out all the original data.
85137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            mDataAdapter.flush();
852dcccc510652b835fdbd39310a07849af8203052aAngus Kong            mFilmStripView.setDataAdapter(mDataAdapter);
85337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        }
8548872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
8558872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
8566432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private void setRotationAnimation() {
8576432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        int rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE;
8586432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE;
8596432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        Window win = getWindow();
8606432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        WindowManager.LayoutParams winParams = win.getAttributes();
8616432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        winParams.rotationAnimation = rotationAnimation;
8626432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        win.setAttributes(winParams);
8638872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
8648872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
8658872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
8666432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void onUserInteraction() {
8676432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        super.onUserInteraction();
8686432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mCurrentModule.onUserInteraction();
86909106a41ee6acc6b20553662cb9b730702a8f08aDoris Liu    }
8708872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
8718872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
872742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    public boolean dispatchTouchEvent(MotionEvent ev) {
873742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        boolean result = super.dispatchTouchEvent(ev);
874742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
875742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // Real deletion is postponed until the next user interaction after
876742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // the gesture that triggers deletion. Until real deletion is performed,
877742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // users can click the undo button to bring back the image that they
878742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // chose to delete.
879742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            if (mPendingDeletion && !mIsUndoingDeletion) {
880742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                 performDeletion();
881742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            }
882742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        }
883742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        return result;
884742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    }
885742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu
886742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    @Override
8878872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void onPause() {
8888872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mOrientationListener.disable();
8898872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mCurrentModule.onPauseBeforeSuper();
8908872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        super.onPause();
8918872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mCurrentModule.onPauseAfterSuper();
8928872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
8938872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
8948872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
895b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
896b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        if (requestCode == REQ_CODE_EDIT && resultCode == RESULT_OK) {
897b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling            Uri uri = data.getData();
898b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling            ContentResolver contentResolver = getContentResolver();
899b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling            if (uri == null) {
900b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                // If we don't have a particular uri returned, then we have
901b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                // to refresh all, it is not optimal, but works best so far.
902b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                // Also don't requestLoad() when in secure camera mode.
903b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                if (!mSecureCamera) {
904b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                    mDataAdapter.requestLoad(contentResolver);
905b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                }
906b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling            } else {
907b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                mDataAdapter.refresh(contentResolver, uri);
908b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling            }
909b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        }
910b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling
911b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        if (requestCode == REQ_CODE_DONT_SWITCH_TO_PREVIEW | requestCode == REQ_CODE_EDIT) {
912b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling            mResetToPreviewOnResume = false;
913b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        } else {
914b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling            super.onActivityResult(requestCode, resultCode, data);
915b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        }
916b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    }
917b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling
918b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    @Override
9198872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void onResume() {
920ce2b94917098f211cacaaebaa0f6b40021d3e3faAngus Kong        // TODO: Handle this in OrientationManager.
921a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        // Auto-rotate off
9223cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu        if (Settings.System.getInt(getContentResolver(),
923a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                Settings.System.ACCELEROMETER_ROTATION, 0) == 0) {
9243cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
9253cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu            mAutoRotateScreen = false;
9263cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu        } else {
9273cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
9283cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu            mAutoRotateScreen = true;
9293cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu        }
9308872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mOrientationListener.enable();
9318872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mCurrentModule.onResumeBeforeSuper();
9328872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        super.onResume();
9338872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mCurrentModule.onResumeAfterSuper();
9348872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
9356798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong        setSwipingEnabled(true);
936b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling
937b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        if (mResetToPreviewOnResume) {
938b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling            // Go to the preview on resume.
939b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling            mFilmStripView.getController().goToFirstItem();
940b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        }
941b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        // Default is showing the preview, unless disabled by explicitly
942b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        // starting an activity we want to return from to the filmstrip rather
943b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        // than the preview.
944b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        mResetToPreviewOnResume = true;
9456798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong    }
9466798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong
9476798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong    @Override
9486798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong    public void onStart() {
9496798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong        super.onStart();
9507e374eb0a450ed2689b556ab42a0a88c8f74df2eAngus Kong        bindMediaSaveService();
951f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling        mPanoramaViewHelper.onStart();
952f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling    }
953f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling
954f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling    @Override
955f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling    protected void onStop() {
956f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling        super.onStop();
957f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling        mPanoramaViewHelper.onStop();
9587e374eb0a450ed2689b556ab42a0a88c8f74df2eAngus Kong        unbindMediaSaveService();
95908650187c1f1a2d1ef7f754be0f479a29958daaaMichael Kolb    }
96008650187c1f1a2d1ef7f754be0f479a29958daaaMichael Kolb
9618872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
9626432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void onDestroy() {
963a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        if (mSecureCamera) {
964a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            unregisterReceiver(mScreenOffReceiver);
965a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        }
9666432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        super.onDestroy();
9678872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
9688872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
9698872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
9706432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void onConfigurationChanged(Configuration config) {
9716432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        super.onConfigurationChanged(config);
9726432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mCurrentModule.onConfigurationChanged(config);
9738872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
9748872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
9758872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
9766432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public boolean onKeyDown(int keyCode, KeyEvent event) {
977a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        if (mCurrentModule.onKeyDown(keyCode, event)) {
978a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            return true;
979a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        }
9806432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        // Prevent software keyboard or voice search from showing up.
9816432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (keyCode == KeyEvent.KEYCODE_SEARCH
9826432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                || keyCode == KeyEvent.KEYCODE_MENU) {
983a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            if (event.isLongPress()) {
984a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                return true;
985a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            }
9866432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
9876432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
9886432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return super.onKeyDown(keyCode, event);
9898872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
9908872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
9918872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
9926432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public boolean onKeyUp(int keyCode, KeyEvent event) {
993a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        if (mCurrentModule.onKeyUp(keyCode, event)) {
994a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            return true;
995a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        }
9966432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return super.onKeyUp(keyCode, event);
9978872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
9988872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
9995f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger    @Override
10005f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger    public void onBackPressed() {
10015f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger        if (!mFilmStripView.inCameraFullscreen()) {
10025f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger            mFilmStripView.getController().goToFirstItem();
10035f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger        } else if (!mCurrentModule.onBackPressed()) {
10045f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger            super.onBackPressed();
10055f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger        }
10065f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger    }
10075f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger
10086432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public boolean isAutoRotateScreen() {
10096432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return mAutoRotateScreen;
10108872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10118872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10126432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    protected void updateStorageSpace() {
10136432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mStorageSpace = Storage.getAvailableSpace();
10148872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10158872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10166432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    protected long getStorageSpace() {
10176432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return mStorageSpace;
10188872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10198872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10206432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    protected void updateStorageSpaceAndHint() {
10216432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        updateStorageSpace();
10226432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        updateStorageHint(mStorageSpace);
10238872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10248872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10256432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    protected void updateStorageHint() {
10266432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        updateStorageHint(mStorageSpace);
10278872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10288872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10296432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    protected boolean updateStorageHintOnResume() {
10306432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return true;
10316432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
10326432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
10336432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    protected void updateStorageHint(long storageSpace) {
10346432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        String message = null;
10356432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (storageSpace == Storage.UNAVAILABLE) {
10366432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            message = getString(R.string.no_storage);
10376432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else if (storageSpace == Storage.PREPARING) {
10386432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            message = getString(R.string.preparing_sd);
10396432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else if (storageSpace == Storage.UNKNOWN_SIZE) {
10406432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            message = getString(R.string.access_sd_fail);
10416432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else if (storageSpace <= Storage.LOW_STORAGE_THRESHOLD) {
10426432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            message = getString(R.string.spaceIsLow_content);
10438872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
10446432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
10456432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (message != null) {
10466432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            if (mStorageHint == null) {
10476432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                mStorageHint = OnScreenHint.makeText(this, message);
10486432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            } else {
10496432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                mStorageHint.setText(message);
10506432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            }
10516432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mStorageHint.show();
10526432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else if (mStorageHint != null) {
10536432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mStorageHint.cancel();
10546432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mStorageHint = null;
10558872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
10568872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10578872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10586432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    protected void setResultEx(int resultCode) {
10596432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mResultCodeForTesting = resultCode;
10606432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        setResult(resultCode);
10618872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10628872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10636432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    protected void setResultEx(int resultCode, Intent data) {
10646432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mResultCodeForTesting = resultCode;
10656432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mResultDataForTesting = data;
10666432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        setResult(resultCode, data);
10678872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10688872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10696432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public int getResultCode() {
10706432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return mResultCodeForTesting;
10718872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10728872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10736432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public Intent getResultData() {
10746432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return mResultDataForTesting;
10758872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10768872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10776432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public boolean isSecureCamera() {
10786432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return mSecureCamera;
10798872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10808872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10818872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
1082ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void onModuleSelected(int moduleIndex) {
1083a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        if (mCurrentModuleIndex == moduleIndex) {
1084a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            return;
1085a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        }
10866432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
10876432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        CameraHolder.instance().keep();
10886432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        closeModule(mCurrentModule);
10892654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        setModuleFromIndex(moduleIndex);
10902654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling
10912654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        openModule(mCurrentModule);
10922654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        mCurrentModule.onOrientationChanged(mLastRawOrientation);
10932654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        if (mMediaSaveService != null) {
10942654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling            mCurrentModule.onMediaSaveServiceConnected(mMediaSaveService);
10952654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        }
10962654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling
10972654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        // Store the module index so we can use it the next time the Camera
10982654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        // starts up.
10992654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
11002654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        prefs.edit().putInt(PREF_STARTUP_MODULE_INDEX, moduleIndex).apply();
11012654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling    }
11022654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling
11032654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling    /**
1104a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     * Sets the mCurrentModuleIndex, creates a new module instance for the given
1105a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     * index an sets it as mCurrentModule.
11062654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling     */
11072654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling    private void setModuleFromIndex(int moduleIndex) {
11082654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        mCurrentModuleIndex = moduleIndex;
11092654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        switch (moduleIndex) {
111015125661ad968cf4d40989a9bc88d11189beb0b3Sascha Haeberling            case ModuleSwitcher.VIDEO_MODULE_INDEX:
11116432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                mCurrentModule = new VideoModule();
11126432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                break;
1113ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
111415125661ad968cf4d40989a9bc88d11189beb0b3Sascha Haeberling            case ModuleSwitcher.PHOTO_MODULE_INDEX:
11156432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                mCurrentModule = new PhotoModule();
11166432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                break;
1117ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
111815125661ad968cf4d40989a9bc88d11189beb0b3Sascha Haeberling            case ModuleSwitcher.WIDE_ANGLE_PANO_MODULE_INDEX:
1119ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                mCurrentModule = new WideAnglePanoramaModule();
1120ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                break;
1121ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
112215125661ad968cf4d40989a9bc88d11189beb0b3Sascha Haeberling            case ModuleSwitcher.LIGHTCYCLE_MODULE_INDEX:
11238e963a5a6016d246184ed65906f9d103e92b17e2Sascha Haeberling                mCurrentModule = PhotoSphereHelper.createPanoramaModule();
11246432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                break;
1125ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
11262654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling            default:
112715125661ad968cf4d40989a9bc88d11189beb0b3Sascha Haeberling                // Fall back to photo mode.
112815125661ad968cf4d40989a9bc88d11189beb0b3Sascha Haeberling                mCurrentModule = new PhotoModule();
112915125661ad968cf4d40989a9bc88d11189beb0b3Sascha Haeberling                mCurrentModuleIndex = ModuleSwitcher.PHOTO_MODULE_INDEX;
11302654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling                break;
11316432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
11328872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
11338872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
113488ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling    /**
113588ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling     * Launches an ACTION_EDIT intent for the given local data item.
113688ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling     */
113788ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling    public void launchEditor(LocalData data) {
113888ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling        Intent intent = new Intent(Intent.ACTION_EDIT)
113988ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling                .setDataAndType(data.getContentUri(), data.getMimeType())
114088ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling                .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
1141b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        startActivityForResult(Intent.createChooser(intent, null), REQ_CODE_EDIT);
114288ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling    }
114388ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling
1144a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling    /**
1145a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     * Launch the tiny planet editor.
1146a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     *
1147a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     * @param data the data must be a 360 degree stereographically mapped
1148a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     *            panoramic image. It will not be modified, instead a new item
1149a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     *            with the result will be added to the filmstrip.
1150a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     */
1151a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling    public void launchTinyPlanetEditor(LocalData data) {
1152a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        TinyPlanetFragment fragment = new TinyPlanetFragment();
1153a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        Bundle bundle = new Bundle();
1154a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        bundle.putString(TinyPlanetFragment.ARGUMENT_URI, data.getContentUri().toString());
1155a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        bundle.putString(TinyPlanetFragment.ARGUMENT_TITLE, data.getTitle());
1156a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        fragment.setArguments(bundle);
1157a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        fragment.show(getFragmentManager(), "tiny_planet");
1158a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling    }
1159a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling
11606432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private void openModule(CameraModule module) {
1161653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        module.init(this, mCameraModuleRootView);
11626432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        module.onResumeBeforeSuper();
11636432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        module.onResumeAfterSuper();
11648872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
11658872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
11666432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private void closeModule(CameraModule module) {
11676432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        module.onPauseBeforeSuper();
11686432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        module.onPauseAfterSuper();
1169653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        ((ViewGroup) mCameraModuleRootView).removeAllViews();
1170653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong    }
1171653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong
1172742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    private void performDeletion() {
1173742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        if (!mPendingDeletion) {
1174742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            return;
1175742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        }
1176742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        hideUndoDeletionBar(false);
1177742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        mDataAdapter.executeDeletion(CameraActivity.this);
1178742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    }
1179742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu
1180742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    public void showUndoDeletionBar() {
1181742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        if (mPendingDeletion) {
1182742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            performDeletion();
1183742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        }
1184742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        Log.v(TAG, "showing undo bar");
1185742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        mPendingDeletion = true;
1186653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        if (mUndoDeletionBar == null) {
1187653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong            ViewGroup v = (ViewGroup) getLayoutInflater().inflate(
1188653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong                    R.layout.undo_bar, mAboveFilmstripControlLayout, true);
1189653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong            mUndoDeletionBar = (ViewGroup) v.findViewById(R.id.camera_undo_deletion_bar);
1190653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong            View button = mUndoDeletionBar.findViewById(R.id.camera_undo_deletion_button);
1191653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong            button.setOnClickListener(new View.OnClickListener() {
1192653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong                @Override
1193653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong                public void onClick(View view) {
1194653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong                    mDataAdapter.undoDataRemoval();
1195742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                    hideUndoDeletionBar(true);
1196742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                }
1197742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            });
1198742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // Setting undo bar clickable to avoid touch events going through
1199742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // the bar to the buttons (eg. edit button, etc) underneath the bar.
1200742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            mUndoDeletionBar.setClickable(true);
1201742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // When there is user interaction going on with the undo button, we
1202742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // do not want to hide the undo bar.
1203742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            button.setOnTouchListener(new View.OnTouchListener() {
1204742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                @Override
1205742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                public boolean onTouch(View v, MotionEvent event) {
1206742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                    if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
1207742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                        mIsUndoingDeletion = true;
1208742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                    } else if (event.getActionMasked() == MotionEvent.ACTION_UP) {
1209742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                        mIsUndoingDeletion =false;
1210742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                    }
1211742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                    return false;
1212653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong                }
1213653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong            });
1214653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        }
1215653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        mUndoDeletionBar.setAlpha(0f);
1216653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        mUndoDeletionBar.setVisibility(View.VISIBLE);
1217742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        mUndoDeletionBar.animate().setDuration(200).alpha(1f).setListener(null).start();
1218653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong    }
1219653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong
1220742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    private void hideUndoDeletionBar(boolean withAnimation) {
1221653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        Log.v(TAG, "Hiding undo deletion bar");
1222742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        mPendingDeletion = false;
1223653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        if (mUndoDeletionBar != null) {
1224742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            if (withAnimation) {
1225742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                mUndoDeletionBar.animate()
1226742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                        .setDuration(200)
1227742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                        .alpha(0f)
1228742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                        .setListener(new Animator.AnimatorListener() {
1229742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            @Override
1230742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            public void onAnimationStart(Animator animation) {
1231742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                                // Do nothing.
1232742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            }
1233742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu
1234742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            @Override
1235742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            public void onAnimationEnd(Animator animation) {
1236742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                                mUndoDeletionBar.setVisibility(View.GONE);
1237742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            }
1238742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu
1239742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            @Override
1240742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            public void onAnimationCancel(Animator animation) {
1241742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                                // Do nothing.
1242742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            }
1243742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu
1244742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            @Override
1245742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            public void onAnimationRepeat(Animator animation) {
1246742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                                // Do nothing.
1247742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            }
1248742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                        })
1249742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                        .start();
1250742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            } else {
1251742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                mUndoDeletionBar.setVisibility(View.GONE);
1252742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            }
1253653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        }
12548872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
12558872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
12568872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
12576432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void onShowSwitcherPopup() {
12586432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
12596432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
1260a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong    /**
1261a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     * Enable/disable swipe-to-filmstrip. Will always disable swipe if in
1262a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     * capture intent.
1263a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong     *
1264a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong     * @param enable {@code true} to enable swipe.
1265a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong     */
12666432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void setSwipingEnabled(boolean enable) {
1267a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong        if (isCaptureIntent()) {
1268a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong            mCameraPreviewData.lockPreview(true);
1269a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong        } else {
1270a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong            mCameraPreviewData.lockPreview(!enable);
1271a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong        }
12728872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
12738872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
12748872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    // Accessor methods for getting latency times used in performance testing
12758872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public long getAutoFocusTime() {
12768872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return (mCurrentModule instanceof PhotoModule) ?
12778872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                ((PhotoModule) mCurrentModule).mAutoFocusTime : -1;
12788872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
12798872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
12808872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public long getShutterLag() {
12818872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return (mCurrentModule instanceof PhotoModule) ?
12828872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                ((PhotoModule) mCurrentModule).mShutterLag : -1;
12838872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
12848872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
12858872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public long getShutterToPictureDisplayedTime() {
12868872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return (mCurrentModule instanceof PhotoModule) ?
12878872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                ((PhotoModule) mCurrentModule).mShutterToPictureDisplayedTime : -1;
12888872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
12898872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
12908872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public long getPictureDisplayedToJpegCallbackTime() {
12918872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return (mCurrentModule instanceof PhotoModule) ?
12928872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                ((PhotoModule) mCurrentModule).mPictureDisplayedToJpegCallbackTime : -1;
12938872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
12948872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
12958872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public long getJpegCallbackFinishTime() {
12968872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return (mCurrentModule instanceof PhotoModule) ?
12978872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                ((PhotoModule) mCurrentModule).mJpegCallbackFinishTime : -1;
12988872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
12998872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
13008872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public long getCaptureStartTime() {
13018872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return (mCurrentModule instanceof PhotoModule) ?
13028872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                ((PhotoModule) mCurrentModule).mCaptureStartTime : -1;
13038872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
13048872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
13058872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public boolean isRecording() {
13068872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return (mCurrentModule instanceof VideoModule) ?
13078872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                ((VideoModule) mCurrentModule).isRecording() : false;
13088872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
13094f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong
13104f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong    public CameraOpenErrorCallback getCameraOpenErrorCallback() {
13114f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong        return mCameraOpenErrorCallback;
13124f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong    }
13138872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb}
1314