CameraActivity.java revision a5682ab08e1d42fe272ec877929478b4adb769f5
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;
432654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberlingimport android.preference.PreferenceManager;
442a7f44cac888de5683d05bef5708f846ee950f43Doris Liuimport android.provider.MediaStore;
453cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liuimport android.provider.Settings;
4637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberlingimport android.util.Log;
478872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.view.KeyEvent;
486432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.view.LayoutInflater;
490353ca2e048543bd6e233b4c2110a1df1070cd3fztenghuiimport android.view.Menu;
500353ca2e048543bd6e233b4c2110a1df1070cd3fztenghuiimport android.view.MenuInflater;
510353ca2e048543bd6e233b4c2110a1df1070cd3fztenghuiimport android.view.MenuItem;
52742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liuimport android.view.MotionEvent;
538872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.view.OrientationEventListener;
548872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.view.View;
556432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.view.ViewGroup;
5608650187c1f1a2d1ef7f754be0f479a29958daaaMichael Kolbimport android.view.Window;
5708650187c1f1a2d1ef7f754be0f479a29958daaaMichael Kolbimport android.view.WindowManager;
58653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kongimport android.widget.FrameLayout;
596432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.widget.ImageView;
6037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberlingimport android.widget.ProgressBar;
61cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiwareimport android.widget.ShareActionProvider;
628872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
63ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport com.android.camera.app.AppManagerFactory;
64ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport com.android.camera.app.PanoramaStitchingManager;
656432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport com.android.camera.data.CameraDataAdapter;
668e5e4eedb25a4589342660b928935acca4375fc7Angus Kongimport com.android.camera.data.CameraPreviewData;
678e5e4eedb25a4589342660b928935acca4375fc7Angus Kongimport com.android.camera.data.FixedFirstDataAdapter;
688e5e4eedb25a4589342660b928935acca4375fc7Angus Kongimport com.android.camera.data.FixedLastDataAdapter;
696432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport com.android.camera.data.LocalData;
708e5e4eedb25a4589342660b928935acca4375fc7Angus Kongimport com.android.camera.data.LocalDataAdapter;
716f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberlingimport com.android.camera.data.MediaDetails;
72bd26069d391830856c57c2141cd2efbc8423d871Angus Kongimport com.android.camera.data.SimpleViewData;
73a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberlingimport com.android.camera.tinyplanet.TinyPlanetFragment;
74ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport com.android.camera.ui.ModuleSwitcher;
756f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberlingimport com.android.camera.ui.DetailsDialog;
766432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport com.android.camera.ui.FilmStripView;
7788ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberlingimport com.android.camera.util.ApiHelper;
78b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kongimport com.android.camera.util.CameraUtil;
79a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunkimport com.android.camera.util.GcamHelper;
8037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberlingimport com.android.camera.util.PhotoSphereHelper;
8188ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberlingimport com.android.camera.util.PhotoSphereHelper.PanoramaViewHelper;
828e963a5a6016d246184ed65906f9d103e92b17e2Sascha Haeberlingimport com.android.camera2.R;
838872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
844f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kongimport static com.android.camera.CameraManager.CameraOpenErrorCallback;
854f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong
866432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liupublic class CameraActivity extends Activity
87a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        implements ModuleSwitcher.ModuleSwitchListener {
886432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
896432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private static final String TAG = "CAM_Activity";
906432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
914ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling    /**
924ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling     * The visibility flags to use to switch the system in either lights-out
934ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling     * mode (pre-K) or hideybar mode (K and up).
944ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling     */
954ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling    private static final int IMMERSIVE_FLAGS = getImmersiveFlags();
964ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling
976432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private static final String INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE =
986432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            "android.media.action.STILL_IMAGE_CAMERA_SECURE";
996432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public static final String ACTION_IMAGE_CAPTURE_SECURE =
1006432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            "android.media.action.IMAGE_CAPTURE_SECURE";
1016b9203214d828d72758943aca55adceab684a862ztenghui    public static final String ACTION_TRIM_VIDEO =
1026b9203214d828d72758943aca55adceab684a862ztenghui            "com.android.camera.action.TRIM";
1036b9203214d828d72758943aca55adceab684a862ztenghui    public static final String MEDIA_ITEM_PATH = "media-item-path";
1046432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
1052654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling    private static final String PREF_STARTUP_MODULE_INDEX = "camera.startup_module";
1062654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling
1076432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    // The intent extra for camera from secure lock screen. True if the gallery
1086432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    // should only show newly captured pictures. sSecureAlbumId does not
1096432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    // increment. This is used when switching between camera, camcorder, and
1106432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    // panorama. If the extra is not set, it is in the normal camera mode.
1116432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public static final String SECURE_CAMERA_EXTRA = "secure_camera";
1126432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
113b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    /**
114b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling     * Request code from an activity we started that indicated that we do not
115b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling     * want to reset the view to the preview in onResume.
116b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling     */
117b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    public static final int REQ_CODE_DONT_SWITCH_TO_PREVIEW = 142;
118b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling
119b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    /** Request code for external image editor activities. */
120b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    private static final int REQ_CODE_EDIT = 1;
121b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling
122b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling
123b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    /** Whether onResume should reset the view to the preview. */
124b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    private boolean mResetToPreviewOnResume = true;
125b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling
1260353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    // Supported operations at FilmStripView. Different data has different
1270353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    // set of supported operations.
1280353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private static final int SUPPORT_DELETE = 1 << 0;
1290353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private static final int SUPPORT_ROTATE = 1 << 1;
1300353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private static final int SUPPORT_INFO = 1 << 2;
1310353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private static final int SUPPORT_CROP = 1 << 3;
1320353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private static final int SUPPORT_SETAS = 1 << 4;
1330353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private static final int SUPPORT_EDIT = 1 << 5;
1340353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private static final int SUPPORT_TRIM = 1 << 6;
135cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private static final int SUPPORT_SHARE = 1 << 7;
136cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private static final int SUPPORT_SHARE_PANORAMA360 = 1 << 8;
137cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private static final int SUPPORT_SHOW_ON_MAP = 1 << 9;
1380353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private static final int SUPPORT_ALL = 0xffffffff;
1390353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui
1406f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling    /** This data adapter is used by FilmStripView. */
1418e5e4eedb25a4589342660b928935acca4375fc7Angus Kong    private LocalDataAdapter mDataAdapter;
1428e5e4eedb25a4589342660b928935acca4375fc7Angus Kong    /** This data adapter represents the real local camera data. */
1438e5e4eedb25a4589342660b928935acca4375fc7Angus Kong    private LocalDataAdapter mWrappedDataAdapter;
1448e5e4eedb25a4589342660b928935acca4375fc7Angus Kong
1456798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong    private PanoramaStitchingManager mPanoramaManager;
1468872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private int mCurrentModuleIndex;
1476432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private CameraModule mCurrentModule;
148653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong    private FrameLayout mAboveFilmstripControlLayout;
149653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong    private View mCameraModuleRootView;
1506432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private FilmStripView mFilmStripView;
15137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    private ProgressBar mBottomProgress;
15237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    private View mPanoStitchingPanel;
1536432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private int mResultCodeForTesting;
1546432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private Intent mResultDataForTesting;
1556432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private OnScreenHint mStorageHint;
1566432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private long mStorageSpace = Storage.LOW_STORAGE_THRESHOLD;
1573cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu    private boolean mAutoRotateScreen;
1586432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private boolean mSecureCamera;
1596a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    // This is a hack to speed up the start of SecureCamera.
1606a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    private static boolean sFirstStartAfterScreenOn = true;
1616432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private int mLastRawOrientation;
1628872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private MyOrientationEventListener mOrientationListener;
1636432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private Handler mMainHandler;
164f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling    private PanoramaViewHelper mPanoramaViewHelper;
1658e5e4eedb25a4589342660b928935acca4375fc7Angus Kong    private CameraPreviewData mCameraPreviewData;
166fa9e2cc9ccbcd746f5765cb7a0afebcdb60e2973ztenghui    private ActionBar mActionBar;
1670353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private Menu mActionBarMenu;
168653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong    private ViewGroup mUndoDeletionBar;
169742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    private boolean mIsUndoingDeletion = false;
1703cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu
171a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware    private Uri[] mNfcPushUris = new Uri[1];
172a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware
173cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private ShareActionProvider mStandardShareActionProvider;
174cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private Intent mStandardShareIntent;
175cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private ShareActionProvider mPanoramaShareActionProvider;
176cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private Intent mPanoramaShareIntent;
177cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware
1785199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling    private final int DEFAULT_SYSTEM_UI_VISIBILITY = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
1795199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
180742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    private boolean mPendingDeletion = false;
1815199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling
18205804751ba07c8abcf422f57467d0ed3de95576cztenghui    private Intent mVideoShareIntent;
18305804751ba07c8abcf422f57467d0ed3de95576cztenghui    private Intent mImageShareIntent;
18405804751ba07c8abcf422f57467d0ed3de95576cztenghui
1858872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private class MyOrientationEventListener
186a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            extends OrientationEventListener {
1878872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        public MyOrientationEventListener(Context context) {
1888872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            super(context);
1898872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
1908872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
1918872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        @Override
1928872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        public void onOrientationChanged(int orientation) {
1938872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // We keep the last known orientation. So if the user first orient
1948872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // the camera then point the camera to floor or sky, we still have
1958872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // the correct orientation.
196a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            if (orientation == ORIENTATION_UNKNOWN) {
197a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                return;
198a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            }
1998872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            mLastRawOrientation = orientation;
2008872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            mCurrentModule.onOrientationChanged(orientation);
2018872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
2028872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
2038872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
2046432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private MediaSaveService mMediaSaveService;
2056432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private ServiceConnection mConnection = new ServiceConnection() {
206a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        @Override
207a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        public void onServiceConnected(ComponentName className, IBinder b) {
208a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            mMediaSaveService = ((MediaSaveService.LocalBinder) b).getService();
209a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            mCurrentModule.onMediaSaveServiceConnected(mMediaSaveService);
210a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        }
211a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling
212a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        @Override
213a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        public void onServiceDisconnected(ComponentName className) {
214a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            if (mMediaSaveService != null) {
215a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                mMediaSaveService.setListener(null);
216a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                mMediaSaveService = null;
2178872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            }
218a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        }
219a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling    };
220e319aeabdc825f221df5af8a6ec080c6f5d41a94John Reck
2214f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong    private CameraOpenErrorCallback mCameraOpenErrorCallback =
2224f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong            new CameraOpenErrorCallback() {
2234f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                @Override
2244f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                public void onCameraDisabled(int cameraId) {
2254f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                    CameraUtil.showErrorAndFinish(CameraActivity.this,
2264f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                            R.string.camera_disabled);
2274f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                }
2284f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong
2294f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                @Override
2304f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                public void onDeviceOpenFailure(int cameraId) {
2314f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                    CameraUtil.showErrorAndFinish(CameraActivity.this,
2324f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                            R.string.cannot_connect_camera);
2334f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                }
2344f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong
2354f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                @Override
2364f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                public void onReconnectionFailure(CameraManager mgr) {
2374f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                    CameraUtil.showErrorAndFinish(CameraActivity.this,
2384f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                            R.string.cannot_connect_camera);
2394f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                }
2404f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong            };
2414f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong
242b84b9738c855a525dc1944165983cc3c342ce446Doris Liu    // close activity when screen turns off
243b84b9738c855a525dc1944165983cc3c342ce446Doris Liu    private BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() {
244b84b9738c855a525dc1944165983cc3c342ce446Doris Liu        @Override
245b84b9738c855a525dc1944165983cc3c342ce446Doris Liu        public void onReceive(Context context, Intent intent) {
246b84b9738c855a525dc1944165983cc3c342ce446Doris Liu            finish();
247b84b9738c855a525dc1944165983cc3c342ce446Doris Liu        }
248b84b9738c855a525dc1944165983cc3c342ce446Doris Liu    };
249b84b9738c855a525dc1944165983cc3c342ce446Doris Liu
2506a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    private static BroadcastReceiver sScreenOffReceiver;
251a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling
2526a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    private static class ScreenOffReceiver extends BroadcastReceiver {
2536a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong        @Override
2546a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong        public void onReceive(Context context, Intent intent) {
2556a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong            sFirstStartAfterScreenOn = true;
2566a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong        }
2576a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    }
2586a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong
2594ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling    private static int getImmersiveFlags() {
260638e6f06c877d90b907f66ea9c22b3c6b73c7384Sascha Haeberling        if (ApiHelper.HAS_HIDEYBARS) {
2614ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling            return View.SYSTEM_UI_FLAG_IMMERSIVE
2624ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling                    | View.SYSTEM_UI_FLAG_TRANSPARENT_STATUS
2634ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling                    | View.SYSTEM_UI_FLAG_TRANSPARENT_NAVIGATION
2644ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
2654ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling                    | View.SYSTEM_UI_FLAG_FULLSCREEN;
2664ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling        } else {
2674ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling            // Pre-KitKat we use lights-out mode.
2684ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling            return View.SYSTEM_UI_FLAG_LOW_PROFILE;
2694ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling        }
2704ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling    }
2714ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling
2726a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    public static boolean isFirstStartAfterScreenOn() {
2736a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong        return sFirstStartAfterScreenOn;
2746a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    }
2756a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong
2766a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    public static void resetFirstStartAfterScreenOn() {
2776a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong        sFirstStartAfterScreenOn = false;
2786a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    }
2796a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong
28037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    private FilmStripView.Listener mFilmStripListener =
28137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            new FilmStripView.Listener() {
28237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                @Override
28337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                public void onDataPromoted(int dataID) {
28437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    removeData(dataID);
28537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                }
286e319aeabdc825f221df5af8a6ec080c6f5d41a94John Reck
28737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                @Override
28837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                public void onDataDemoted(int dataID) {
28937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    removeData(dataID);
29037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                }
291e319aeabdc825f221df5af8a6ec080c6f5d41a94John Reck
29237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                @Override
29337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                public void onDataFullScreenChange(int dataID, boolean full) {
2948566dd777cd219254c945240a31ac97de28792a2ztenghui                    boolean isCameraID = isCameraPreview(dataID);
2957b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                    if (!isCameraID) {
2967b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                        setActionBarVisibilityAndLightsOut(full);
297fa9e2cc9ccbcd746f5765cb7a0afebcdb60e2973ztenghui                    }
29837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                }
29937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling
3008566dd777cd219254c945240a31ac97de28792a2ztenghui                /**
3018566dd777cd219254c945240a31ac97de28792a2ztenghui                 * Check if the local data corresponding to dataID is the camera
3028566dd777cd219254c945240a31ac97de28792a2ztenghui                 * preview.
3038566dd777cd219254c945240a31ac97de28792a2ztenghui                 *
3048566dd777cd219254c945240a31ac97de28792a2ztenghui                 * @param dataID the ID of the local data
3058566dd777cd219254c945240a31ac97de28792a2ztenghui                 * @return true if the local data is not null and it is the
3068566dd777cd219254c945240a31ac97de28792a2ztenghui                 *         camera preview.
3078566dd777cd219254c945240a31ac97de28792a2ztenghui                 */
3088566dd777cd219254c945240a31ac97de28792a2ztenghui                private boolean isCameraPreview(int dataID) {
3098566dd777cd219254c945240a31ac97de28792a2ztenghui                    LocalData localData = mDataAdapter.getLocalData(dataID);
3108566dd777cd219254c945240a31ac97de28792a2ztenghui                    if (localData == null) {
3118566dd777cd219254c945240a31ac97de28792a2ztenghui                        Log.w(TAG, "Current data ID not found.");
3128566dd777cd219254c945240a31ac97de28792a2ztenghui                        return false;
3138566dd777cd219254c945240a31ac97de28792a2ztenghui                    }
3148566dd777cd219254c945240a31ac97de28792a2ztenghui                    return localData.getLocalDataType() == LocalData.LOCAL_CAMERA_PREVIEW;
3158566dd777cd219254c945240a31ac97de28792a2ztenghui                }
3168566dd777cd219254c945240a31ac97de28792a2ztenghui
31737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                @Override
31833035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                public void onCurrentDataChanged(final int dataID, final boolean current) {
31933035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                    runOnUiThread(new Runnable() {
32033035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                        @Override
32133035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                        public void run() {
3227b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                            LocalData currentData = mDataAdapter.getLocalData(dataID);
3237b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                            if (currentData == null) {
3247b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                Log.w(TAG, "Current data ID not found.");
3257b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                hidePanoStitchingProgress();
3267b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                return;
3277b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                            }
3287b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                            boolean isCameraID = currentData.getLocalDataType() ==
3297b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                    LocalData.LOCAL_CAMERA_PREVIEW;
33033035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                            if (!current) {
3317b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                if (isCameraID) {
3327b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                    mCurrentModule.onPreviewFocusChanged(false);
3337b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                    setActionBarVisibilityAndLightsOut(false);
3347b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                }
33533035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                hidePanoStitchingProgress();
33633035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                            } else {
3377b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                if (isCameraID) {
3387b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                    mCurrentModule.onPreviewFocusChanged(true);
339a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                                    // Don't show the action bar in Camera
340a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                                    // preview.
3415199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling                                    setActionBarVisibilityAndLightsOut(true);
342742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                                    if (mPendingDeletion) {
343742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                                        performDeletion();
344742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                                    }
3451ef76d4cbd73c02cb8d02cf4cde3f4cee81548d6Alan Newberger                                } else {
3461ef76d4cbd73c02cb8d02cf4cde3f4cee81548d6Alan Newberger                                    updateActionBarMenu(dataID);
3471ef76d4cbd73c02cb8d02cf4cde3f4cee81548d6Alan Newberger                                }
34833035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware
34933035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                Uri contentUri = currentData.getContentUri();
35033035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                if (contentUri == null) {
35133035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                    hidePanoStitchingProgress();
35233035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                    return;
35333035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                }
35433035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                int panoStitchingProgress = mPanoramaManager.getTaskProgress(
355a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                                        contentUri);
35633035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                if (panoStitchingProgress < 0) {
35733035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                    hidePanoStitchingProgress();
35833035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                    return;
35933035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                }
36033035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                showPanoStitchingProgress();
36133035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                updateStitchingProgress(panoStitchingProgress);
36233035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                            }
36337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        }
36433035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                    });
36537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                }
366394023fb7e3c8d07d4aeafc30bf4b66ed481ebb7Sascha Haeberling
367394023fb7e3c8d07d4aeafc30bf4b66ed481ebb7Sascha Haeberling                @Override
3688566dd777cd219254c945240a31ac97de28792a2ztenghui                public boolean onToggleActionBarVisibility(int dataID) {
369394023fb7e3c8d07d4aeafc30bf4b66ed481ebb7Sascha Haeberling                    if (mActionBar.isShowing()) {
3705199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling                        setActionBarVisibilityAndLightsOut(true);
3714ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling                        return false;
372394023fb7e3c8d07d4aeafc30bf4b66ed481ebb7Sascha Haeberling                    } else {
3738566dd777cd219254c945240a31ac97de28792a2ztenghui                        // Don't show the action bar if that is the camera preview.
3748566dd777cd219254c945240a31ac97de28792a2ztenghui                        boolean isCameraID = isCameraPreview(dataID);
3758566dd777cd219254c945240a31ac97de28792a2ztenghui                        if (!isCameraID) {
3765199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling                            setActionBarVisibilityAndLightsOut(false);
3774ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling                            return true;
378fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui                        }
3794ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling                        return false;
380394023fb7e3c8d07d4aeafc30bf4b66ed481ebb7Sascha Haeberling                    }
381394023fb7e3c8d07d4aeafc30bf4b66ed481ebb7Sascha Haeberling                }
38237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            };
38337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling
3844ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling    public void gotoGallery() {
3854ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling        mFilmStripView.getController().goToNextItem();
3864ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling    }
3874ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling
3885199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling    /**
3895199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling     * If enabled, this hides the action bar and switches the system UI to
3905199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling     * lights-out mode.
3915199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling     */
3925199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling    private void setActionBarVisibilityAndLightsOut(boolean enabled) {
3934ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling        int visibility = DEFAULT_SYSTEM_UI_VISIBILITY | (enabled ? IMMERSIVE_FLAGS
3944ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling                : View.SYSTEM_UI_FLAG_VISIBLE);
3954ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling        mAboveFilmstripControlLayout
3964ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling                .setSystemUiVisibility(visibility);
3975199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling        if (enabled) {
3985199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling            mActionBar.hide();
3995199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling        } else {
4005199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling            mActionBar.show();
4015199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling        }
4025199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling    }
4035199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling
40437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    private void hidePanoStitchingProgress() {
40537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        mPanoStitchingPanel.setVisibility(View.GONE);
40637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    }
40737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling
40837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    private void showPanoStitchingProgress() {
40937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        mPanoStitchingPanel.setVisibility(View.VISIBLE);
41037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    }
41137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling
41237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    private void updateStitchingProgress(int progress) {
41337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        mBottomProgress.setProgress(progress);
41437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    }
4158872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
416a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
417a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware    private void setupNfcBeamPush() {
418a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware        NfcAdapter adapter = NfcAdapter.getDefaultAdapter(CameraActivity.this);
419a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware        if (adapter == null) {
420a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware            return;
421a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware        }
422a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware
423a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware        if (!ApiHelper.HAS_SET_BEAM_PUSH_URIS) {
424a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware            // Disable beaming
425a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware            adapter.setNdefPushMessage(null, CameraActivity.this);
426a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware            return;
427a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware        }
428a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware
429a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware        adapter.setBeamPushUris(null, CameraActivity.this);
430a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware        adapter.setBeamPushUrisCallback(new CreateBeamUrisCallback() {
431a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware            @Override
432a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware            public Uri[] createBeamUris(NfcEvent event) {
433a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware                return mNfcPushUris;
434a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware            }
435a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware        }, CameraActivity.this);
436a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware    }
437a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware
438a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware    private void setNfcBeamPushUri(Uri uri) {
439a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware        mNfcPushUris[0] = uri;
440a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware    }
441a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware
442cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private void setStandardShareIntent(Uri contentUri, String mimeType) {
44305804751ba07c8abcf422f57467d0ed3de95576cztenghui        mStandardShareIntent = getShareIntentFromType(mimeType);
44405804751ba07c8abcf422f57467d0ed3de95576cztenghui        if (mStandardShareIntent != null) {
44505804751ba07c8abcf422f57467d0ed3de95576cztenghui            mStandardShareIntent.putExtra(Intent.EXTRA_STREAM, contentUri);
44605804751ba07c8abcf422f57467d0ed3de95576cztenghui            mStandardShareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
44705804751ba07c8abcf422f57467d0ed3de95576cztenghui            if (mStandardShareActionProvider != null) {
44805804751ba07c8abcf422f57467d0ed3de95576cztenghui                mStandardShareActionProvider.setShareIntent(mStandardShareIntent);
44905804751ba07c8abcf422f57467d0ed3de95576cztenghui            }
450cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        }
45105804751ba07c8abcf422f57467d0ed3de95576cztenghui    }
45205804751ba07c8abcf422f57467d0ed3de95576cztenghui
45305804751ba07c8abcf422f57467d0ed3de95576cztenghui    /**
45405804751ba07c8abcf422f57467d0ed3de95576cztenghui     * Get the share intent according to the mimeType
45505804751ba07c8abcf422f57467d0ed3de95576cztenghui     *
45605804751ba07c8abcf422f57467d0ed3de95576cztenghui     * @param mimeType The mimeType of current data.
45705804751ba07c8abcf422f57467d0ed3de95576cztenghui     * @return the video/image's ShareIntent or null if mimeType is invalid.
45805804751ba07c8abcf422f57467d0ed3de95576cztenghui     */
45905804751ba07c8abcf422f57467d0ed3de95576cztenghui    private Intent getShareIntentFromType(String mimeType) {
46005804751ba07c8abcf422f57467d0ed3de95576cztenghui        // Lazily create the intent object.
46105804751ba07c8abcf422f57467d0ed3de95576cztenghui        if (mimeType.startsWith("video/")) {
46205804751ba07c8abcf422f57467d0ed3de95576cztenghui            if (mVideoShareIntent == null) {
46305804751ba07c8abcf422f57467d0ed3de95576cztenghui                mVideoShareIntent = new Intent(Intent.ACTION_SEND);
46405804751ba07c8abcf422f57467d0ed3de95576cztenghui                mVideoShareIntent.setType("video/*");
46505804751ba07c8abcf422f57467d0ed3de95576cztenghui            }
46605804751ba07c8abcf422f57467d0ed3de95576cztenghui            return mVideoShareIntent;
46705804751ba07c8abcf422f57467d0ed3de95576cztenghui        } else if (mimeType.startsWith("image/")) {
46805804751ba07c8abcf422f57467d0ed3de95576cztenghui            if (mImageShareIntent == null) {
46905804751ba07c8abcf422f57467d0ed3de95576cztenghui                mImageShareIntent = new Intent(Intent.ACTION_SEND);
47005804751ba07c8abcf422f57467d0ed3de95576cztenghui                mImageShareIntent.setType("image/*");
47105804751ba07c8abcf422f57467d0ed3de95576cztenghui            }
47205804751ba07c8abcf422f57467d0ed3de95576cztenghui            return mImageShareIntent;
473cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        }
47405804751ba07c8abcf422f57467d0ed3de95576cztenghui        Log.w(TAG, "unsupported mimeType " + mimeType);
47505804751ba07c8abcf422f57467d0ed3de95576cztenghui        return null;
476cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    }
477cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware
478cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private void setPanoramaShareIntent(Uri contentUri) {
479cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        if (mPanoramaShareIntent == null) {
480cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware            mPanoramaShareIntent = new Intent(Intent.ACTION_SEND);
481cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        }
482cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        mPanoramaShareIntent.setType("application/vnd.google.panorama360+jpg");
483cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        mPanoramaShareIntent.putExtra(Intent.EXTRA_STREAM, contentUri);
484cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        if (mPanoramaShareActionProvider != null) {
485cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware            mPanoramaShareActionProvider.setShareIntent(mPanoramaShareIntent);
486cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        }
487cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    }
488cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware
4890353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    /**
4900353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui     * According to the data type, make the menu items for supported operations
4910353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui     * visible.
492a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     *
493fae11a165e344a38811770c7d348eda214683edcSascha Haeberling     * @param dataID the data ID of the current item.
4940353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui     */
495fae11a165e344a38811770c7d348eda214683edcSascha Haeberling    private void updateActionBarMenu(int dataID) {
496fae11a165e344a38811770c7d348eda214683edcSascha Haeberling        LocalData currentData = mDataAdapter.getLocalData(dataID);
497fae11a165e344a38811770c7d348eda214683edcSascha Haeberling        int type = currentData.getLocalDataType();
498fae11a165e344a38811770c7d348eda214683edcSascha Haeberling
4990353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        if (mActionBarMenu == null) {
5000353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            return;
5010353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        }
5020353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui
5030353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        int supported = 0;
5040353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        switch (type) {
5050353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case LocalData.LOCAL_IMAGE:
5060353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                supported |= SUPPORT_DELETE | SUPPORT_ROTATE | SUPPORT_INFO
5070353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                        | SUPPORT_CROP | SUPPORT_SETAS | SUPPORT_EDIT
508cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                        | SUPPORT_SHARE | SUPPORT_SHOW_ON_MAP;
5090353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                break;
5100353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case LocalData.LOCAL_VIDEO:
511cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                supported |= SUPPORT_DELETE | SUPPORT_INFO | SUPPORT_TRIM
512cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                        | SUPPORT_SHARE;
5130353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                break;
5140353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case LocalData.LOCAL_PHOTO_SPHERE:
5150353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                supported |= SUPPORT_DELETE | SUPPORT_ROTATE | SUPPORT_INFO
5160353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                        | SUPPORT_CROP | SUPPORT_SETAS | SUPPORT_EDIT
517cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                        | SUPPORT_SHARE | SUPPORT_SHOW_ON_MAP;
518cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                break;
519cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware            case LocalData.LOCAL_360_PHOTO_SPHERE:
520cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                supported |= SUPPORT_DELETE | SUPPORT_ROTATE | SUPPORT_INFO
521cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                        | SUPPORT_CROP | SUPPORT_SETAS | SUPPORT_EDIT
522cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                        | SUPPORT_SHARE | SUPPORT_SHARE_PANORAMA360
5230353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                        | SUPPORT_SHOW_ON_MAP;
5240353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                break;
5250353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            default:
5260353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                break;
5270353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        }
5280353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui
5290353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        setMenuItemVisible(mActionBarMenu, R.id.action_delete,
5300353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                (supported & SUPPORT_DELETE) != 0);
5310353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        setMenuItemVisible(mActionBarMenu, R.id.action_rotate_ccw,
5320353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                (supported & SUPPORT_ROTATE) != 0);
5330353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        setMenuItemVisible(mActionBarMenu, R.id.action_rotate_cw,
5340353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                (supported & SUPPORT_ROTATE) != 0);
535cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        setMenuItemVisible(mActionBarMenu, R.id.action_details,
536cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                (supported & SUPPORT_INFO) != 0);
5370353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        setMenuItemVisible(mActionBarMenu, R.id.action_crop,
5380353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                (supported & SUPPORT_CROP) != 0);
5390353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        setMenuItemVisible(mActionBarMenu, R.id.action_setas,
5400353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                (supported & SUPPORT_SETAS) != 0);
5410353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        setMenuItemVisible(mActionBarMenu, R.id.action_edit,
5420353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                (supported & SUPPORT_EDIT) != 0);
543cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        setMenuItemVisible(mActionBarMenu, R.id.action_trim,
544cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                (supported & SUPPORT_TRIM) != 0);
545cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware
54633035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        boolean standardShare = (supported & SUPPORT_SHARE) != 0;
54733035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        boolean panoramaShare = (supported & SUPPORT_SHARE_PANORAMA360) != 0;
54833035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        setMenuItemVisible(mActionBarMenu, R.id.action_share, standardShare);
54933035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        setMenuItemVisible(mActionBarMenu, R.id.action_share_panorama, panoramaShare);
55033035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware
55133035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        if (panoramaShare) {
55233035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            // For 360 PhotoSphere, relegate standard share to the overflow menu
55333035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            MenuItem item = mActionBarMenu.findItem(R.id.action_share);
55433035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            if (item != null) {
55533035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                item.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
55633035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                item.setTitle(getResources().getString(R.string.share_as_photo));
55733035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            }
55833035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            // And, promote "share as panorama" to action bar
55933035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            item = mActionBarMenu.findItem(R.id.action_share_panorama);
56033035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            if (item != null) {
56133035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
56233035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            }
563cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware            setPanoramaShareIntent(currentData.getContentUri());
564cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        }
56533035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        if (standardShare) {
56633035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            if (!panoramaShare) {
56733035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                MenuItem item = mActionBarMenu.findItem(R.id.action_share);
56833035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                if (item != null) {
56933035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                    item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
57033035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                    item.setTitle(getResources().getString(R.string.share));
57133035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                }
57233035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            }
57333035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            setStandardShareIntent(currentData.getContentUri(), currentData.getMimeType());
574a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware            setNfcBeamPushUri(currentData.getContentUri());
57533035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        }
576fae11a165e344a38811770c7d348eda214683edcSascha Haeberling
577fae11a165e344a38811770c7d348eda214683edcSascha Haeberling        boolean itemHasLocation = currentData.getLatLong() != null;
578fae11a165e344a38811770c7d348eda214683edcSascha Haeberling        setMenuItemVisible(mActionBarMenu, R.id.action_show_on_map,
579fae11a165e344a38811770c7d348eda214683edcSascha Haeberling                itemHasLocation && (supported & SUPPORT_SHOW_ON_MAP) != 0);
5800353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    }
5810353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui
5820353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private void setMenuItemVisible(Menu menu, int itemId, boolean visible) {
5830353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        MenuItem item = menu.findItem(itemId);
5840353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        if (item != null)
5850353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            item.setVisible(visible);
5860353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    }
5870353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui
5886798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong    private ImageTaskManager.TaskListener mStitchingListener =
5896798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong            new ImageTaskManager.TaskListener() {
5906798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong                @Override
59137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                public void onTaskQueued(String filePath, final Uri imageUri) {
59237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    mMainHandler.post(new Runnable() {
59337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        @Override
59437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        public void run() {
59537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            notifyNewMedia(imageUri);
59637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        }
59737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    });
5986798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong                }
5996798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong
6006798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong                @Override
60137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                public void onTaskDone(String filePath, final Uri imageUri) {
60237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    Log.v(TAG, "onTaskDone:" + filePath);
60337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    mMainHandler.post(new Runnable() {
60437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        @Override
60537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        public void run() {
60637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            int doneID = mDataAdapter.findDataByContentUri(imageUri);
60737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            int currentDataId = mFilmStripView.getCurrentId();
60837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling
60937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            if (currentDataId == doneID) {
61037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                                hidePanoStitchingProgress();
61137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                                updateStitchingProgress(0);
61237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            }
61337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling
61437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            mDataAdapter.refresh(getContentResolver(), imageUri);
61537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        }
61637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    });
6176798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong                }
6186798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong
6196798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong                @Override
6206798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong                public void onTaskProgress(
62137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        String filePath, final Uri imageUri, final int progress) {
62237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    mMainHandler.post(new Runnable() {
62337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        @Override
62437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        public void run() {
62537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            int currentDataId = mFilmStripView.getCurrentId();
62637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            if (currentDataId == -1) {
62737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                                return;
62837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            }
62937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            if (imageUri.equals(
63037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                                    mDataAdapter.getLocalData(currentDataId).getContentUri())) {
63137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                                updateStitchingProgress(progress);
63237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            }
63337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        }
63437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    });
6356798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong                }
6366798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong            };
6376798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong
6386432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public MediaSaveService getMediaSaveService() {
6396432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return mMediaSaveService;
6408872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
6418872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
6426432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void notifyNewMedia(Uri uri) {
6436432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        ContentResolver cr = getContentResolver();
6446432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        String mimeType = cr.getType(uri);
6456432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (mimeType.startsWith("video/")) {
646b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong            sendBroadcast(new Intent(CameraUtil.ACTION_NEW_VIDEO, uri));
6476432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mDataAdapter.addNewVideo(cr, uri);
6486432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else if (mimeType.startsWith("image/")) {
649b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong            CameraUtil.broadcastNewPicture(this, uri);
6506432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mDataAdapter.addNewPhoto(cr, uri);
65137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        } else if (mimeType.startsWith("application/stitching-preview")) {
65237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            mDataAdapter.addNewPhoto(cr, uri);
6536432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else {
6546432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            android.util.Log.w(TAG, "Unknown new media with MIME type:"
6556432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                    + mimeType + ", uri:" + uri);
6566432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
6578872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
6588872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
6596432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private void removeData(int dataID) {
6606432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mDataAdapter.removeData(CameraActivity.this, dataID);
661742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        if (mDataAdapter.getTotalNumber() > 1) {
662742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            showUndoDeletionBar();
663742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        } else {
664742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // If camera preview is the only view left in filmstrip,
665742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // no need to show undo bar.
666742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            performDeletion();
667742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        }
6688872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
6698872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
6706432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private void bindMediaSaveService() {
6716432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        Intent intent = new Intent(this, MediaSaveService.class);
6726432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
6738872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
6748872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
6756432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private void unbindMediaSaveService() {
6766432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (mConnection != null) {
6776432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            unbindService(mConnection);
6786432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
6798872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
6808872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
6816432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    @Override
6820353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    public boolean onCreateOptionsMenu(Menu menu) {
6830353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        // Inflate the menu items for use in the action bar
6840353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        MenuInflater inflater = getMenuInflater();
6850353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        inflater.inflate(R.menu.operations, menu);
6860353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        mActionBarMenu = menu;
687cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware
688cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        // Configure the standard share action provider
689cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        MenuItem item = menu.findItem(R.id.action_share);
690cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        mStandardShareActionProvider = (ShareActionProvider) item.getActionProvider();
69133035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        mStandardShareActionProvider.setShareHistoryFileName("standard_share_history.xml");
692cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        if (mStandardShareIntent != null) {
693cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware            mStandardShareActionProvider.setShareIntent(mStandardShareIntent);
694cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        }
695cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware
696cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        // Configure the panorama share action provider
697cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        item = menu.findItem(R.id.action_share_panorama);
698cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        mPanoramaShareActionProvider = (ShareActionProvider) item.getActionProvider();
69933035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        mPanoramaShareActionProvider.setShareHistoryFileName("panorama_share_history.xml");
700cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        if (mPanoramaShareIntent != null) {
701cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware            mPanoramaShareActionProvider.setShareIntent(mPanoramaShareIntent);
702cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        }
703cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware
7040353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        return super.onCreateOptionsMenu(menu);
7050353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    }
7060353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui
7070353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    @Override
7080353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    public boolean onOptionsItemSelected(MenuItem item) {
7096f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling        int currentDataId = mFilmStripView.getCurrentId();
7106f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling        if (currentDataId < 0) {
7116f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling            return false;
7126f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling        }
7136f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling        final LocalData localData = mDataAdapter.getLocalData(currentDataId);
7146f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling
7150353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        // Handle presses on the action bar items
7160353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        switch (item.getItemId()) {
7173f969c1735e2636bf22dfe44104d0e99924cca97Alan Newberger            case android.R.id.home:
7183f969c1735e2636bf22dfe44104d0e99924cca97Alan Newberger                // ActionBar's Up/Home button was clicked
7195df64b0a818d4f85cb14602db725f05b0055c1d9Mangesh Ghiware                if (ApiHelper.HAS_APP_GALLERY) {
7205df64b0a818d4f85cb14602db725f05b0055c1d9Mangesh Ghiware                    startActivity(Intent.makeMainSelectorActivity(
7215df64b0a818d4f85cb14602db725f05b0055c1d9Mangesh Ghiware                                Intent.ACTION_MAIN, Intent.CATEGORY_APP_GALLERY));
7225df64b0a818d4f85cb14602db725f05b0055c1d9Mangesh Ghiware                } else {
7235df64b0a818d4f85cb14602db725f05b0055c1d9Mangesh Ghiware                    mFilmStripView.getController().goToFirstItem();
7245df64b0a818d4f85cb14602db725f05b0055c1d9Mangesh Ghiware                }
7253f969c1735e2636bf22dfe44104d0e99924cca97Alan Newberger                return true;
7260353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case R.id.action_delete:
727e857cc90a98e280e2008beb03e2446bd642d2ec4Angus Kong                removeData(currentDataId);
7280353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
7290353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case R.id.action_edit:
73088ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling                launchEditor(localData);
7310353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
7320819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard            case R.id.action_trim: {
7336b9203214d828d72758943aca55adceab684a862ztenghui                // This is going to be handled by the Gallery app.
7346b9203214d828d72758943aca55adceab684a862ztenghui                Intent intent = new Intent(ACTION_TRIM_VIDEO);
7356b9203214d828d72758943aca55adceab684a862ztenghui                LocalData currentData = mDataAdapter.getLocalData(
7366b9203214d828d72758943aca55adceab684a862ztenghui                        mFilmStripView.getCurrentId());
7376b9203214d828d72758943aca55adceab684a862ztenghui                intent.setData(currentData.getContentUri());
7386b9203214d828d72758943aca55adceab684a862ztenghui                // We need the file path to wrap this into a RandomAccessFile.
7396b9203214d828d72758943aca55adceab684a862ztenghui                intent.putExtra(MEDIA_ITEM_PATH, currentData.getPath());
740b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                startActivityForResult(intent, REQ_CODE_DONT_SWITCH_TO_PREVIEW);
7410353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
7420819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard            }
7430353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case R.id.action_rotate_ccw:
744a16e7b50f3148f581439509279f242092e254309ztenghui                localData.rotate90Degrees(this, mDataAdapter, currentDataId, false);
7450353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
7460353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case R.id.action_rotate_cw:
747a16e7b50f3148f581439509279f242092e254309ztenghui                localData.rotate90Degrees(this, mDataAdapter, currentDataId, true);
7480353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
7490353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case R.id.action_crop:
7500353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                // TODO: add the functionality.
7510353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
7520819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard            case R.id.action_setas: {
7530819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard                Intent intent = new Intent(Intent.ACTION_ATTACH_DATA)
7540819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard                        .setDataAndType(localData.getContentUri(),
7550819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard                                localData.getMimeType())
7560819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard                        .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
7570819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard                intent.putExtra("mimeType", intent.getType());
758b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                startActivityForResult(Intent.createChooser(
759b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                        intent, getString(R.string.set_as)), REQ_CODE_DONT_SWITCH_TO_PREVIEW);
7600353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
7610819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard            }
7620353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case R.id.action_details:
7636f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                (new AsyncTask<Void, Void, MediaDetails>() {
7646f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                    @Override
7656f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                    protected MediaDetails doInBackground(Void... params) {
7666f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                        return localData.getMediaDetails(CameraActivity.this);
7676f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                    }
7686f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling
7696f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                    @Override
7706f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                    protected void onPostExecute(MediaDetails mediaDetails) {
7716f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                        DetailsDialog.create(CameraActivity.this, mediaDetails).show();
7726f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                    }
7736f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                }).execute();
7740353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
7750353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case R.id.action_show_on_map:
776fae11a165e344a38811770c7d348eda214683edcSascha Haeberling                double[] latLong = localData.getLatLong();
777fae11a165e344a38811770c7d348eda214683edcSascha Haeberling                if (latLong != null) {
778a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                    CameraUtil.showOnMap(this, latLong);
779fae11a165e344a38811770c7d348eda214683edcSascha Haeberling                }
7800353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
7810353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            default:
7820353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return super.onOptionsItemSelected(item);
7830353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        }
7840353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    }
7850353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui
786fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui    private boolean isCaptureIntent() {
787fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui        if (MediaStore.ACTION_VIDEO_CAPTURE.equals(getIntent().getAction())
788fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui                || MediaStore.ACTION_IMAGE_CAPTURE.equals(getIntent().getAction())
789fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui                || MediaStore.ACTION_IMAGE_CAPTURE_SECURE.equals(getIntent().getAction())) {
790fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui            return true;
791fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui        } else {
792fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui            return false;
793fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui        }
794fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui    }
795fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui
7960353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    @Override
7976432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void onCreate(Bundle state) {
7986432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        super.onCreate(state);
79950df47071c776703a36dbc4cb90ec8d1df3c0f6eztenghui        getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
8006432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        setContentView(R.layout.camera_filmstrip);
801fa9e2cc9ccbcd746f5765cb7a0afebcdb60e2973ztenghui        mActionBar = getActionBar();
802fa9e2cc9ccbcd746f5765cb7a0afebcdb60e2973ztenghui
8036432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (ApiHelper.HAS_ROTATION_ANIMATION) {
8046432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            setRotationAnimation();
8056432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
8066432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        // Check if this is in the secure camera mode.
8076432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        Intent intent = getIntent();
8086432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        String action = intent.getAction();
809b84b9738c855a525dc1944165983cc3c342ce446Doris Liu        if (INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE.equals(action)
810b84b9738c855a525dc1944165983cc3c342ce446Doris Liu                || ACTION_IMAGE_CAPTURE_SECURE.equals(action)) {
8116432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mSecureCamera = true;
8126432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else {
8136432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mSecureCamera = intent.getBooleanExtra(SECURE_CAMERA_EXTRA, false);
8148872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
815b84b9738c855a525dc1944165983cc3c342ce446Doris Liu
816b84b9738c855a525dc1944165983cc3c342ce446Doris Liu        if (mSecureCamera) {
817b84b9738c855a525dc1944165983cc3c342ce446Doris Liu            // Change the window flags so that secure camera can show when locked
818b84b9738c855a525dc1944165983cc3c342ce446Doris Liu            Window win = getWindow();
819b84b9738c855a525dc1944165983cc3c342ce446Doris Liu            WindowManager.LayoutParams params = win.getAttributes();
820b84b9738c855a525dc1944165983cc3c342ce446Doris Liu            params.flags |= WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
821b84b9738c855a525dc1944165983cc3c342ce446Doris Liu            win.setAttributes(params);
822b84b9738c855a525dc1944165983cc3c342ce446Doris Liu
823b84b9738c855a525dc1944165983cc3c342ce446Doris Liu            // Filter for screen off so that we can finish secure camera activity
824b84b9738c855a525dc1944165983cc3c342ce446Doris Liu            // when screen is off.
8256432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
8266432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            registerReceiver(mScreenOffReceiver, filter);
8276a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong            // TODO: This static screen off event receiver is a workaround to the
8286a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong            // double onResume() invocation (onResume->onPause->onResume). We should
8296a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong            // find a better solution to this.
8306a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong            if (sScreenOffReceiver == null) {
8316a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong                sScreenOffReceiver = new ScreenOffReceiver();
8326a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong                registerReceiver(sScreenOffReceiver, filter);
8336a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong            }
834b84b9738c855a525dc1944165983cc3c342ce446Doris Liu        }
835653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        mAboveFilmstripControlLayout =
836653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong                (FrameLayout) findViewById(R.id.camera_above_filmstrip_layout);
837653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        mAboveFilmstripControlLayout.setFitsSystemWindows(true);
8385199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling        // Hide action bar first since we are in full screen mode first, and
8395199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling        // switch the system UI to lights-out mode.
8405199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling        setActionBarVisibilityAndLightsOut(true);
841ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mPanoramaManager = AppManagerFactory.getInstance(this)
842ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                .getPanoramaStitchingManager();
8436798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong        mPanoramaManager.addTaskListener(mStitchingListener);
8446432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        LayoutInflater inflater = getLayoutInflater();
8456432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        View rootLayout = inflater.inflate(R.layout.camera, null, false);
846653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        mCameraModuleRootView = rootLayout.findViewById(R.id.camera_app_root);
847fa9e2cc9ccbcd746f5765cb7a0afebcdb60e2973ztenghui        mPanoStitchingPanel = findViewById(R.id.pano_stitching_progress_panel);
84837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        mBottomProgress = (ProgressBar) findViewById(R.id.pano_stitching_progress_bar);
8498e5e4eedb25a4589342660b928935acca4375fc7Angus Kong        mCameraPreviewData = new CameraPreviewData(rootLayout,
8508e5e4eedb25a4589342660b928935acca4375fc7Angus Kong                FilmStripView.ImageData.SIZE_FULL,
8518e5e4eedb25a4589342660b928935acca4375fc7Angus Kong                FilmStripView.ImageData.SIZE_FULL);
85237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        // Put a CameraPreviewData at the first position.
8538e5e4eedb25a4589342660b928935acca4375fc7Angus Kong        mWrappedDataAdapter = new FixedFirstDataAdapter(
8548e5e4eedb25a4589342660b928935acca4375fc7Angus Kong                new CameraDataAdapter(new ColorDrawable(
8558e5e4eedb25a4589342660b928935acca4375fc7Angus Kong                        getResources().getColor(R.color.photo_placeholder))),
8568e5e4eedb25a4589342660b928935acca4375fc7Angus Kong                mCameraPreviewData);
8576432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mFilmStripView = (FilmStripView) findViewById(R.id.filmstrip_view);
8586432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mFilmStripView.setViewGap(
8596432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                getResources().getDimensionPixelSize(R.dimen.camera_film_strip_gap));
860f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling        mPanoramaViewHelper = new PanoramaViewHelper(this);
861f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling        mPanoramaViewHelper.onCreate();
862f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling        mFilmStripView.setPanoramaViewHelper(mPanoramaViewHelper);
8636432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        // Set up the camera preview first so the preview shows up ASAP.
8646432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mFilmStripView.setListener(mFilmStripListener);
8652654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling
8662654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        int moduleIndex = -1;
8672a7f44cac888de5683d05bef5708f846ee950f43Doris Liu        if (MediaStore.INTENT_ACTION_VIDEO_CAMERA.equals(getIntent().getAction())
8682a7f44cac888de5683d05bef5708f846ee950f43Doris Liu                || MediaStore.ACTION_VIDEO_CAPTURE.equals(getIntent().getAction())) {
869ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            moduleIndex = ModuleSwitcher.VIDEO_MODULE_INDEX;
8702654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        } else if (MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA.equals(getIntent().getAction())
8712654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling                || MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE.equals(getIntent()
8722654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling                        .getAction())
8732654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling                || MediaStore.ACTION_IMAGE_CAPTURE.equals(getIntent().getAction())
8742654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling                || MediaStore.ACTION_IMAGE_CAPTURE_SECURE.equals(getIntent().getAction())) {
875ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            moduleIndex = ModuleSwitcher.PHOTO_MODULE_INDEX;
8762a7f44cac888de5683d05bef5708f846ee950f43Doris Liu        } else {
8772654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling            // If the activity has not been started using an explicit intent,
8782654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling            // read the module index from the last time the user changed modes
8792654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
8802654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling            moduleIndex = prefs.getInt(PREF_STARTUP_MODULE_INDEX, -1);
881a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunk            if ((moduleIndex == ModuleSwitcher.GCAM_MODULE_INDEX &&
882a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunk                    !GcamHelper.hasGcamCapture(this)) || moduleIndex < 0) {
883ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                moduleIndex = ModuleSwitcher.PHOTO_MODULE_INDEX;
8842654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling            }
8852a7f44cac888de5683d05bef5708f846ee950f43Doris Liu        }
8862654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling
8876432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mOrientationListener = new MyOrientationEventListener(this);
888ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        setModuleFromIndex(moduleIndex);
889ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mCurrentModule.init(this, mCameraModuleRootView);
8906432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mMainHandler = new Handler(getMainLooper());
89137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling
89237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        if (!mSecureCamera) {
89337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            mDataAdapter = mWrappedDataAdapter;
894dcccc510652b835fdbd39310a07849af8203052aAngus Kong            mFilmStripView.setDataAdapter(mDataAdapter);
895a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong            if (!isCaptureIntent()) {
896a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong                mDataAdapter.requestLoad(getContentResolver());
897a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong            }
89837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        } else {
899a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            // Put a lock placeholder as the last image by setting its date to
900a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            // 0.
90137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            ImageView v = (ImageView) getLayoutInflater().inflate(
90237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    R.layout.secure_album_placeholder, null);
90337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            mDataAdapter = new FixedLastDataAdapter(
90437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    mWrappedDataAdapter,
905bd26069d391830856c57c2141cd2efbc8423d871Angus Kong                    new SimpleViewData(
90637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            v,
90737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            v.getDrawable().getIntrinsicWidth(),
90837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            v.getDrawable().getIntrinsicHeight(),
90937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            0, 0));
91037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            // Flush out all the original data.
91137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            mDataAdapter.flush();
912dcccc510652b835fdbd39310a07849af8203052aAngus Kong            mFilmStripView.setDataAdapter(mDataAdapter);
91337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        }
914a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware
915a5682ab08e1d42fe272ec877929478b4adb769f5Mangesh Ghiware        setupNfcBeamPush();
9168872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
9178872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
9186432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private void setRotationAnimation() {
9196432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        int rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE;
9206432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE;
9216432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        Window win = getWindow();
9226432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        WindowManager.LayoutParams winParams = win.getAttributes();
9236432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        winParams.rotationAnimation = rotationAnimation;
9246432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        win.setAttributes(winParams);
9258872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
9268872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
9278872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
9286432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void onUserInteraction() {
9296432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        super.onUserInteraction();
9306432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mCurrentModule.onUserInteraction();
93109106a41ee6acc6b20553662cb9b730702a8f08aDoris Liu    }
9328872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
9338872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
934742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    public boolean dispatchTouchEvent(MotionEvent ev) {
935742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        boolean result = super.dispatchTouchEvent(ev);
936742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
937742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // Real deletion is postponed until the next user interaction after
938742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // the gesture that triggers deletion. Until real deletion is performed,
939742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // users can click the undo button to bring back the image that they
940742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // chose to delete.
941742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            if (mPendingDeletion && !mIsUndoingDeletion) {
942742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                 performDeletion();
943742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            }
944742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        }
945742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        return result;
946742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    }
947742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu
948742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    @Override
9498872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void onPause() {
9508872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mOrientationListener.disable();
9518872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mCurrentModule.onPauseBeforeSuper();
9528872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        super.onPause();
9538872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mCurrentModule.onPauseAfterSuper();
9548872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
9558872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
9568872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
957b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
958b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        if (requestCode == REQ_CODE_EDIT && resultCode == RESULT_OK) {
959b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling            Uri uri = data.getData();
960b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling            ContentResolver contentResolver = getContentResolver();
961b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling            if (uri == null) {
962b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                // If we don't have a particular uri returned, then we have
963b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                // to refresh all, it is not optimal, but works best so far.
964b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                // Also don't requestLoad() when in secure camera mode.
965b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                if (!mSecureCamera) {
966b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                    mDataAdapter.requestLoad(contentResolver);
967b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                }
968b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling            } else {
969b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                mDataAdapter.refresh(contentResolver, uri);
970b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling            }
971b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        }
972b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling
973b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        if (requestCode == REQ_CODE_DONT_SWITCH_TO_PREVIEW | requestCode == REQ_CODE_EDIT) {
974b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling            mResetToPreviewOnResume = false;
975b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        } else {
976b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling            super.onActivityResult(requestCode, resultCode, data);
977b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        }
978b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    }
979b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling
980b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    @Override
9818872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void onResume() {
982ce2b94917098f211cacaaebaa0f6b40021d3e3faAngus Kong        // TODO: Handle this in OrientationManager.
983a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        // Auto-rotate off
9843cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu        if (Settings.System.getInt(getContentResolver(),
985a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                Settings.System.ACCELEROMETER_ROTATION, 0) == 0) {
9863cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
9873cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu            mAutoRotateScreen = false;
9883cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu        } else {
9893cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
9903cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu            mAutoRotateScreen = true;
9913cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu        }
9928872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mOrientationListener.enable();
9938872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mCurrentModule.onResumeBeforeSuper();
9948872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        super.onResume();
9958872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mCurrentModule.onResumeAfterSuper();
9968872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
9976798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong        setSwipingEnabled(true);
998b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling
999b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        if (mResetToPreviewOnResume) {
1000b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling            // Go to the preview on resume.
1001b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling            mFilmStripView.getController().goToFirstItem();
1002b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        }
1003b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        // Default is showing the preview, unless disabled by explicitly
1004b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        // starting an activity we want to return from to the filmstrip rather
1005b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        // than the preview.
1006b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        mResetToPreviewOnResume = true;
10076798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong    }
10086798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong
10096798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong    @Override
10106798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong    public void onStart() {
10116798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong        super.onStart();
10127e374eb0a450ed2689b556ab42a0a88c8f74df2eAngus Kong        bindMediaSaveService();
1013f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling        mPanoramaViewHelper.onStart();
1014f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling    }
1015f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling
1016f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling    @Override
1017f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling    protected void onStop() {
1018f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling        super.onStop();
1019f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling        mPanoramaViewHelper.onStop();
10207e374eb0a450ed2689b556ab42a0a88c8f74df2eAngus Kong        unbindMediaSaveService();
102108650187c1f1a2d1ef7f754be0f479a29958daaaMichael Kolb    }
102208650187c1f1a2d1ef7f754be0f479a29958daaaMichael Kolb
10238872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
10246432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void onDestroy() {
1025a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        if (mSecureCamera) {
1026a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            unregisterReceiver(mScreenOffReceiver);
1027a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        }
10286432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        super.onDestroy();
10298872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10308872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10318872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
10326432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void onConfigurationChanged(Configuration config) {
10336432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        super.onConfigurationChanged(config);
10346432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mCurrentModule.onConfigurationChanged(config);
10358872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10368872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10378872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
10386432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public boolean onKeyDown(int keyCode, KeyEvent event) {
1039a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        if (mCurrentModule.onKeyDown(keyCode, event)) {
1040a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            return true;
1041a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        }
10426432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        // Prevent software keyboard or voice search from showing up.
10436432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (keyCode == KeyEvent.KEYCODE_SEARCH
10446432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                || keyCode == KeyEvent.KEYCODE_MENU) {
1045a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            if (event.isLongPress()) {
1046a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                return true;
1047a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            }
10486432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
10496432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
10506432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return super.onKeyDown(keyCode, event);
10518872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10528872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10538872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
10546432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public boolean onKeyUp(int keyCode, KeyEvent event) {
1055a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        if (mCurrentModule.onKeyUp(keyCode, event)) {
1056a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            return true;
1057a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        }
10586432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return super.onKeyUp(keyCode, event);
10598872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10608872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10615f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger    @Override
10625f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger    public void onBackPressed() {
10635f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger        if (!mFilmStripView.inCameraFullscreen()) {
10645f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger            mFilmStripView.getController().goToFirstItem();
10655f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger        } else if (!mCurrentModule.onBackPressed()) {
10665f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger            super.onBackPressed();
10675f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger        }
10685f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger    }
10695f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger
10706432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public boolean isAutoRotateScreen() {
10716432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return mAutoRotateScreen;
10728872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10738872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10746432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    protected void updateStorageSpace() {
10756432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mStorageSpace = Storage.getAvailableSpace();
10768872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10778872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10786432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    protected long getStorageSpace() {
10796432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return mStorageSpace;
10808872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10818872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10826432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    protected void updateStorageSpaceAndHint() {
10836432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        updateStorageSpace();
10846432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        updateStorageHint(mStorageSpace);
10858872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10868872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10876432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    protected void updateStorageHint() {
10886432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        updateStorageHint(mStorageSpace);
10898872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10908872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10916432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    protected boolean updateStorageHintOnResume() {
10926432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return true;
10936432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
10946432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
10956432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    protected void updateStorageHint(long storageSpace) {
10966432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        String message = null;
10976432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (storageSpace == Storage.UNAVAILABLE) {
10986432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            message = getString(R.string.no_storage);
10996432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else if (storageSpace == Storage.PREPARING) {
11006432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            message = getString(R.string.preparing_sd);
11016432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else if (storageSpace == Storage.UNKNOWN_SIZE) {
11026432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            message = getString(R.string.access_sd_fail);
11036432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else if (storageSpace <= Storage.LOW_STORAGE_THRESHOLD) {
11046432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            message = getString(R.string.spaceIsLow_content);
11058872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
11066432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
11076432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (message != null) {
11086432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            if (mStorageHint == null) {
11096432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                mStorageHint = OnScreenHint.makeText(this, message);
11106432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            } else {
11116432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                mStorageHint.setText(message);
11126432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            }
11136432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mStorageHint.show();
11146432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else if (mStorageHint != null) {
11156432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mStorageHint.cancel();
11166432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mStorageHint = null;
11178872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
11188872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
11198872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
11206432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    protected void setResultEx(int resultCode) {
11216432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mResultCodeForTesting = resultCode;
11226432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        setResult(resultCode);
11238872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
11248872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
11256432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    protected void setResultEx(int resultCode, Intent data) {
11266432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mResultCodeForTesting = resultCode;
11276432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mResultDataForTesting = data;
11286432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        setResult(resultCode, data);
11298872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
11308872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
11316432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public int getResultCode() {
11326432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return mResultCodeForTesting;
11338872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
11348872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
11356432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public Intent getResultData() {
11366432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return mResultDataForTesting;
11378872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
11388872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
11396432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public boolean isSecureCamera() {
11406432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return mSecureCamera;
11418872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
11428872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
11438872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
1144ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void onModuleSelected(int moduleIndex) {
1145a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        if (mCurrentModuleIndex == moduleIndex) {
1146a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            return;
1147a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        }
11486432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
11496432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        CameraHolder.instance().keep();
11506432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        closeModule(mCurrentModule);
11512654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        setModuleFromIndex(moduleIndex);
11522654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling
11532654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        openModule(mCurrentModule);
11542654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        mCurrentModule.onOrientationChanged(mLastRawOrientation);
11552654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        if (mMediaSaveService != null) {
11562654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling            mCurrentModule.onMediaSaveServiceConnected(mMediaSaveService);
11572654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        }
11582654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling
11592654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        // Store the module index so we can use it the next time the Camera
11602654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        // starts up.
11612654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
11622654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        prefs.edit().putInt(PREF_STARTUP_MODULE_INDEX, moduleIndex).apply();
11632654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling    }
11642654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling
11652654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling    /**
1166a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     * Sets the mCurrentModuleIndex, creates a new module instance for the given
1167a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     * index an sets it as mCurrentModule.
11682654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling     */
11692654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling    private void setModuleFromIndex(int moduleIndex) {
11702654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        mCurrentModuleIndex = moduleIndex;
11712654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        switch (moduleIndex) {
117215125661ad968cf4d40989a9bc88d11189beb0b3Sascha Haeberling            case ModuleSwitcher.VIDEO_MODULE_INDEX:
11736432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                mCurrentModule = new VideoModule();
11746432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                break;
1175ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
117615125661ad968cf4d40989a9bc88d11189beb0b3Sascha Haeberling            case ModuleSwitcher.PHOTO_MODULE_INDEX:
11776432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                mCurrentModule = new PhotoModule();
11786432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                break;
1179ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
118015125661ad968cf4d40989a9bc88d11189beb0b3Sascha Haeberling            case ModuleSwitcher.WIDE_ANGLE_PANO_MODULE_INDEX:
1181ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                mCurrentModule = new WideAnglePanoramaModule();
1182ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                break;
1183ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
118415125661ad968cf4d40989a9bc88d11189beb0b3Sascha Haeberling            case ModuleSwitcher.LIGHTCYCLE_MODULE_INDEX:
11858e963a5a6016d246184ed65906f9d103e92b17e2Sascha Haeberling                mCurrentModule = PhotoSphereHelper.createPanoramaModule();
11866432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                break;
1187a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunk            case ModuleSwitcher.GCAM_MODULE_INDEX:
1188a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunk                // Force immediate release of Camera instance
1189a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunk                CameraHolder.instance().strongRelease();
1190a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunk                mCurrentModule = GcamHelper.createGcamModule();
1191a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunk                break;
11922654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling            default:
119315125661ad968cf4d40989a9bc88d11189beb0b3Sascha Haeberling                // Fall back to photo mode.
119415125661ad968cf4d40989a9bc88d11189beb0b3Sascha Haeberling                mCurrentModule = new PhotoModule();
119515125661ad968cf4d40989a9bc88d11189beb0b3Sascha Haeberling                mCurrentModuleIndex = ModuleSwitcher.PHOTO_MODULE_INDEX;
11962654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling                break;
11976432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
11988872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
11998872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
120088ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling    /**
120188ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling     * Launches an ACTION_EDIT intent for the given local data item.
120288ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling     */
120388ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling    public void launchEditor(LocalData data) {
120488ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling        Intent intent = new Intent(Intent.ACTION_EDIT)
120588ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling                .setDataAndType(data.getContentUri(), data.getMimeType())
120688ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling                .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
1207b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        startActivityForResult(Intent.createChooser(intent, null), REQ_CODE_EDIT);
120888ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling    }
120988ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling
1210a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling    /**
1211a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     * Launch the tiny planet editor.
1212a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     *
1213a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     * @param data the data must be a 360 degree stereographically mapped
1214a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     *            panoramic image. It will not be modified, instead a new item
1215a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     *            with the result will be added to the filmstrip.
1216a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     */
1217a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling    public void launchTinyPlanetEditor(LocalData data) {
1218a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        TinyPlanetFragment fragment = new TinyPlanetFragment();
1219a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        Bundle bundle = new Bundle();
1220a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        bundle.putString(TinyPlanetFragment.ARGUMENT_URI, data.getContentUri().toString());
1221a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        bundle.putString(TinyPlanetFragment.ARGUMENT_TITLE, data.getTitle());
1222a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        fragment.setArguments(bundle);
1223a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        fragment.show(getFragmentManager(), "tiny_planet");
1224a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling    }
1225a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling
12266432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private void openModule(CameraModule module) {
1227653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        module.init(this, mCameraModuleRootView);
12286432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        module.onResumeBeforeSuper();
12296432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        module.onResumeAfterSuper();
12308872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
12318872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
12326432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private void closeModule(CameraModule module) {
12336432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        module.onPauseBeforeSuper();
12346432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        module.onPauseAfterSuper();
1235653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        ((ViewGroup) mCameraModuleRootView).removeAllViews();
1236653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong    }
1237653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong
1238742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    private void performDeletion() {
1239742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        if (!mPendingDeletion) {
1240742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            return;
1241742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        }
1242742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        hideUndoDeletionBar(false);
1243742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        mDataAdapter.executeDeletion(CameraActivity.this);
1244742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    }
1245742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu
1246742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    public void showUndoDeletionBar() {
1247742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        if (mPendingDeletion) {
1248742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            performDeletion();
1249742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        }
1250742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        Log.v(TAG, "showing undo bar");
1251742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        mPendingDeletion = true;
1252653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        if (mUndoDeletionBar == null) {
1253653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong            ViewGroup v = (ViewGroup) getLayoutInflater().inflate(
1254653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong                    R.layout.undo_bar, mAboveFilmstripControlLayout, true);
1255653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong            mUndoDeletionBar = (ViewGroup) v.findViewById(R.id.camera_undo_deletion_bar);
1256653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong            View button = mUndoDeletionBar.findViewById(R.id.camera_undo_deletion_button);
1257653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong            button.setOnClickListener(new View.OnClickListener() {
1258653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong                @Override
1259653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong                public void onClick(View view) {
1260653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong                    mDataAdapter.undoDataRemoval();
1261742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                    hideUndoDeletionBar(true);
1262742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                }
1263742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            });
1264742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // Setting undo bar clickable to avoid touch events going through
1265742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // the bar to the buttons (eg. edit button, etc) underneath the bar.
1266742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            mUndoDeletionBar.setClickable(true);
1267742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // When there is user interaction going on with the undo button, we
1268742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // do not want to hide the undo bar.
1269742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            button.setOnTouchListener(new View.OnTouchListener() {
1270742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                @Override
1271742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                public boolean onTouch(View v, MotionEvent event) {
1272742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                    if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
1273742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                        mIsUndoingDeletion = true;
1274742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                    } else if (event.getActionMasked() == MotionEvent.ACTION_UP) {
1275742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                        mIsUndoingDeletion =false;
1276742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                    }
1277742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                    return false;
1278653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong                }
1279653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong            });
1280653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        }
1281653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        mUndoDeletionBar.setAlpha(0f);
1282653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        mUndoDeletionBar.setVisibility(View.VISIBLE);
1283742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        mUndoDeletionBar.animate().setDuration(200).alpha(1f).setListener(null).start();
1284653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong    }
1285653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong
1286742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    private void hideUndoDeletionBar(boolean withAnimation) {
1287653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        Log.v(TAG, "Hiding undo deletion bar");
1288742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        mPendingDeletion = false;
1289653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        if (mUndoDeletionBar != null) {
1290742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            if (withAnimation) {
1291742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                mUndoDeletionBar.animate()
1292742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                        .setDuration(200)
1293742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                        .alpha(0f)
1294742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                        .setListener(new Animator.AnimatorListener() {
1295742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            @Override
1296742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            public void onAnimationStart(Animator animation) {
1297742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                                // Do nothing.
1298742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            }
1299742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu
1300742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            @Override
1301742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            public void onAnimationEnd(Animator animation) {
1302742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                                mUndoDeletionBar.setVisibility(View.GONE);
1303742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            }
1304742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu
1305742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            @Override
1306742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            public void onAnimationCancel(Animator animation) {
1307742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                                // Do nothing.
1308742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            }
1309742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu
1310742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            @Override
1311742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            public void onAnimationRepeat(Animator animation) {
1312742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                                // Do nothing.
1313742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            }
1314742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                        })
1315742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                        .start();
1316742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            } else {
1317742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                mUndoDeletionBar.setVisibility(View.GONE);
1318742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            }
1319653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        }
13208872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
13218872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
13228872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
13236432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void onShowSwitcherPopup() {
13246432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
13256432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
1326a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong    /**
1327a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     * Enable/disable swipe-to-filmstrip. Will always disable swipe if in
1328a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     * capture intent.
1329a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong     *
1330a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong     * @param enable {@code true} to enable swipe.
1331a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong     */
13326432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void setSwipingEnabled(boolean enable) {
1333a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong        if (isCaptureIntent()) {
1334a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong            mCameraPreviewData.lockPreview(true);
1335a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong        } else {
1336a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong            mCameraPreviewData.lockPreview(!enable);
1337a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong        }
13388872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
13398872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
13408872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    // Accessor methods for getting latency times used in performance testing
13418872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public long getAutoFocusTime() {
13428872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return (mCurrentModule instanceof PhotoModule) ?
13438872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                ((PhotoModule) mCurrentModule).mAutoFocusTime : -1;
13448872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
13458872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
13468872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public long getShutterLag() {
13478872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return (mCurrentModule instanceof PhotoModule) ?
13488872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                ((PhotoModule) mCurrentModule).mShutterLag : -1;
13498872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
13508872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
13518872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public long getShutterToPictureDisplayedTime() {
13528872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return (mCurrentModule instanceof PhotoModule) ?
13538872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                ((PhotoModule) mCurrentModule).mShutterToPictureDisplayedTime : -1;
13548872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
13558872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
13568872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public long getPictureDisplayedToJpegCallbackTime() {
13578872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return (mCurrentModule instanceof PhotoModule) ?
13588872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                ((PhotoModule) mCurrentModule).mPictureDisplayedToJpegCallbackTime : -1;
13598872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
13608872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
13618872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public long getJpegCallbackFinishTime() {
13628872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return (mCurrentModule instanceof PhotoModule) ?
13638872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                ((PhotoModule) mCurrentModule).mJpegCallbackFinishTime : -1;
13648872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
13658872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
13668872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public long getCaptureStartTime() {
13678872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return (mCurrentModule instanceof PhotoModule) ?
13688872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                ((PhotoModule) mCurrentModule).mCaptureStartTime : -1;
13698872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
13708872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
13718872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public boolean isRecording() {
13728872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return (mCurrentModule instanceof VideoModule) ?
13738872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                ((VideoModule) mCurrentModule).isRecording() : false;
13748872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
13754f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong
13764f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong    public CameraOpenErrorCallback getCameraOpenErrorCallback() {
13774f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong        return mCameraOpenErrorCallback;
13784f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong    }
13798872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb}
1380