CameraActivity.java revision d4f69ed6fa6e302955ce8d0b2a21f47794ce7d64
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;
20a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiwareimport android.annotation.TargetApi;
21fa9e2cc9ccbcd746f5765cb7a0afebcdb60e2973ztenghuiimport android.app.ActionBar;
226432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.app.Activity;
23b84b9738c855a525dc1944165983cc3c342ce446Doris Liuimport android.content.BroadcastReceiver;
2486d36313d88fe96354f2cdd4f378e5ff8397c458Angus Kongimport android.content.ComponentName;
256432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.content.ContentResolver;
2608650187c1f1a2d1ef7f754be0f479a29958daaaMichael Kolbimport android.content.Context;
278872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.content.Intent;
28b84b9738c855a525dc1944165983cc3c342ce446Doris Liuimport android.content.IntentFilter;
2986d36313d88fe96354f2cdd4f378e5ff8397c458Angus Kongimport android.content.ServiceConnection;
302654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberlingimport android.content.SharedPreferences;
313cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liuimport android.content.pm.ActivityInfo;
328872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.content.res.Configuration;
336432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.graphics.drawable.ColorDrawable;
346432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.net.Uri;
35a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiwareimport android.nfc.NfcAdapter;
36a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiwareimport android.nfc.NfcAdapter.CreateBeamUrisCallback;
37a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiwareimport android.nfc.NfcEvent;
386f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberlingimport android.os.AsyncTask;
39a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiwareimport android.os.Build;
408872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.os.Bundle;
416432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.os.Handler;
4286d36313d88fe96354f2cdd4f378e5ff8397c458Angus Kongimport android.os.IBinder;
43aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liuimport android.os.Looper;
44aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liuimport android.os.Message;
452654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberlingimport android.preference.PreferenceManager;
462a7f44cac888de5683d05bef5708f846ee950f43Doris Liuimport android.provider.MediaStore;
473cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liuimport android.provider.Settings;
4837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberlingimport android.util.Log;
498872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.view.KeyEvent;
506432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.view.LayoutInflater;
510353ca2e048543bd6e233b4c2110a1df1070cd3fztenghuiimport android.view.Menu;
520353ca2e048543bd6e233b4c2110a1df1070cd3fztenghuiimport android.view.MenuInflater;
530353ca2e048543bd6e233b4c2110a1df1070cd3fztenghuiimport android.view.MenuItem;
54742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liuimport android.view.MotionEvent;
558872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.view.OrientationEventListener;
568872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.view.View;
576432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.view.ViewGroup;
5808650187c1f1a2d1ef7f754be0f479a29958daaaMichael Kolbimport android.view.Window;
5908650187c1f1a2d1ef7f754be0f479a29958daaaMichael Kolbimport android.view.WindowManager;
60653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kongimport android.widget.FrameLayout;
616432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.widget.ImageView;
6237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberlingimport android.widget.ProgressBar;
63cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiwareimport android.widget.ShareActionProvider;
648872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
65ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport com.android.camera.app.AppManagerFactory;
66ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport com.android.camera.app.PanoramaStitchingManager;
6719ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroardimport com.android.camera.crop.CropActivity;
686432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport com.android.camera.data.CameraDataAdapter;
698e5e4eedb25a4589342660b928935acca4375fc7Angus Kongimport com.android.camera.data.CameraPreviewData;
708e5e4eedb25a4589342660b928935acca4375fc7Angus Kongimport com.android.camera.data.FixedFirstDataAdapter;
718e5e4eedb25a4589342660b928935acca4375fc7Angus Kongimport com.android.camera.data.FixedLastDataAdapter;
726432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport com.android.camera.data.LocalData;
738e5e4eedb25a4589342660b928935acca4375fc7Angus Kongimport com.android.camera.data.LocalDataAdapter;
74064d6000933354f7bf344a41e0caa7052401c903ztenghuiimport com.android.camera.data.LocalMediaObserver;
756f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberlingimport com.android.camera.data.MediaDetails;
76bd26069d391830856c57c2141cd2efbc8423d871Angus Kongimport com.android.camera.data.SimpleViewData;
77a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberlingimport com.android.camera.tinyplanet.TinyPlanetFragment;
78ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport com.android.camera.ui.ModuleSwitcher;
796f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberlingimport com.android.camera.ui.DetailsDialog;
806432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport com.android.camera.ui.FilmStripView;
8188ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberlingimport com.android.camera.util.ApiHelper;
82b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kongimport com.android.camera.util.CameraUtil;
83a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunkimport com.android.camera.util.GcamHelper;
8437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberlingimport com.android.camera.util.PhotoSphereHelper;
8588ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberlingimport com.android.camera.util.PhotoSphereHelper.PanoramaViewHelper;
868e963a5a6016d246184ed65906f9d103e92b17e2Sascha Haeberlingimport com.android.camera2.R;
878872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
884f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kongimport static com.android.camera.CameraManager.CameraOpenErrorCallback;
894f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong
906432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liupublic class CameraActivity extends Activity
91aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu        implements ModuleSwitcher.ModuleSwitchListener,
92aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu        ActionBar.OnMenuVisibilityListener {
936432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
946432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private static final String TAG = "CAM_Activity";
956432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
966432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private static final String INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE =
976432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            "android.media.action.STILL_IMAGE_CAMERA_SECURE";
986432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public static final String ACTION_IMAGE_CAPTURE_SECURE =
996432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            "android.media.action.IMAGE_CAPTURE_SECURE";
1006b9203214d828d72758943aca55adceab684a862ztenghui    public static final String ACTION_TRIM_VIDEO =
1016b9203214d828d72758943aca55adceab684a862ztenghui            "com.android.camera.action.TRIM";
1026b9203214d828d72758943aca55adceab684a862ztenghui    public static final String MEDIA_ITEM_PATH = "media-item-path";
1036432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
1042654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling    private static final String PREF_STARTUP_MODULE_INDEX = "camera.startup_module";
1052654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling
1066432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    // The intent extra for camera from secure lock screen. True if the gallery
1076432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    // should only show newly captured pictures. sSecureAlbumId does not
1086432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    // increment. This is used when switching between camera, camcorder, and
1096432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    // panorama. If the extra is not set, it is in the normal camera mode.
1106432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public static final String SECURE_CAMERA_EXTRA = "secure_camera";
1116432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
112b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    /**
113b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling     * Request code from an activity we started that indicated that we do not
114b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling     * want to reset the view to the preview in onResume.
115b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling     */
116b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    public static final int REQ_CODE_DONT_SWITCH_TO_PREVIEW = 142;
117b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling
118aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu    private static final int HIDE_ACTION_BAR = 1;
119aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu    private static final long SHOW_ACTION_BAR_TIMEOUT_MS = 3000;
120aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu
121b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    /** Whether onResume should reset the view to the preview. */
122b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    private boolean mResetToPreviewOnResume = true;
123b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling
1240353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    // Supported operations at FilmStripView. Different data has different
1250353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    // set of supported operations.
1260353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private static final int SUPPORT_DELETE = 1 << 0;
1270353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private static final int SUPPORT_ROTATE = 1 << 1;
1280353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private static final int SUPPORT_INFO = 1 << 2;
1290353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private static final int SUPPORT_CROP = 1 << 3;
1300353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private static final int SUPPORT_SETAS = 1 << 4;
1310353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private static final int SUPPORT_EDIT = 1 << 5;
1320353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private static final int SUPPORT_TRIM = 1 << 6;
133cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private static final int SUPPORT_SHARE = 1 << 7;
134cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private static final int SUPPORT_SHARE_PANORAMA360 = 1 << 8;
135cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private static final int SUPPORT_SHOW_ON_MAP = 1 << 9;
1360353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private static final int SUPPORT_ALL = 0xffffffff;
1370353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui
1386f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling    /** This data adapter is used by FilmStripView. */
1398e5e4eedb25a4589342660b928935acca4375fc7Angus Kong    private LocalDataAdapter mDataAdapter;
1408e5e4eedb25a4589342660b928935acca4375fc7Angus Kong    /** This data adapter represents the real local camera data. */
1418e5e4eedb25a4589342660b928935acca4375fc7Angus Kong    private LocalDataAdapter mWrappedDataAdapter;
1428e5e4eedb25a4589342660b928935acca4375fc7Angus Kong
1436798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong    private PanoramaStitchingManager mPanoramaManager;
1448872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private int mCurrentModuleIndex;
1456432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private CameraModule mCurrentModule;
146653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong    private FrameLayout mAboveFilmstripControlLayout;
147653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong    private View mCameraModuleRootView;
1486432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private FilmStripView mFilmStripView;
14937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    private ProgressBar mBottomProgress;
15037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    private View mPanoStitchingPanel;
1516432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private int mResultCodeForTesting;
1526432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private Intent mResultDataForTesting;
1536432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private OnScreenHint mStorageHint;
1542dcc0a9dfcc23f090bbe36308f92d72f68c4f0a2Angus Kong    private long mStorageSpaceBytes = Storage.LOW_STORAGE_THRESHOLD_BYTES;
1553cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu    private boolean mAutoRotateScreen;
1566432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private boolean mSecureCamera;
1576a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    // This is a hack to speed up the start of SecureCamera.
1586a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    private static boolean sFirstStartAfterScreenOn = true;
1596432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private int mLastRawOrientation;
1608872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private MyOrientationEventListener mOrientationListener;
1616432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private Handler mMainHandler;
162f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling    private PanoramaViewHelper mPanoramaViewHelper;
1638e5e4eedb25a4589342660b928935acca4375fc7Angus Kong    private CameraPreviewData mCameraPreviewData;
164fa9e2cc9ccbcd746f5765cb7a0afebcdb60e2973ztenghui    private ActionBar mActionBar;
165aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu    private OnActionBarVisibilityListener mOnActionBarVisibilityListener = null;
1660353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private Menu mActionBarMenu;
167653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong    private ViewGroup mUndoDeletionBar;
168742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    private boolean mIsUndoingDeletion = false;
1693cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu
170a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware    private Uri[] mNfcPushUris = new Uri[1];
171a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware
172cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private ShareActionProvider mStandardShareActionProvider;
173cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private Intent mStandardShareIntent;
174cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private ShareActionProvider mPanoramaShareActionProvider;
175cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private Intent mPanoramaShareIntent;
176064d6000933354f7bf344a41e0caa7052401c903ztenghui    private LocalMediaObserver mLocalImagesObserver;
177064d6000933354f7bf344a41e0caa7052401c903ztenghui    private LocalMediaObserver mLocalVideosObserver;
178cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware
1795199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling    private final int DEFAULT_SYSTEM_UI_VISIBILITY = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
1805199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
181742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    private boolean mPendingDeletion = false;
1825199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling
18305804751ba07c8abcf422f57467d0ed3de95576cztenghui    private Intent mVideoShareIntent;
18405804751ba07c8abcf422f57467d0ed3de95576cztenghui    private Intent mImageShareIntent;
18505804751ba07c8abcf422f57467d0ed3de95576cztenghui
1868872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private class MyOrientationEventListener
187a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            extends OrientationEventListener {
1888872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        public MyOrientationEventListener(Context context) {
1898872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            super(context);
1908872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
1918872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
1928872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        @Override
1938872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        public void onOrientationChanged(int orientation) {
1948872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // We keep the last known orientation. So if the user first orient
1958872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // the camera then point the camera to floor or sky, we still have
1968872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // the correct orientation.
197a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            if (orientation == ORIENTATION_UNKNOWN) {
198a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                return;
199a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            }
2008872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            mLastRawOrientation = orientation;
2018872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            mCurrentModule.onOrientationChanged(orientation);
2028872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
2038872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
2048872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
2056432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private MediaSaveService mMediaSaveService;
2066432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private ServiceConnection mConnection = new ServiceConnection() {
207a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        @Override
208a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        public void onServiceConnected(ComponentName className, IBinder b) {
209a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            mMediaSaveService = ((MediaSaveService.LocalBinder) b).getService();
210a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            mCurrentModule.onMediaSaveServiceConnected(mMediaSaveService);
211a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        }
212a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling
213a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        @Override
214a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        public void onServiceDisconnected(ComponentName className) {
215a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            if (mMediaSaveService != null) {
216a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                mMediaSaveService.setListener(null);
217a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                mMediaSaveService = null;
2188872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            }
219a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        }
220a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling    };
221e319aeabdc825f221df5af8a6ec080c6f5d41a94John Reck
2224f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong    private CameraOpenErrorCallback mCameraOpenErrorCallback =
2234f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong            new CameraOpenErrorCallback() {
2244f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                @Override
2254f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                public void onCameraDisabled(int cameraId) {
2264f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                    CameraUtil.showErrorAndFinish(CameraActivity.this,
2274f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                            R.string.camera_disabled);
2284f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                }
2294f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong
2304f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                @Override
2314f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                public void onDeviceOpenFailure(int cameraId) {
2324f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                    CameraUtil.showErrorAndFinish(CameraActivity.this,
2334f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                            R.string.cannot_connect_camera);
2344f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                }
2354f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong
2364f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                @Override
2374f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                public void onReconnectionFailure(CameraManager mgr) {
2384f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                    CameraUtil.showErrorAndFinish(CameraActivity.this,
2394f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                            R.string.cannot_connect_camera);
2404f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                }
2414f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong            };
2424f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong
243b84b9738c855a525dc1944165983cc3c342ce446Doris Liu    // close activity when screen turns off
244b84b9738c855a525dc1944165983cc3c342ce446Doris Liu    private BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() {
245b84b9738c855a525dc1944165983cc3c342ce446Doris Liu        @Override
246b84b9738c855a525dc1944165983cc3c342ce446Doris Liu        public void onReceive(Context context, Intent intent) {
247b84b9738c855a525dc1944165983cc3c342ce446Doris Liu            finish();
248b84b9738c855a525dc1944165983cc3c342ce446Doris Liu        }
249b84b9738c855a525dc1944165983cc3c342ce446Doris Liu    };
250b84b9738c855a525dc1944165983cc3c342ce446Doris Liu
2516a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    private static BroadcastReceiver sScreenOffReceiver;
252a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling
2536a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    private static class ScreenOffReceiver extends BroadcastReceiver {
2546a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong        @Override
2556a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong        public void onReceive(Context context, Intent intent) {
2566a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong            sFirstStartAfterScreenOn = true;
2576a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong        }
2586a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    }
2596a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong
260aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu    private class MainHandler extends Handler {
261aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu        public MainHandler(Looper looper) {
262aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu            super(looper);
263aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu        }
264aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu
265aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu        @Override
266aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu        public void handleMessage(Message msg) {
267aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu            if (msg.what == HIDE_ACTION_BAR) {
268aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu                removeMessages(HIDE_ACTION_BAR);
269aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu                CameraActivity.this.setSystemBarsVisibility(false);
270aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu            }
271aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu        }
272aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu    }
273aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu
274aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu    public interface OnActionBarVisibilityListener {
275aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu        public void onActionBarVisibilityChanged(boolean isVisible);
276aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu    }
277aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu
278aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu    public void setOnActionBarVisibilityListener(OnActionBarVisibilityListener listener) {
279aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu        mOnActionBarVisibilityListener = listener;
280aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu    }
281aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu
2826a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    public static boolean isFirstStartAfterScreenOn() {
2836a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong        return sFirstStartAfterScreenOn;
2846a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    }
2856a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong
2866a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    public static void resetFirstStartAfterScreenOn() {
2876a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong        sFirstStartAfterScreenOn = false;
2886a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    }
2896a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong
29037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    private FilmStripView.Listener mFilmStripListener =
29137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            new FilmStripView.Listener() {
29237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                @Override
29337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                public void onDataPromoted(int dataID) {
29437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    removeData(dataID);
29537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                }
296e319aeabdc825f221df5af8a6ec080c6f5d41a94John Reck
29737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                @Override
29837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                public void onDataDemoted(int dataID) {
29937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    removeData(dataID);
30037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                }
301e319aeabdc825f221df5af8a6ec080c6f5d41a94John Reck
30237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                @Override
30337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                public void onDataFullScreenChange(int dataID, boolean full) {
3048566dd777cd219254c945240a31ac97de28792a2ztenghui                    boolean isCameraID = isCameraPreview(dataID);
3057b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                    if (!isCameraID) {
306aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu                        if (!full) {
307aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu                            // Always show action bar in filmstrip mode
308aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu                            CameraActivity.this.setSystemBarsVisibility(true, false);
309aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu                        } else if (mActionBar.isShowing()) {
310aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu                            // Hide action bar after time out in full screen mode
311aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu                            mMainHandler.sendEmptyMessageDelayed(HIDE_ACTION_BAR,
312aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu                                    SHOW_ACTION_BAR_TIMEOUT_MS);
313aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu                        }
314fa9e2cc9ccbcd746f5765cb7a0afebcdb60e2973ztenghui                    }
31537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                }
31637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling
3178566dd777cd219254c945240a31ac97de28792a2ztenghui                /**
3188566dd777cd219254c945240a31ac97de28792a2ztenghui                 * Check if the local data corresponding to dataID is the camera
3198566dd777cd219254c945240a31ac97de28792a2ztenghui                 * preview.
3208566dd777cd219254c945240a31ac97de28792a2ztenghui                 *
3218566dd777cd219254c945240a31ac97de28792a2ztenghui                 * @param dataID the ID of the local data
3228566dd777cd219254c945240a31ac97de28792a2ztenghui                 * @return true if the local data is not null and it is the
3238566dd777cd219254c945240a31ac97de28792a2ztenghui                 *         camera preview.
3248566dd777cd219254c945240a31ac97de28792a2ztenghui                 */
3258566dd777cd219254c945240a31ac97de28792a2ztenghui                private boolean isCameraPreview(int dataID) {
3268566dd777cd219254c945240a31ac97de28792a2ztenghui                    LocalData localData = mDataAdapter.getLocalData(dataID);
3278566dd777cd219254c945240a31ac97de28792a2ztenghui                    if (localData == null) {
3288566dd777cd219254c945240a31ac97de28792a2ztenghui                        Log.w(TAG, "Current data ID not found.");
3298566dd777cd219254c945240a31ac97de28792a2ztenghui                        return false;
3308566dd777cd219254c945240a31ac97de28792a2ztenghui                    }
3318566dd777cd219254c945240a31ac97de28792a2ztenghui                    return localData.getLocalDataType() == LocalData.LOCAL_CAMERA_PREVIEW;
3328566dd777cd219254c945240a31ac97de28792a2ztenghui                }
3338566dd777cd219254c945240a31ac97de28792a2ztenghui
33437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                @Override
33533035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                public void onCurrentDataChanged(final int dataID, final boolean current) {
336aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu                    // Delay hiding action bar if there is any user interaction
337aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu                    if (mMainHandler.hasMessages(HIDE_ACTION_BAR)) {
338aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu                        mMainHandler.removeMessages(HIDE_ACTION_BAR);
339aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu                        mMainHandler.sendEmptyMessageDelayed(HIDE_ACTION_BAR,
340aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu                                SHOW_ACTION_BAR_TIMEOUT_MS);
341aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu                    }
34233035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                    runOnUiThread(new Runnable() {
34333035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                        @Override
34433035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                        public void run() {
3457b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                            LocalData currentData = mDataAdapter.getLocalData(dataID);
3467b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                            if (currentData == null) {
3477b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                Log.w(TAG, "Current data ID not found.");
3487b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                hidePanoStitchingProgress();
3497b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                return;
3507b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                            }
3517b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                            boolean isCameraID = currentData.getLocalDataType() ==
3527b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                    LocalData.LOCAL_CAMERA_PREVIEW;
35333035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                            if (!current) {
3547b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                if (isCameraID) {
3557b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                    mCurrentModule.onPreviewFocusChanged(false);
356aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu                                    CameraActivity.this.setSystemBarsVisibility(true);
3577b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                }
35833035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                hidePanoStitchingProgress();
35933035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                            } else {
3607b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                if (isCameraID) {
3617b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                    mCurrentModule.onPreviewFocusChanged(true);
362a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                                    // Don't show the action bar in Camera
363a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                                    // preview.
364aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu                                    CameraActivity.this.setSystemBarsVisibility(false);
365742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                                    if (mPendingDeletion) {
366742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                                        performDeletion();
367742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                                    }
3681ef76d4cbd73c02cb8d02cf4cde3f4cee81548d6Alan Newberger                                } else {
3691ef76d4cbd73c02cb8d02cf4cde3f4cee81548d6Alan Newberger                                    updateActionBarMenu(dataID);
3701ef76d4cbd73c02cb8d02cf4cde3f4cee81548d6Alan Newberger                                }
37133035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware
37233035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                Uri contentUri = currentData.getContentUri();
37333035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                if (contentUri == null) {
37433035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                    hidePanoStitchingProgress();
37533035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                    return;
37633035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                }
37733035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                int panoStitchingProgress = mPanoramaManager.getTaskProgress(
378a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                                        contentUri);
37933035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                if (panoStitchingProgress < 0) {
38033035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                    hidePanoStitchingProgress();
38133035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                    return;
38233035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                }
38333035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                showPanoStitchingProgress();
38433035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                updateStitchingProgress(panoStitchingProgress);
38533035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                            }
38637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        }
38733035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                    });
38837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                }
389394023fb7e3c8d07d4aeafc30bf4b66ed481ebb7Sascha Haeberling
390394023fb7e3c8d07d4aeafc30bf4b66ed481ebb7Sascha Haeberling                @Override
391aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu                public void onToggleSystemDecorsVisibility(int dataID) {
392aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu                    // If action bar is showing, hide it immediately, otherwise
393aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu                    // show action bar and hide it later
394394023fb7e3c8d07d4aeafc30bf4b66ed481ebb7Sascha Haeberling                    if (mActionBar.isShowing()) {
395aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu                        CameraActivity.this.setSystemBarsVisibility(false);
396394023fb7e3c8d07d4aeafc30bf4b66ed481ebb7Sascha Haeberling                    } else {
3978566dd777cd219254c945240a31ac97de28792a2ztenghui                        // Don't show the action bar if that is the camera preview.
3988566dd777cd219254c945240a31ac97de28792a2ztenghui                        boolean isCameraID = isCameraPreview(dataID);
3998566dd777cd219254c945240a31ac97de28792a2ztenghui                        if (!isCameraID) {
400aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu                            CameraActivity.this.setSystemBarsVisibility(true, true);
401fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui                        }
402394023fb7e3c8d07d4aeafc30bf4b66ed481ebb7Sascha Haeberling                    }
403394023fb7e3c8d07d4aeafc30bf4b66ed481ebb7Sascha Haeberling                }
404aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu
405aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu                @Override
406aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu                public void setSystemDecorsVisibility(boolean visible) {
407aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu                    CameraActivity.this.setSystemBarsVisibility(visible);
408aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu                }
40937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            };
41037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling
4114ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling    public void gotoGallery() {
4124ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling        mFilmStripView.getController().goToNextItem();
4134ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling    }
4144ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling
4155199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling    /**
416aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu     * If {@param visible} is false, this hides the action bar and switches the system UI
417aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu     * to lights-out mode.
4185199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling     */
419aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu
420aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu    private void setSystemBarsVisibility(boolean visible) {
421aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu        setSystemBarsVisibility(visible, false);
422aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu    }
423aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu
424aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu    /**
425aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu     * If {@param visible} is false, this hides the action bar and switches the
426aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu     * system UI to lights-out mode. If {@param hideLater} is true, a delayed message
427aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu     * will be sent after a timeout to hide the action bar.
428aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu     */
429aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu    private void setSystemBarsVisibility(boolean visible, boolean hideLater) {
430aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu        mMainHandler.removeMessages(HIDE_ACTION_BAR);
431aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu        boolean currentlyVisible = mActionBar.isShowing();
432aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu
433aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu        if (visible != currentlyVisible) {
434aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu            int visibility = DEFAULT_SYSTEM_UI_VISIBILITY | (visible ? View.SYSTEM_UI_FLAG_VISIBLE
4350156d9179bb9ba8718b25ee05985a7c71e5578c7Sascha Haeberling                    : View.SYSTEM_UI_FLAG_LOW_PROFILE | View.SYSTEM_UI_FLAG_FULLSCREEN);
436aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu            mAboveFilmstripControlLayout.setSystemUiVisibility(visibility);
437aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu            if (visible) {
438aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu                mActionBar.show();
439aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu            } else {
440aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu                mActionBar.hide();
441aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu            }
442aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu            if (mOnActionBarVisibilityListener != null) {
443aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu                mOnActionBarVisibilityListener.onActionBarVisibilityChanged(visible);
444aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu            }
445aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu        }
446aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu
447aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu        // Now delay hiding the bars
448aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu        if (visible && hideLater) {
449aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu            mMainHandler.sendEmptyMessageDelayed(HIDE_ACTION_BAR, SHOW_ACTION_BAR_TIMEOUT_MS);
4505199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling        }
4515199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling    }
4525199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling
45337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    private void hidePanoStitchingProgress() {
45437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        mPanoStitchingPanel.setVisibility(View.GONE);
45537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    }
45637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling
45737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    private void showPanoStitchingProgress() {
45837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        mPanoStitchingPanel.setVisibility(View.VISIBLE);
45937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    }
46037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling
46137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    private void updateStitchingProgress(int progress) {
46237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        mBottomProgress.setProgress(progress);
46337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    }
4648872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
465a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
466a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware    private void setupNfcBeamPush() {
467a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware        NfcAdapter adapter = NfcAdapter.getDefaultAdapter(CameraActivity.this);
468a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware        if (adapter == null) {
469a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware            return;
470a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware        }
471a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware
472a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware        if (!ApiHelper.HAS_SET_BEAM_PUSH_URIS) {
473a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware            // Disable beaming
474a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware            adapter.setNdefPushMessage(null, CameraActivity.this);
475a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware            return;
476a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware        }
477a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware
478a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware        adapter.setBeamPushUris(null, CameraActivity.this);
479a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware        adapter.setBeamPushUrisCallback(new CreateBeamUrisCallback() {
480a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware            @Override
481a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware            public Uri[] createBeamUris(NfcEvent event) {
482a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware                return mNfcPushUris;
483a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware            }
484a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware        }, CameraActivity.this);
485a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware    }
486a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware
487a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware    private void setNfcBeamPushUri(Uri uri) {
488a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware        mNfcPushUris[0] = uri;
489a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware    }
490a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware
491cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private void setStandardShareIntent(Uri contentUri, String mimeType) {
49205804751ba07c8abcf422f57467d0ed3de95576cztenghui        mStandardShareIntent = getShareIntentFromType(mimeType);
49305804751ba07c8abcf422f57467d0ed3de95576cztenghui        if (mStandardShareIntent != null) {
49405804751ba07c8abcf422f57467d0ed3de95576cztenghui            mStandardShareIntent.putExtra(Intent.EXTRA_STREAM, contentUri);
49505804751ba07c8abcf422f57467d0ed3de95576cztenghui            mStandardShareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
49605804751ba07c8abcf422f57467d0ed3de95576cztenghui            if (mStandardShareActionProvider != null) {
49705804751ba07c8abcf422f57467d0ed3de95576cztenghui                mStandardShareActionProvider.setShareIntent(mStandardShareIntent);
49805804751ba07c8abcf422f57467d0ed3de95576cztenghui            }
499cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        }
50005804751ba07c8abcf422f57467d0ed3de95576cztenghui    }
50105804751ba07c8abcf422f57467d0ed3de95576cztenghui
50205804751ba07c8abcf422f57467d0ed3de95576cztenghui    /**
50305804751ba07c8abcf422f57467d0ed3de95576cztenghui     * Get the share intent according to the mimeType
50405804751ba07c8abcf422f57467d0ed3de95576cztenghui     *
50505804751ba07c8abcf422f57467d0ed3de95576cztenghui     * @param mimeType The mimeType of current data.
50605804751ba07c8abcf422f57467d0ed3de95576cztenghui     * @return the video/image's ShareIntent or null if mimeType is invalid.
50705804751ba07c8abcf422f57467d0ed3de95576cztenghui     */
50805804751ba07c8abcf422f57467d0ed3de95576cztenghui    private Intent getShareIntentFromType(String mimeType) {
50905804751ba07c8abcf422f57467d0ed3de95576cztenghui        // Lazily create the intent object.
51005804751ba07c8abcf422f57467d0ed3de95576cztenghui        if (mimeType.startsWith("video/")) {
51105804751ba07c8abcf422f57467d0ed3de95576cztenghui            if (mVideoShareIntent == null) {
51205804751ba07c8abcf422f57467d0ed3de95576cztenghui                mVideoShareIntent = new Intent(Intent.ACTION_SEND);
51305804751ba07c8abcf422f57467d0ed3de95576cztenghui                mVideoShareIntent.setType("video/*");
51405804751ba07c8abcf422f57467d0ed3de95576cztenghui            }
51505804751ba07c8abcf422f57467d0ed3de95576cztenghui            return mVideoShareIntent;
51605804751ba07c8abcf422f57467d0ed3de95576cztenghui        } else if (mimeType.startsWith("image/")) {
51705804751ba07c8abcf422f57467d0ed3de95576cztenghui            if (mImageShareIntent == null) {
51805804751ba07c8abcf422f57467d0ed3de95576cztenghui                mImageShareIntent = new Intent(Intent.ACTION_SEND);
51905804751ba07c8abcf422f57467d0ed3de95576cztenghui                mImageShareIntent.setType("image/*");
52005804751ba07c8abcf422f57467d0ed3de95576cztenghui            }
52105804751ba07c8abcf422f57467d0ed3de95576cztenghui            return mImageShareIntent;
522cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        }
52305804751ba07c8abcf422f57467d0ed3de95576cztenghui        Log.w(TAG, "unsupported mimeType " + mimeType);
52405804751ba07c8abcf422f57467d0ed3de95576cztenghui        return null;
525cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    }
526cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware
527cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private void setPanoramaShareIntent(Uri contentUri) {
528cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        if (mPanoramaShareIntent == null) {
529cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware            mPanoramaShareIntent = new Intent(Intent.ACTION_SEND);
530cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        }
531cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        mPanoramaShareIntent.setType("application/vnd.google.panorama360+jpg");
532cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        mPanoramaShareIntent.putExtra(Intent.EXTRA_STREAM, contentUri);
533cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        if (mPanoramaShareActionProvider != null) {
534cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware            mPanoramaShareActionProvider.setShareIntent(mPanoramaShareIntent);
535cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        }
536cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    }
537cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware
538aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu    @Override
539aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu    public void onMenuVisibilityChanged(boolean isVisible) {
540aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu        // If menu is showing, we need to make sure action bar does not go away.
541aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu        mMainHandler.removeMessages(HIDE_ACTION_BAR);
542aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu        if (!isVisible) {
543aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu            mMainHandler.sendEmptyMessageDelayed(HIDE_ACTION_BAR, SHOW_ACTION_BAR_TIMEOUT_MS);
544aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu        }
545aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu    }
546aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu
5470353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    /**
5480353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui     * According to the data type, make the menu items for supported operations
5490353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui     * visible.
550a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     *
551fae11a165e344a38811770c7d348eda214683edcSascha Haeberling     * @param dataID the data ID of the current item.
5520353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui     */
553fae11a165e344a38811770c7d348eda214683edcSascha Haeberling    private void updateActionBarMenu(int dataID) {
554fae11a165e344a38811770c7d348eda214683edcSascha Haeberling        LocalData currentData = mDataAdapter.getLocalData(dataID);
555d4f69ed6fa6e302955ce8d0b2a21f47794ce7d64Erin Dahlgren        if (currentData == null) {
556d4f69ed6fa6e302955ce8d0b2a21f47794ce7d64Erin Dahlgren            return;
557d4f69ed6fa6e302955ce8d0b2a21f47794ce7d64Erin Dahlgren        }
558fae11a165e344a38811770c7d348eda214683edcSascha Haeberling        int type = currentData.getLocalDataType();
559fae11a165e344a38811770c7d348eda214683edcSascha Haeberling
5600353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        if (mActionBarMenu == null) {
5610353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            return;
5620353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        }
5630353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui
5640353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        int supported = 0;
5650353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        switch (type) {
5660353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case LocalData.LOCAL_IMAGE:
5670353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                supported |= SUPPORT_DELETE | SUPPORT_ROTATE | SUPPORT_INFO
5680353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                        | SUPPORT_CROP | SUPPORT_SETAS | SUPPORT_EDIT
569cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                        | SUPPORT_SHARE | SUPPORT_SHOW_ON_MAP;
5700353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                break;
5710353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case LocalData.LOCAL_VIDEO:
572cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                supported |= SUPPORT_DELETE | SUPPORT_INFO | SUPPORT_TRIM
573cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                        | SUPPORT_SHARE;
5740353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                break;
5750353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case LocalData.LOCAL_PHOTO_SPHERE:
5760353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                supported |= SUPPORT_DELETE | SUPPORT_ROTATE | SUPPORT_INFO
5770353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                        | SUPPORT_CROP | SUPPORT_SETAS | SUPPORT_EDIT
578cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                        | SUPPORT_SHARE | SUPPORT_SHOW_ON_MAP;
579cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                break;
580cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware            case LocalData.LOCAL_360_PHOTO_SPHERE:
581cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                supported |= SUPPORT_DELETE | SUPPORT_ROTATE | SUPPORT_INFO
582cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                        | SUPPORT_CROP | SUPPORT_SETAS | SUPPORT_EDIT
583cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                        | SUPPORT_SHARE | SUPPORT_SHARE_PANORAMA360
5840353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                        | SUPPORT_SHOW_ON_MAP;
5850353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                break;
5860353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            default:
5870353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                break;
5880353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        }
5890353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui
5900353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        setMenuItemVisible(mActionBarMenu, R.id.action_delete,
5910353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                (supported & SUPPORT_DELETE) != 0);
5920353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        setMenuItemVisible(mActionBarMenu, R.id.action_rotate_ccw,
5930353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                (supported & SUPPORT_ROTATE) != 0);
5940353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        setMenuItemVisible(mActionBarMenu, R.id.action_rotate_cw,
5950353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                (supported & SUPPORT_ROTATE) != 0);
596cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        setMenuItemVisible(mActionBarMenu, R.id.action_details,
597cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                (supported & SUPPORT_INFO) != 0);
5980353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        setMenuItemVisible(mActionBarMenu, R.id.action_crop,
5990353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                (supported & SUPPORT_CROP) != 0);
6000353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        setMenuItemVisible(mActionBarMenu, R.id.action_setas,
6010353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                (supported & SUPPORT_SETAS) != 0);
6020353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        setMenuItemVisible(mActionBarMenu, R.id.action_edit,
6030353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                (supported & SUPPORT_EDIT) != 0);
604cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        setMenuItemVisible(mActionBarMenu, R.id.action_trim,
605cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                (supported & SUPPORT_TRIM) != 0);
606cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware
60733035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        boolean standardShare = (supported & SUPPORT_SHARE) != 0;
60833035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        boolean panoramaShare = (supported & SUPPORT_SHARE_PANORAMA360) != 0;
60933035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        setMenuItemVisible(mActionBarMenu, R.id.action_share, standardShare);
61033035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        setMenuItemVisible(mActionBarMenu, R.id.action_share_panorama, panoramaShare);
61133035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware
61233035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        if (panoramaShare) {
61333035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            // For 360 PhotoSphere, relegate standard share to the overflow menu
61433035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            MenuItem item = mActionBarMenu.findItem(R.id.action_share);
61533035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            if (item != null) {
61633035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                item.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
61733035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                item.setTitle(getResources().getString(R.string.share_as_photo));
61833035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            }
61933035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            // And, promote "share as panorama" to action bar
62033035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            item = mActionBarMenu.findItem(R.id.action_share_panorama);
62133035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            if (item != null) {
62233035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
62333035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            }
624cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware            setPanoramaShareIntent(currentData.getContentUri());
625cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        }
62633035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        if (standardShare) {
62733035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            if (!panoramaShare) {
62833035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                MenuItem item = mActionBarMenu.findItem(R.id.action_share);
62933035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                if (item != null) {
63033035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                    item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
63133035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                    item.setTitle(getResources().getString(R.string.share));
63233035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                }
63333035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            }
63433035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            setStandardShareIntent(currentData.getContentUri(), currentData.getMimeType());
635a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware            setNfcBeamPushUri(currentData.getContentUri());
63633035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        }
637fae11a165e344a38811770c7d348eda214683edcSascha Haeberling
638fae11a165e344a38811770c7d348eda214683edcSascha Haeberling        boolean itemHasLocation = currentData.getLatLong() != null;
639fae11a165e344a38811770c7d348eda214683edcSascha Haeberling        setMenuItemVisible(mActionBarMenu, R.id.action_show_on_map,
640fae11a165e344a38811770c7d348eda214683edcSascha Haeberling                itemHasLocation && (supported & SUPPORT_SHOW_ON_MAP) != 0);
6410353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    }
6420353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui
6430353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private void setMenuItemVisible(Menu menu, int itemId, boolean visible) {
6440353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        MenuItem item = menu.findItem(itemId);
6450353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        if (item != null)
6460353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            item.setVisible(visible);
6470353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    }
6480353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui
6496798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong    private ImageTaskManager.TaskListener mStitchingListener =
6506798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong            new ImageTaskManager.TaskListener() {
6516798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong                @Override
65237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                public void onTaskQueued(String filePath, final Uri imageUri) {
65337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    mMainHandler.post(new Runnable() {
65437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        @Override
65537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        public void run() {
65637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            notifyNewMedia(imageUri);
65737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        }
65837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    });
6596798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong                }
6606798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong
6616798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong                @Override
66237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                public void onTaskDone(String filePath, final Uri imageUri) {
66337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    Log.v(TAG, "onTaskDone:" + filePath);
66437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    mMainHandler.post(new Runnable() {
66537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        @Override
66637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        public void run() {
66737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            int doneID = mDataAdapter.findDataByContentUri(imageUri);
66837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            int currentDataId = mFilmStripView.getCurrentId();
66937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling
67037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            if (currentDataId == doneID) {
67137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                                hidePanoStitchingProgress();
67237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                                updateStitchingProgress(0);
67337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            }
67437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling
67537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            mDataAdapter.refresh(getContentResolver(), imageUri);
67637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        }
67737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    });
6786798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong                }
6796798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong
6806798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong                @Override
6816798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong                public void onTaskProgress(
68237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        String filePath, final Uri imageUri, final int progress) {
68337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    mMainHandler.post(new Runnable() {
68437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        @Override
68537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        public void run() {
68637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            int currentDataId = mFilmStripView.getCurrentId();
68737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            if (currentDataId == -1) {
68837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                                return;
68937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            }
69037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            if (imageUri.equals(
69137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                                    mDataAdapter.getLocalData(currentDataId).getContentUri())) {
69237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                                updateStitchingProgress(progress);
69337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            }
69437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        }
69537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    });
6966798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong                }
6976798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong            };
6986798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong
6996432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public MediaSaveService getMediaSaveService() {
7006432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return mMediaSaveService;
7018872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
7028872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
7036432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void notifyNewMedia(Uri uri) {
7046432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        ContentResolver cr = getContentResolver();
7056432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        String mimeType = cr.getType(uri);
7066432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (mimeType.startsWith("video/")) {
707b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong            sendBroadcast(new Intent(CameraUtil.ACTION_NEW_VIDEO, uri));
7086432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mDataAdapter.addNewVideo(cr, uri);
7096432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else if (mimeType.startsWith("image/")) {
710b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong            CameraUtil.broadcastNewPicture(this, uri);
7116432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mDataAdapter.addNewPhoto(cr, uri);
71237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        } else if (mimeType.startsWith("application/stitching-preview")) {
71337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            mDataAdapter.addNewPhoto(cr, uri);
7146432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else {
7156432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            android.util.Log.w(TAG, "Unknown new media with MIME type:"
7166432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                    + mimeType + ", uri:" + uri);
7176432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
7188872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
7198872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
7206432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private void removeData(int dataID) {
7216432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mDataAdapter.removeData(CameraActivity.this, dataID);
722d4f69ed6fa6e302955ce8d0b2a21f47794ce7d64Erin Dahlgren        updateActionBarMenu(mFilmStripView.getCurrentId());
723742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        if (mDataAdapter.getTotalNumber() > 1) {
724742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            showUndoDeletionBar();
725742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        } else {
726742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // If camera preview is the only view left in filmstrip,
727742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // no need to show undo bar.
728f2c14330a49abb55f75bfae6b3bae67a0dad115bDoris Liu            mPendingDeletion = true;
729742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            performDeletion();
730742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        }
7318872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
7328872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
7336432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private void bindMediaSaveService() {
7346432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        Intent intent = new Intent(this, MediaSaveService.class);
7356432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
7368872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
7378872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
7386432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private void unbindMediaSaveService() {
7396432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (mConnection != null) {
7406432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            unbindService(mConnection);
7416432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
7428872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
7438872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
7446432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    @Override
7450353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    public boolean onCreateOptionsMenu(Menu menu) {
7460353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        // Inflate the menu items for use in the action bar
7470353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        MenuInflater inflater = getMenuInflater();
7480353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        inflater.inflate(R.menu.operations, menu);
7490353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        mActionBarMenu = menu;
750cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware
751cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        // Configure the standard share action provider
752cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        MenuItem item = menu.findItem(R.id.action_share);
753cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        mStandardShareActionProvider = (ShareActionProvider) item.getActionProvider();
75433035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        mStandardShareActionProvider.setShareHistoryFileName("standard_share_history.xml");
755cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        if (mStandardShareIntent != null) {
756cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware            mStandardShareActionProvider.setShareIntent(mStandardShareIntent);
757cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        }
758cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware
759cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        // Configure the panorama share action provider
760cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        item = menu.findItem(R.id.action_share_panorama);
761cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        mPanoramaShareActionProvider = (ShareActionProvider) item.getActionProvider();
76233035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        mPanoramaShareActionProvider.setShareHistoryFileName("panorama_share_history.xml");
763cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        if (mPanoramaShareIntent != null) {
764cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware            mPanoramaShareActionProvider.setShareIntent(mPanoramaShareIntent);
765cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        }
766cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware
7670353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        return super.onCreateOptionsMenu(menu);
7680353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    }
7690353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui
7700353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    @Override
7710353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    public boolean onOptionsItemSelected(MenuItem item) {
7726f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling        int currentDataId = mFilmStripView.getCurrentId();
7736f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling        if (currentDataId < 0) {
7746f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling            return false;
7756f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling        }
7766f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling        final LocalData localData = mDataAdapter.getLocalData(currentDataId);
7776f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling
7780353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        // Handle presses on the action bar items
7790353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        switch (item.getItemId()) {
7803f969c1735e2636bf22dfe44104d0e99924cca97Alan Newberger            case android.R.id.home:
7813f969c1735e2636bf22dfe44104d0e99924cca97Alan Newberger                // ActionBar's Up/Home button was clicked
782690dc4722d068a1838b16dc0eabe9c7d518d524cAngus Kong                if (!CameraUtil.launchGallery(CameraActivity.this)) {
7835df64b0a818d4f85cb14602db725f05b0055c1d9Mangesh Ghiware                    mFilmStripView.getController().goToFirstItem();
7845df64b0a818d4f85cb14602db725f05b0055c1d9Mangesh Ghiware                }
7853f969c1735e2636bf22dfe44104d0e99924cca97Alan Newberger                return true;
7860353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case R.id.action_delete:
787e857cc90a98e280e2008beb03e2446bd642d2ec4Angus Kong                removeData(currentDataId);
7880353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
7890353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case R.id.action_edit:
79088ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling                launchEditor(localData);
7910353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
7920819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard            case R.id.action_trim: {
7936b9203214d828d72758943aca55adceab684a862ztenghui                // This is going to be handled by the Gallery app.
7946b9203214d828d72758943aca55adceab684a862ztenghui                Intent intent = new Intent(ACTION_TRIM_VIDEO);
7956b9203214d828d72758943aca55adceab684a862ztenghui                LocalData currentData = mDataAdapter.getLocalData(
7966b9203214d828d72758943aca55adceab684a862ztenghui                        mFilmStripView.getCurrentId());
7976b9203214d828d72758943aca55adceab684a862ztenghui                intent.setData(currentData.getContentUri());
7986b9203214d828d72758943aca55adceab684a862ztenghui                // We need the file path to wrap this into a RandomAccessFile.
7996b9203214d828d72758943aca55adceab684a862ztenghui                intent.putExtra(MEDIA_ITEM_PATH, currentData.getPath());
800b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                startActivityForResult(intent, REQ_CODE_DONT_SWITCH_TO_PREVIEW);
8010353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
8020819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard            }
8030353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case R.id.action_rotate_ccw:
804a16e7b50f3148f581439509279f242092e254309ztenghui                localData.rotate90Degrees(this, mDataAdapter, currentDataId, false);
8050353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
8060353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case R.id.action_rotate_cw:
807a16e7b50f3148f581439509279f242092e254309ztenghui                localData.rotate90Degrees(this, mDataAdapter, currentDataId, true);
8080353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
80919ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard            case R.id.action_crop: {
81019ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard                Intent intent = new Intent(CropActivity.CROP_ACTION);
81119ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard                intent.setClass(this, CropActivity.class);
81219ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard                intent.setDataAndType(localData.getContentUri(), localData.getMimeType())
81319ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard                        .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
81419ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard                startActivityForResult(intent, REQ_CODE_DONT_SWITCH_TO_PREVIEW);
8150353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
81619ab725a5e640a1a20b1a6def083e37d1d1c1e20nicolasroard            }
8170819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard            case R.id.action_setas: {
8180819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard                Intent intent = new Intent(Intent.ACTION_ATTACH_DATA)
8190819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard                        .setDataAndType(localData.getContentUri(),
8200819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard                                localData.getMimeType())
8210819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard                        .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
8220819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard                intent.putExtra("mimeType", intent.getType());
823b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                startActivityForResult(Intent.createChooser(
824b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                        intent, getString(R.string.set_as)), REQ_CODE_DONT_SWITCH_TO_PREVIEW);
8250353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
8260819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard            }
8270353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case R.id.action_details:
8286f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                (new AsyncTask<Void, Void, MediaDetails>() {
8296f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                    @Override
8306f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                    protected MediaDetails doInBackground(Void... params) {
8316f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                        return localData.getMediaDetails(CameraActivity.this);
8326f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                    }
8336f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling
8346f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                    @Override
8356f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                    protected void onPostExecute(MediaDetails mediaDetails) {
8366f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                        DetailsDialog.create(CameraActivity.this, mediaDetails).show();
8376f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                    }
8386f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                }).execute();
8390353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
8400353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case R.id.action_show_on_map:
841fae11a165e344a38811770c7d348eda214683edcSascha Haeberling                double[] latLong = localData.getLatLong();
842fae11a165e344a38811770c7d348eda214683edcSascha Haeberling                if (latLong != null) {
843a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                    CameraUtil.showOnMap(this, latLong);
844fae11a165e344a38811770c7d348eda214683edcSascha Haeberling                }
8450353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
8460353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            default:
8470353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return super.onOptionsItemSelected(item);
8480353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        }
8490353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    }
8500353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui
851fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui    private boolean isCaptureIntent() {
852fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui        if (MediaStore.ACTION_VIDEO_CAPTURE.equals(getIntent().getAction())
853fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui                || MediaStore.ACTION_IMAGE_CAPTURE.equals(getIntent().getAction())
854fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui                || MediaStore.ACTION_IMAGE_CAPTURE_SECURE.equals(getIntent().getAction())) {
855fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui            return true;
856fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui        } else {
857fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui            return false;
858fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui        }
859fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui    }
860fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui
8610353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    @Override
8626432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void onCreate(Bundle state) {
8636432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        super.onCreate(state);
86450df47071c776703a36dbc4cb90ec8d1df3c0f6eztenghui        getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
8656432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        setContentView(R.layout.camera_filmstrip);
866fa9e2cc9ccbcd746f5765cb7a0afebcdb60e2973ztenghui        mActionBar = getActionBar();
867aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu        mActionBar.addOnMenuVisibilityListener(this);
868fa9e2cc9ccbcd746f5765cb7a0afebcdb60e2973ztenghui
8696432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (ApiHelper.HAS_ROTATION_ANIMATION) {
8706432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            setRotationAnimation();
8716432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
872aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu
873aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu        mMainHandler = new MainHandler(getMainLooper());
8746432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        // Check if this is in the secure camera mode.
8756432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        Intent intent = getIntent();
8766432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        String action = intent.getAction();
877b84b9738c855a525dc1944165983cc3c342ce446Doris Liu        if (INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE.equals(action)
878b84b9738c855a525dc1944165983cc3c342ce446Doris Liu                || ACTION_IMAGE_CAPTURE_SECURE.equals(action)) {
8796432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mSecureCamera = true;
8806432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else {
8816432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mSecureCamera = intent.getBooleanExtra(SECURE_CAMERA_EXTRA, false);
8828872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
883b84b9738c855a525dc1944165983cc3c342ce446Doris Liu
884b84b9738c855a525dc1944165983cc3c342ce446Doris Liu        if (mSecureCamera) {
885b84b9738c855a525dc1944165983cc3c342ce446Doris Liu            // Change the window flags so that secure camera can show when locked
886b84b9738c855a525dc1944165983cc3c342ce446Doris Liu            Window win = getWindow();
887b84b9738c855a525dc1944165983cc3c342ce446Doris Liu            WindowManager.LayoutParams params = win.getAttributes();
888b84b9738c855a525dc1944165983cc3c342ce446Doris Liu            params.flags |= WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
889b84b9738c855a525dc1944165983cc3c342ce446Doris Liu            win.setAttributes(params);
890b84b9738c855a525dc1944165983cc3c342ce446Doris Liu
891b84b9738c855a525dc1944165983cc3c342ce446Doris Liu            // Filter for screen off so that we can finish secure camera activity
892b84b9738c855a525dc1944165983cc3c342ce446Doris Liu            // when screen is off.
8936432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
8946432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            registerReceiver(mScreenOffReceiver, filter);
8956a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong            // TODO: This static screen off event receiver is a workaround to the
8966a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong            // double onResume() invocation (onResume->onPause->onResume). We should
8976a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong            // find a better solution to this.
8986a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong            if (sScreenOffReceiver == null) {
8996a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong                sScreenOffReceiver = new ScreenOffReceiver();
9006a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong                registerReceiver(sScreenOffReceiver, filter);
9016a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong            }
902b84b9738c855a525dc1944165983cc3c342ce446Doris Liu        }
903653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        mAboveFilmstripControlLayout =
904653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong                (FrameLayout) findViewById(R.id.camera_above_filmstrip_layout);
905653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        mAboveFilmstripControlLayout.setFitsSystemWindows(true);
9065199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling        // Hide action bar first since we are in full screen mode first, and
9075199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling        // switch the system UI to lights-out mode.
908aa8744284864cda5570e8dfa4eccc2747cee52dcDoris Liu        this.setSystemBarsVisibility(false);
909ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mPanoramaManager = AppManagerFactory.getInstance(this)
910ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                .getPanoramaStitchingManager();
9116798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong        mPanoramaManager.addTaskListener(mStitchingListener);
9126432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        LayoutInflater inflater = getLayoutInflater();
9136432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        View rootLayout = inflater.inflate(R.layout.camera, null, false);
914653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        mCameraModuleRootView = rootLayout.findViewById(R.id.camera_app_root);
915fa9e2cc9ccbcd746f5765cb7a0afebcdb60e2973ztenghui        mPanoStitchingPanel = findViewById(R.id.pano_stitching_progress_panel);
91637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        mBottomProgress = (ProgressBar) findViewById(R.id.pano_stitching_progress_bar);
9178e5e4eedb25a4589342660b928935acca4375fc7Angus Kong        mCameraPreviewData = new CameraPreviewData(rootLayout,
9188e5e4eedb25a4589342660b928935acca4375fc7Angus Kong                FilmStripView.ImageData.SIZE_FULL,
9198e5e4eedb25a4589342660b928935acca4375fc7Angus Kong                FilmStripView.ImageData.SIZE_FULL);
92037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        // Put a CameraPreviewData at the first position.
9218e5e4eedb25a4589342660b928935acca4375fc7Angus Kong        mWrappedDataAdapter = new FixedFirstDataAdapter(
9228e5e4eedb25a4589342660b928935acca4375fc7Angus Kong                new CameraDataAdapter(new ColorDrawable(
9238e5e4eedb25a4589342660b928935acca4375fc7Angus Kong                        getResources().getColor(R.color.photo_placeholder))),
9248e5e4eedb25a4589342660b928935acca4375fc7Angus Kong                mCameraPreviewData);
9256432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mFilmStripView = (FilmStripView) findViewById(R.id.filmstrip_view);
9266432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mFilmStripView.setViewGap(
9276432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                getResources().getDimensionPixelSize(R.dimen.camera_film_strip_gap));
928f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling        mPanoramaViewHelper = new PanoramaViewHelper(this);
929f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling        mPanoramaViewHelper.onCreate();
930f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling        mFilmStripView.setPanoramaViewHelper(mPanoramaViewHelper);
9316432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        // Set up the camera preview first so the preview shows up ASAP.
9326432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mFilmStripView.setListener(mFilmStripListener);
9332654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling
9342654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        int moduleIndex = -1;
9352a7f44cac888de5683d05bef5708f846ee950f43Doris Liu        if (MediaStore.INTENT_ACTION_VIDEO_CAMERA.equals(getIntent().getAction())
9362a7f44cac888de5683d05bef5708f846ee950f43Doris Liu                || MediaStore.ACTION_VIDEO_CAPTURE.equals(getIntent().getAction())) {
937ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            moduleIndex = ModuleSwitcher.VIDEO_MODULE_INDEX;
9382654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        } else if (MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA.equals(getIntent().getAction())
9392654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling                || MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE.equals(getIntent()
9402654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling                        .getAction())
9412654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling                || MediaStore.ACTION_IMAGE_CAPTURE.equals(getIntent().getAction())
9422654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling                || MediaStore.ACTION_IMAGE_CAPTURE_SECURE.equals(getIntent().getAction())) {
943ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            moduleIndex = ModuleSwitcher.PHOTO_MODULE_INDEX;
9442a7f44cac888de5683d05bef5708f846ee950f43Doris Liu        } else {
9452654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling            // If the activity has not been started using an explicit intent,
9462654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling            // read the module index from the last time the user changed modes
9472654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
9482654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling            moduleIndex = prefs.getInt(PREF_STARTUP_MODULE_INDEX, -1);
949a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunk            if ((moduleIndex == ModuleSwitcher.GCAM_MODULE_INDEX &&
95098f38bb04daa3db49a072718cd8b5005b8b73af1Sascha Haeberling                    !GcamHelper.hasGcamCapture()) || moduleIndex < 0) {
951ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                moduleIndex = ModuleSwitcher.PHOTO_MODULE_INDEX;
9522654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling            }
9532a7f44cac888de5683d05bef5708f846ee950f43Doris Liu        }
9542654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling
9556432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mOrientationListener = new MyOrientationEventListener(this);
956ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        setModuleFromIndex(moduleIndex);
957ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mCurrentModule.init(this, mCameraModuleRootView);
95837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling
95937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        if (!mSecureCamera) {
96037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            mDataAdapter = mWrappedDataAdapter;
961dcccc510652b835fdbd39310a07849af8203052aAngus Kong            mFilmStripView.setDataAdapter(mDataAdapter);
962a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong            if (!isCaptureIntent()) {
963a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong                mDataAdapter.requestLoad(getContentResolver());
964a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong            }
96537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        } else {
966a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            // Put a lock placeholder as the last image by setting its date to
967a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            // 0.
96837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            ImageView v = (ImageView) getLayoutInflater().inflate(
96937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    R.layout.secure_album_placeholder, null);
970690dc4722d068a1838b16dc0eabe9c7d518d524cAngus Kong            v.setOnClickListener(new View.OnClickListener() {
971690dc4722d068a1838b16dc0eabe9c7d518d524cAngus Kong                @Override
972690dc4722d068a1838b16dc0eabe9c7d518d524cAngus Kong                public void onClick(View view) {
973690dc4722d068a1838b16dc0eabe9c7d518d524cAngus Kong                    CameraUtil.launchGallery(CameraActivity.this);
974690dc4722d068a1838b16dc0eabe9c7d518d524cAngus Kong                    finish();
975690dc4722d068a1838b16dc0eabe9c7d518d524cAngus Kong                }
976690dc4722d068a1838b16dc0eabe9c7d518d524cAngus Kong            });
97737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            mDataAdapter = new FixedLastDataAdapter(
97837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    mWrappedDataAdapter,
979bd26069d391830856c57c2141cd2efbc8423d871Angus Kong                    new SimpleViewData(
98037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            v,
98137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            v.getDrawable().getIntrinsicWidth(),
98237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            v.getDrawable().getIntrinsicHeight(),
98337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            0, 0));
98437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            // Flush out all the original data.
98537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            mDataAdapter.flush();
986dcccc510652b835fdbd39310a07849af8203052aAngus Kong            mFilmStripView.setDataAdapter(mDataAdapter);
98737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        }
988a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware
989a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware        setupNfcBeamPush();
990064d6000933354f7bf344a41e0caa7052401c903ztenghui
9912b86d873ca4fb3a921139633ed7be9959ab452dfDoris Liu        mLocalImagesObserver = new LocalMediaObserver();
9922b86d873ca4fb3a921139633ed7be9959ab452dfDoris Liu        mLocalVideosObserver = new LocalMediaObserver();
993064d6000933354f7bf344a41e0caa7052401c903ztenghui
994064d6000933354f7bf344a41e0caa7052401c903ztenghui        getContentResolver().registerContentObserver(
995064d6000933354f7bf344a41e0caa7052401c903ztenghui                MediaStore.Images.Media.EXTERNAL_CONTENT_URI, true,
996064d6000933354f7bf344a41e0caa7052401c903ztenghui                mLocalImagesObserver);
997064d6000933354f7bf344a41e0caa7052401c903ztenghui        getContentResolver().registerContentObserver(
998064d6000933354f7bf344a41e0caa7052401c903ztenghui                MediaStore.Video.Media.EXTERNAL_CONTENT_URI, true,
999064d6000933354f7bf344a41e0caa7052401c903ztenghui                mLocalVideosObserver);
10008872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10018872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10026432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private void setRotationAnimation() {
10036432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        int rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE;
10046432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE;
10056432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        Window win = getWindow();
10066432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        WindowManager.LayoutParams winParams = win.getAttributes();
10076432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        winParams.rotationAnimation = rotationAnimation;
10086432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        win.setAttributes(winParams);
10098872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10108872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10118872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
10126432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void onUserInteraction() {
10136432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        super.onUserInteraction();
10146432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mCurrentModule.onUserInteraction();
101509106a41ee6acc6b20553662cb9b730702a8f08aDoris Liu    }
10168872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10178872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
1018742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    public boolean dispatchTouchEvent(MotionEvent ev) {
1019742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        boolean result = super.dispatchTouchEvent(ev);
1020742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
1021742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // Real deletion is postponed until the next user interaction after
1022742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // the gesture that triggers deletion. Until real deletion is performed,
1023742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // users can click the undo button to bring back the image that they
1024742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // chose to delete.
1025742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            if (mPendingDeletion && !mIsUndoingDeletion) {
1026742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                 performDeletion();
1027742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            }
1028742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        }
1029742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        return result;
1030742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    }
1031742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu
1032742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    @Override
10338872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void onPause() {
1034f2c14330a49abb55f75bfae6b3bae67a0dad115bDoris Liu        // Delete photos that are pending deletion
1035f2c14330a49abb55f75bfae6b3bae67a0dad115bDoris Liu        performDeletion();
10368872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mOrientationListener.disable();
10378872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mCurrentModule.onPauseBeforeSuper();
10388872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        super.onPause();
10398872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mCurrentModule.onPauseAfterSuper();
10402b86d873ca4fb3a921139633ed7be9959ab452dfDoris Liu
10412b86d873ca4fb3a921139633ed7be9959ab452dfDoris Liu        mLocalImagesObserver.setActivityPaused(true);
10422b86d873ca4fb3a921139633ed7be9959ab452dfDoris Liu        mLocalVideosObserver.setActivityPaused(true);
10438872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10448872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10458872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
1046b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
1047064d6000933354f7bf344a41e0caa7052401c903ztenghui        if (requestCode == REQ_CODE_DONT_SWITCH_TO_PREVIEW) {
1048b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling            mResetToPreviewOnResume = false;
1049b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        } else {
1050b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling            super.onActivityResult(requestCode, resultCode, data);
1051b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        }
1052b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    }
1053b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling
1054b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    @Override
10558872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void onResume() {
1056ce2b94917098f211cacaaebaa0f6b40021d3e3faAngus Kong        // TODO: Handle this in OrientationManager.
1057a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        // Auto-rotate off
10583cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu        if (Settings.System.getInt(getContentResolver(),
1059a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                Settings.System.ACCELEROMETER_ROTATION, 0) == 0) {
10603cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
10613cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu            mAutoRotateScreen = false;
10623cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu        } else {
10633cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
10643cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu            mAutoRotateScreen = true;
10653cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu        }
10668872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mOrientationListener.enable();
10678872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mCurrentModule.onResumeBeforeSuper();
10688872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        super.onResume();
10698872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mCurrentModule.onResumeAfterSuper();
10708872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10716798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong        setSwipingEnabled(true);
1072b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling
1073b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        if (mResetToPreviewOnResume) {
1074b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling            // Go to the preview on resume.
1075b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling            mFilmStripView.getController().goToFirstItem();
1076b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        }
1077b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        // Default is showing the preview, unless disabled by explicitly
1078b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        // starting an activity we want to return from to the filmstrip rather
1079b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        // than the preview.
1080b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        mResetToPreviewOnResume = true;
1081064d6000933354f7bf344a41e0caa7052401c903ztenghui
10822b86d873ca4fb3a921139633ed7be9959ab452dfDoris Liu        if (mLocalVideosObserver.isMediaDataChangedDuringPause()
10832b86d873ca4fb3a921139633ed7be9959ab452dfDoris Liu                || mLocalImagesObserver.isMediaDataChangedDuringPause()) {
1084064d6000933354f7bf344a41e0caa7052401c903ztenghui            mDataAdapter.requestLoad(getContentResolver());
1085064d6000933354f7bf344a41e0caa7052401c903ztenghui        }
10862b86d873ca4fb3a921139633ed7be9959ab452dfDoris Liu        mLocalImagesObserver.setActivityPaused(false);
10872b86d873ca4fb3a921139633ed7be9959ab452dfDoris Liu        mLocalVideosObserver.setActivityPaused(false);
10886798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong    }
10896798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong
10906798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong    @Override
10916798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong    public void onStart() {
10926798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong        super.onStart();
10937e374eb0a450ed2689b556ab42a0a88c8f74df2eAngus Kong        bindMediaSaveService();
1094f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling        mPanoramaViewHelper.onStart();
1095f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling    }
1096f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling
1097f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling    @Override
1098f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling    protected void onStop() {
1099f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling        super.onStop();
1100f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling        mPanoramaViewHelper.onStop();
11017e374eb0a450ed2689b556ab42a0a88c8f74df2eAngus Kong        unbindMediaSaveService();
110208650187c1f1a2d1ef7f754be0f479a29958daaaMichael Kolb    }
110308650187c1f1a2d1ef7f754be0f479a29958daaaMichael Kolb
11048872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
11056432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void onDestroy() {
1106a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        if (mSecureCamera) {
1107a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            unregisterReceiver(mScreenOffReceiver);
1108a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        }
1109064d6000933354f7bf344a41e0caa7052401c903ztenghui        getContentResolver().unregisterContentObserver(mLocalImagesObserver);
1110064d6000933354f7bf344a41e0caa7052401c903ztenghui        getContentResolver().unregisterContentObserver(mLocalVideosObserver);
1111064d6000933354f7bf344a41e0caa7052401c903ztenghui
11126432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        super.onDestroy();
11138872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
11148872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
11158872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
11166432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void onConfigurationChanged(Configuration config) {
11176432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        super.onConfigurationChanged(config);
11186432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mCurrentModule.onConfigurationChanged(config);
11198872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
11208872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
11218872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
11226432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public boolean onKeyDown(int keyCode, KeyEvent event) {
1123a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        if (mCurrentModule.onKeyDown(keyCode, event)) {
1124a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            return true;
1125a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        }
11266432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        // Prevent software keyboard or voice search from showing up.
11276432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (keyCode == KeyEvent.KEYCODE_SEARCH
11286432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                || keyCode == KeyEvent.KEYCODE_MENU) {
1129a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            if (event.isLongPress()) {
1130a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                return true;
1131a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            }
11326432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
11336432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
11346432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return super.onKeyDown(keyCode, event);
11358872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
11368872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
11378872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
11386432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public boolean onKeyUp(int keyCode, KeyEvent event) {
1139a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        if (mCurrentModule.onKeyUp(keyCode, event)) {
1140a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            return true;
1141a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        }
11426432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return super.onKeyUp(keyCode, event);
11438872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
11448872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
11455f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger    @Override
11465f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger    public void onBackPressed() {
11475f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger        if (!mFilmStripView.inCameraFullscreen()) {
11485f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger            mFilmStripView.getController().goToFirstItem();
11495f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger        } else if (!mCurrentModule.onBackPressed()) {
11505f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger            super.onBackPressed();
11515f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger        }
11525f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger    }
11535f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger
11546432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public boolean isAutoRotateScreen() {
11556432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return mAutoRotateScreen;
11568872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
11578872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
11586432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    protected void updateStorageSpace() {
11592dcc0a9dfcc23f090bbe36308f92d72f68c4f0a2Angus Kong        mStorageSpaceBytes = Storage.getAvailableSpace();
11608872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
11618872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
11622dcc0a9dfcc23f090bbe36308f92d72f68c4f0a2Angus Kong    protected long getStorageSpaceBytes() {
11632dcc0a9dfcc23f090bbe36308f92d72f68c4f0a2Angus Kong        return mStorageSpaceBytes;
11648872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
11658872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
11666432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    protected void updateStorageSpaceAndHint() {
11676432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        updateStorageSpace();
11682dcc0a9dfcc23f090bbe36308f92d72f68c4f0a2Angus Kong        updateStorageHint(mStorageSpaceBytes);
11696432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
11706432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
11716432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    protected void updateStorageHint(long storageSpace) {
11726432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        String message = null;
11736432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (storageSpace == Storage.UNAVAILABLE) {
11746432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            message = getString(R.string.no_storage);
11756432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else if (storageSpace == Storage.PREPARING) {
11766432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            message = getString(R.string.preparing_sd);
11776432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else if (storageSpace == Storage.UNKNOWN_SIZE) {
11786432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            message = getString(R.string.access_sd_fail);
11792dcc0a9dfcc23f090bbe36308f92d72f68c4f0a2Angus Kong        } else if (storageSpace <= Storage.LOW_STORAGE_THRESHOLD_BYTES) {
11806432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            message = getString(R.string.spaceIsLow_content);
11818872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
11826432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
11836432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (message != null) {
11846432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            if (mStorageHint == null) {
11856432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                mStorageHint = OnScreenHint.makeText(this, message);
11866432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            } else {
11876432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                mStorageHint.setText(message);
11886432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            }
11896432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mStorageHint.show();
11906432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else if (mStorageHint != null) {
11916432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mStorageHint.cancel();
11926432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mStorageHint = null;
11938872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
11948872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
11958872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
11966432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    protected void setResultEx(int resultCode) {
11976432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mResultCodeForTesting = resultCode;
11986432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        setResult(resultCode);
11998872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
12008872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
12016432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    protected void setResultEx(int resultCode, Intent data) {
12026432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mResultCodeForTesting = resultCode;
12036432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mResultDataForTesting = data;
12046432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        setResult(resultCode, data);
12058872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
12068872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
12076432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public int getResultCode() {
12086432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return mResultCodeForTesting;
12098872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
12108872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
12116432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public Intent getResultData() {
12126432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return mResultDataForTesting;
12138872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
12148872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
12156432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public boolean isSecureCamera() {
12166432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return mSecureCamera;
12178872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
12188872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
12198872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
1220ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void onModuleSelected(int moduleIndex) {
1221a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        if (mCurrentModuleIndex == moduleIndex) {
1222a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            return;
1223a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        }
12246432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
12256432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        CameraHolder.instance().keep();
12266432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        closeModule(mCurrentModule);
12272654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        setModuleFromIndex(moduleIndex);
12282654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling
12292654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        openModule(mCurrentModule);
12302654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        mCurrentModule.onOrientationChanged(mLastRawOrientation);
12312654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        if (mMediaSaveService != null) {
12322654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling            mCurrentModule.onMediaSaveServiceConnected(mMediaSaveService);
12332654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        }
12342654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling
12352654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        // Store the module index so we can use it the next time the Camera
12362654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        // starts up.
12372654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
12382654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        prefs.edit().putInt(PREF_STARTUP_MODULE_INDEX, moduleIndex).apply();
12392654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling    }
12402654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling
12412654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling    /**
1242a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     * Sets the mCurrentModuleIndex, creates a new module instance for the given
1243a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     * index an sets it as mCurrentModule.
12442654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling     */
12452654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling    private void setModuleFromIndex(int moduleIndex) {
12462654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        mCurrentModuleIndex = moduleIndex;
12472654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        switch (moduleIndex) {
124815125661ad968cf4d40989a9bc88d11189beb0b3Sascha Haeberling            case ModuleSwitcher.VIDEO_MODULE_INDEX:
12496432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                mCurrentModule = new VideoModule();
12506432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                break;
1251ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
125215125661ad968cf4d40989a9bc88d11189beb0b3Sascha Haeberling            case ModuleSwitcher.PHOTO_MODULE_INDEX:
12536432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                mCurrentModule = new PhotoModule();
12546432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                break;
1255ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
125615125661ad968cf4d40989a9bc88d11189beb0b3Sascha Haeberling            case ModuleSwitcher.WIDE_ANGLE_PANO_MODULE_INDEX:
1257ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                mCurrentModule = new WideAnglePanoramaModule();
1258ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                break;
1259ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
126015125661ad968cf4d40989a9bc88d11189beb0b3Sascha Haeberling            case ModuleSwitcher.LIGHTCYCLE_MODULE_INDEX:
12618e963a5a6016d246184ed65906f9d103e92b17e2Sascha Haeberling                mCurrentModule = PhotoSphereHelper.createPanoramaModule();
12626432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                break;
1263a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunk            case ModuleSwitcher.GCAM_MODULE_INDEX:
1264a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunk                // Force immediate release of Camera instance
1265a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunk                CameraHolder.instance().strongRelease();
1266a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunk                mCurrentModule = GcamHelper.createGcamModule();
1267a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunk                break;
12682654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling            default:
126915125661ad968cf4d40989a9bc88d11189beb0b3Sascha Haeberling                // Fall back to photo mode.
127015125661ad968cf4d40989a9bc88d11189beb0b3Sascha Haeberling                mCurrentModule = new PhotoModule();
127115125661ad968cf4d40989a9bc88d11189beb0b3Sascha Haeberling                mCurrentModuleIndex = ModuleSwitcher.PHOTO_MODULE_INDEX;
12722654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling                break;
12736432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
12748872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
12758872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
127688ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling    /**
127788ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling     * Launches an ACTION_EDIT intent for the given local data item.
127888ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling     */
127988ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling    public void launchEditor(LocalData data) {
128088ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling        Intent intent = new Intent(Intent.ACTION_EDIT)
128188ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling                .setDataAndType(data.getContentUri(), data.getMimeType())
128288ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling                .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
1283064d6000933354f7bf344a41e0caa7052401c903ztenghui        startActivityForResult(Intent.createChooser(intent, null),
1284064d6000933354f7bf344a41e0caa7052401c903ztenghui                REQ_CODE_DONT_SWITCH_TO_PREVIEW);
128588ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling    }
128688ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling
1287a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling    /**
1288a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     * Launch the tiny planet editor.
1289a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     *
1290a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     * @param data the data must be a 360 degree stereographically mapped
1291a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     *            panoramic image. It will not be modified, instead a new item
1292a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     *            with the result will be added to the filmstrip.
1293a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     */
1294a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling    public void launchTinyPlanetEditor(LocalData data) {
1295a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        TinyPlanetFragment fragment = new TinyPlanetFragment();
1296a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        Bundle bundle = new Bundle();
1297a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        bundle.putString(TinyPlanetFragment.ARGUMENT_URI, data.getContentUri().toString());
1298a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        bundle.putString(TinyPlanetFragment.ARGUMENT_TITLE, data.getTitle());
1299a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        fragment.setArguments(bundle);
1300a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        fragment.show(getFragmentManager(), "tiny_planet");
1301a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling    }
1302a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling
13036432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private void openModule(CameraModule module) {
1304653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        module.init(this, mCameraModuleRootView);
13056432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        module.onResumeBeforeSuper();
13066432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        module.onResumeAfterSuper();
13078872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
13088872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
13096432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private void closeModule(CameraModule module) {
13106432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        module.onPauseBeforeSuper();
13116432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        module.onPauseAfterSuper();
1312653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        ((ViewGroup) mCameraModuleRootView).removeAllViews();
1313653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong    }
1314653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong
1315742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    private void performDeletion() {
1316742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        if (!mPendingDeletion) {
1317742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            return;
1318742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        }
1319742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        hideUndoDeletionBar(false);
1320742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        mDataAdapter.executeDeletion(CameraActivity.this);
1321742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    }
1322742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu
1323742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    public void showUndoDeletionBar() {
1324742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        if (mPendingDeletion) {
1325742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            performDeletion();
1326742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        }
1327742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        Log.v(TAG, "showing undo bar");
1328742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        mPendingDeletion = true;
1329653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        if (mUndoDeletionBar == null) {
1330653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong            ViewGroup v = (ViewGroup) getLayoutInflater().inflate(
1331653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong                    R.layout.undo_bar, mAboveFilmstripControlLayout, true);
1332653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong            mUndoDeletionBar = (ViewGroup) v.findViewById(R.id.camera_undo_deletion_bar);
1333653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong            View button = mUndoDeletionBar.findViewById(R.id.camera_undo_deletion_button);
1334653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong            button.setOnClickListener(new View.OnClickListener() {
1335653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong                @Override
1336653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong                public void onClick(View view) {
1337653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong                    mDataAdapter.undoDataRemoval();
1338742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                    hideUndoDeletionBar(true);
1339742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                }
1340742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            });
1341742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // Setting undo bar clickable to avoid touch events going through
1342742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // the bar to the buttons (eg. edit button, etc) underneath the bar.
1343742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            mUndoDeletionBar.setClickable(true);
1344742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // When there is user interaction going on with the undo button, we
1345742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // do not want to hide the undo bar.
1346742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            button.setOnTouchListener(new View.OnTouchListener() {
1347742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                @Override
1348742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                public boolean onTouch(View v, MotionEvent event) {
1349742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                    if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
1350742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                        mIsUndoingDeletion = true;
1351742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                    } else if (event.getActionMasked() == MotionEvent.ACTION_UP) {
1352742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                        mIsUndoingDeletion =false;
1353742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                    }
1354742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                    return false;
1355653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong                }
1356653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong            });
1357653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        }
1358653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        mUndoDeletionBar.setAlpha(0f);
1359653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        mUndoDeletionBar.setVisibility(View.VISIBLE);
1360742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        mUndoDeletionBar.animate().setDuration(200).alpha(1f).setListener(null).start();
1361653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong    }
1362653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong
1363742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    private void hideUndoDeletionBar(boolean withAnimation) {
1364653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        Log.v(TAG, "Hiding undo deletion bar");
1365742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        mPendingDeletion = false;
1366653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        if (mUndoDeletionBar != null) {
1367742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            if (withAnimation) {
1368742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                mUndoDeletionBar.animate()
1369742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                        .setDuration(200)
1370742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                        .alpha(0f)
1371742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                        .setListener(new Animator.AnimatorListener() {
1372742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            @Override
1373742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            public void onAnimationStart(Animator animation) {
1374742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                                // Do nothing.
1375742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            }
1376742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu
1377742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            @Override
1378742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            public void onAnimationEnd(Animator animation) {
1379742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                                mUndoDeletionBar.setVisibility(View.GONE);
1380742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            }
1381742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu
1382742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            @Override
1383742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            public void onAnimationCancel(Animator animation) {
1384742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                                // Do nothing.
1385742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            }
1386742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu
1387742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            @Override
1388742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            public void onAnimationRepeat(Animator animation) {
1389742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                                // Do nothing.
1390742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            }
1391742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                        })
1392742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                        .start();
1393742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            } else {
1394742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                mUndoDeletionBar.setVisibility(View.GONE);
1395742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            }
1396653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        }
13978872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
13988872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
13998872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
14006432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void onShowSwitcherPopup() {
14016432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
14026432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
1403a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong    /**
1404a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     * Enable/disable swipe-to-filmstrip. Will always disable swipe if in
1405a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     * capture intent.
1406a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong     *
1407a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong     * @param enable {@code true} to enable swipe.
1408a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong     */
14096432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void setSwipingEnabled(boolean enable) {
1410a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong        if (isCaptureIntent()) {
1411a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong            mCameraPreviewData.lockPreview(true);
1412a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong        } else {
1413a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong            mCameraPreviewData.lockPreview(!enable);
1414a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong        }
14158872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
14168872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
14178872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    // Accessor methods for getting latency times used in performance testing
14188872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public long getAutoFocusTime() {
14198872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return (mCurrentModule instanceof PhotoModule) ?
14208872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                ((PhotoModule) mCurrentModule).mAutoFocusTime : -1;
14218872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
14228872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
14238872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public long getShutterLag() {
14248872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return (mCurrentModule instanceof PhotoModule) ?
14258872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                ((PhotoModule) mCurrentModule).mShutterLag : -1;
14268872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
14278872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
14288872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public long getShutterToPictureDisplayedTime() {
14298872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return (mCurrentModule instanceof PhotoModule) ?
14308872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                ((PhotoModule) mCurrentModule).mShutterToPictureDisplayedTime : -1;
14318872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
14328872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
14338872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public long getPictureDisplayedToJpegCallbackTime() {
14348872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return (mCurrentModule instanceof PhotoModule) ?
14358872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                ((PhotoModule) mCurrentModule).mPictureDisplayedToJpegCallbackTime : -1;
14368872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
14378872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
14388872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public long getJpegCallbackFinishTime() {
14398872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return (mCurrentModule instanceof PhotoModule) ?
14408872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                ((PhotoModule) mCurrentModule).mJpegCallbackFinishTime : -1;
14418872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
14428872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
14438872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public long getCaptureStartTime() {
14448872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return (mCurrentModule instanceof PhotoModule) ?
14458872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                ((PhotoModule) mCurrentModule).mCaptureStartTime : -1;
14468872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
14478872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
14488872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public boolean isRecording() {
14498872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return (mCurrentModule instanceof VideoModule) ?
14508872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                ((VideoModule) mCurrentModule).isRecording() : false;
14518872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
14524f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong
14534f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong    public CameraOpenErrorCallback getCameraOpenErrorCallback() {
14544f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong        return mCameraOpenErrorCallback;
14554f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong    }
14568872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb}
1457