CameraActivity.java revision a9d66bdab247626b31dc182c4d62520b3abffdbd
18872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb/*
28872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * Copyright (C) 2012 The Android Open Source Project
38872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb *
48872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * Licensed under the Apache License, Version 2.0 (the "License");
58872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * you may not use this file except in compliance with the License.
68872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * You may obtain a copy of the License at
78872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb *
88872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb *      http://www.apache.org/licenses/LICENSE-2.0
98872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb *
108872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * Unless required by applicable law or agreed to in writing, software
118872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * distributed under the License is distributed on an "AS IS" BASIS,
128872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * See the License for the specific language governing permissions and
148872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * limitations under the License.
158872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb */
168872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
178872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbpackage com.android.camera;
188872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
19742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liuimport android.animation.Animator;
20fa9e2cc9ccbcd746f5765cb7a0afebcdb60e2973ztenghuiimport android.app.ActionBar;
216432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.app.Activity;
22b84b9738c855a525dc1944165983cc3c342ce446Doris Liuimport android.content.BroadcastReceiver;
2386d36313d88fe96354f2cdd4f378e5ff8397c458Angus Kongimport android.content.ComponentName;
246432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.content.ContentResolver;
2508650187c1f1a2d1ef7f754be0f479a29958daaaMichael Kolbimport android.content.Context;
268872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.content.Intent;
27b84b9738c855a525dc1944165983cc3c342ce446Doris Liuimport android.content.IntentFilter;
2886d36313d88fe96354f2cdd4f378e5ff8397c458Angus Kongimport android.content.ServiceConnection;
292654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberlingimport android.content.SharedPreferences;
303cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liuimport android.content.pm.ActivityInfo;
318872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.content.res.Configuration;
326432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.graphics.drawable.ColorDrawable;
336432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.net.Uri;
346f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberlingimport android.os.AsyncTask;
358872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.os.Bundle;
366432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.os.Handler;
3786d36313d88fe96354f2cdd4f378e5ff8397c458Angus Kongimport android.os.IBinder;
382654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberlingimport android.preference.PreferenceManager;
392a7f44cac888de5683d05bef5708f846ee950f43Doris Liuimport android.provider.MediaStore;
403cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liuimport android.provider.Settings;
4137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberlingimport android.util.Log;
428872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.view.KeyEvent;
436432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.view.LayoutInflater;
440353ca2e048543bd6e233b4c2110a1df1070cd3fztenghuiimport android.view.Menu;
450353ca2e048543bd6e233b4c2110a1df1070cd3fztenghuiimport android.view.MenuInflater;
460353ca2e048543bd6e233b4c2110a1df1070cd3fztenghuiimport android.view.MenuItem;
47742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liuimport android.view.MotionEvent;
488872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.view.OrientationEventListener;
498872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.view.View;
506432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.view.ViewGroup;
5108650187c1f1a2d1ef7f754be0f479a29958daaaMichael Kolbimport android.view.Window;
5208650187c1f1a2d1ef7f754be0f479a29958daaaMichael Kolbimport android.view.WindowManager;
53653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kongimport android.widget.FrameLayout;
546432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport android.widget.ImageView;
5537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberlingimport android.widget.ProgressBar;
56cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiwareimport android.widget.ShareActionProvider;
578872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
58ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport com.android.camera.app.AppManagerFactory;
59ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport com.android.camera.app.PanoramaStitchingManager;
606432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport com.android.camera.data.CameraDataAdapter;
618e5e4eedb25a4589342660b928935acca4375fc7Angus Kongimport com.android.camera.data.CameraPreviewData;
628e5e4eedb25a4589342660b928935acca4375fc7Angus Kongimport com.android.camera.data.FixedFirstDataAdapter;
638e5e4eedb25a4589342660b928935acca4375fc7Angus Kongimport com.android.camera.data.FixedLastDataAdapter;
646432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport com.android.camera.data.LocalData;
658e5e4eedb25a4589342660b928935acca4375fc7Angus Kongimport com.android.camera.data.LocalDataAdapter;
666f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberlingimport com.android.camera.data.MediaDetails;
67bd26069d391830856c57c2141cd2efbc8423d871Angus Kongimport com.android.camera.data.SimpleViewData;
68a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberlingimport com.android.camera.tinyplanet.TinyPlanetFragment;
69ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongimport com.android.camera.ui.ModuleSwitcher;
706f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberlingimport com.android.camera.ui.DetailsDialog;
716432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liuimport com.android.camera.ui.FilmStripView;
7288ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberlingimport com.android.camera.util.ApiHelper;
73b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kongimport com.android.camera.util.CameraUtil;
74a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunkimport com.android.camera.util.GcamHelper;
7537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberlingimport com.android.camera.util.PhotoSphereHelper;
7688ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberlingimport com.android.camera.util.PhotoSphereHelper.PanoramaViewHelper;
778e963a5a6016d246184ed65906f9d103e92b17e2Sascha Haeberlingimport com.android.camera2.R;
788872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
794f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kongimport static com.android.camera.CameraManager.CameraOpenErrorCallback;
804f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong
816432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liupublic class CameraActivity extends Activity
82a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        implements ModuleSwitcher.ModuleSwitchListener {
836432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
846432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private static final String TAG = "CAM_Activity";
856432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
864ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling    /**
874ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling     * The visibility flags to use to switch the system in either lights-out
884ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling     * mode (pre-K) or hideybar mode (K and up).
894ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling     */
904ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling    private static final int IMMERSIVE_FLAGS = getImmersiveFlags();
914ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling
926432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private static final String INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE =
936432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            "android.media.action.STILL_IMAGE_CAMERA_SECURE";
946432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public static final String ACTION_IMAGE_CAPTURE_SECURE =
956432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            "android.media.action.IMAGE_CAPTURE_SECURE";
966b9203214d828d72758943aca55adceab684a862ztenghui    public static final String ACTION_TRIM_VIDEO =
976b9203214d828d72758943aca55adceab684a862ztenghui            "com.android.camera.action.TRIM";
986b9203214d828d72758943aca55adceab684a862ztenghui    public static final String MEDIA_ITEM_PATH = "media-item-path";
996432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
1002654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling    private static final String PREF_STARTUP_MODULE_INDEX = "camera.startup_module";
1012654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling
1026432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    // The intent extra for camera from secure lock screen. True if the gallery
1036432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    // should only show newly captured pictures. sSecureAlbumId does not
1046432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    // increment. This is used when switching between camera, camcorder, and
1056432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    // panorama. If the extra is not set, it is in the normal camera mode.
1066432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public static final String SECURE_CAMERA_EXTRA = "secure_camera";
1076432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
108b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    /**
109b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling     * Request code from an activity we started that indicated that we do not
110b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling     * want to reset the view to the preview in onResume.
111b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling     */
112b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    public static final int REQ_CODE_DONT_SWITCH_TO_PREVIEW = 142;
113b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling
114b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    /** Request code for external image editor activities. */
115b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    private static final int REQ_CODE_EDIT = 1;
116b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling
117b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling
118b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    /** Whether onResume should reset the view to the preview. */
119b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    private boolean mResetToPreviewOnResume = true;
120b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling
1210353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    // Supported operations at FilmStripView. Different data has different
1220353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    // set of supported operations.
1230353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private static final int SUPPORT_DELETE = 1 << 0;
1240353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private static final int SUPPORT_ROTATE = 1 << 1;
1250353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private static final int SUPPORT_INFO = 1 << 2;
1260353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private static final int SUPPORT_CROP = 1 << 3;
1270353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private static final int SUPPORT_SETAS = 1 << 4;
1280353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private static final int SUPPORT_EDIT = 1 << 5;
1290353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private static final int SUPPORT_TRIM = 1 << 6;
130cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private static final int SUPPORT_SHARE = 1 << 7;
131cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private static final int SUPPORT_SHARE_PANORAMA360 = 1 << 8;
132cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private static final int SUPPORT_SHOW_ON_MAP = 1 << 9;
1330353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private static final int SUPPORT_ALL = 0xffffffff;
1340353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui
1356f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling    /** This data adapter is used by FilmStripView. */
1368e5e4eedb25a4589342660b928935acca4375fc7Angus Kong    private LocalDataAdapter mDataAdapter;
1378e5e4eedb25a4589342660b928935acca4375fc7Angus Kong    /** This data adapter represents the real local camera data. */
1388e5e4eedb25a4589342660b928935acca4375fc7Angus Kong    private LocalDataAdapter mWrappedDataAdapter;
1398e5e4eedb25a4589342660b928935acca4375fc7Angus Kong
1406798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong    private PanoramaStitchingManager mPanoramaManager;
1418872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private int mCurrentModuleIndex;
1426432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private CameraModule mCurrentModule;
143653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong    private FrameLayout mAboveFilmstripControlLayout;
144653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong    private View mCameraModuleRootView;
1456432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private FilmStripView mFilmStripView;
14637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    private ProgressBar mBottomProgress;
14737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    private View mPanoStitchingPanel;
1486432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private int mResultCodeForTesting;
1496432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private Intent mResultDataForTesting;
1506432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private OnScreenHint mStorageHint;
1516432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private long mStorageSpace = Storage.LOW_STORAGE_THRESHOLD;
1523cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu    private boolean mAutoRotateScreen;
1536432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private boolean mSecureCamera;
1546a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    // This is a hack to speed up the start of SecureCamera.
1556a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    private static boolean sFirstStartAfterScreenOn = true;
1566432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private int mLastRawOrientation;
1578872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private MyOrientationEventListener mOrientationListener;
1586432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private Handler mMainHandler;
159f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling    private PanoramaViewHelper mPanoramaViewHelper;
1608e5e4eedb25a4589342660b928935acca4375fc7Angus Kong    private CameraPreviewData mCameraPreviewData;
161fa9e2cc9ccbcd746f5765cb7a0afebcdb60e2973ztenghui    private ActionBar mActionBar;
1620353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private Menu mActionBarMenu;
163653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong    private ViewGroup mUndoDeletionBar;
164742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    private boolean mIsUndoingDeletion = false;
1653cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu
166cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private ShareActionProvider mStandardShareActionProvider;
167cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private Intent mStandardShareIntent;
168cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private ShareActionProvider mPanoramaShareActionProvider;
169cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private Intent mPanoramaShareIntent;
170cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware
1715199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling    private final int DEFAULT_SYSTEM_UI_VISIBILITY = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
1725199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
173742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    private boolean mPendingDeletion = false;
1745199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling
17505804751ba07c8abcf422f57467d0ed3de95576cztenghui    private Intent mVideoShareIntent;
17605804751ba07c8abcf422f57467d0ed3de95576cztenghui    private Intent mImageShareIntent;
17705804751ba07c8abcf422f57467d0ed3de95576cztenghui
1788872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private class MyOrientationEventListener
179a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            extends OrientationEventListener {
1808872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        public MyOrientationEventListener(Context context) {
1818872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            super(context);
1828872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
1838872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
1848872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        @Override
1858872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        public void onOrientationChanged(int orientation) {
1868872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // We keep the last known orientation. So if the user first orient
1878872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // the camera then point the camera to floor or sky, we still have
1888872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            // the correct orientation.
189a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            if (orientation == ORIENTATION_UNKNOWN) {
190a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                return;
191a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            }
1928872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            mLastRawOrientation = orientation;
1938872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            mCurrentModule.onOrientationChanged(orientation);
1948872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
1958872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
1968872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
1976432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private MediaSaveService mMediaSaveService;
1986432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private ServiceConnection mConnection = new ServiceConnection() {
199a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        @Override
200a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        public void onServiceConnected(ComponentName className, IBinder b) {
201a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            mMediaSaveService = ((MediaSaveService.LocalBinder) b).getService();
202a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            mCurrentModule.onMediaSaveServiceConnected(mMediaSaveService);
203a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        }
204a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling
205a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        @Override
206a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        public void onServiceDisconnected(ComponentName className) {
207a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            if (mMediaSaveService != null) {
208a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                mMediaSaveService.setListener(null);
209a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                mMediaSaveService = null;
2108872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            }
211a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        }
212a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling    };
213e319aeabdc825f221df5af8a6ec080c6f5d41a94John Reck
2144f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong    private CameraOpenErrorCallback mCameraOpenErrorCallback =
2154f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong            new CameraOpenErrorCallback() {
2164f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                @Override
2174f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                public void onCameraDisabled(int cameraId) {
2184f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                    CameraUtil.showErrorAndFinish(CameraActivity.this,
2194f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                            R.string.camera_disabled);
2204f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                }
2214f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong
2224f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                @Override
2234f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                public void onDeviceOpenFailure(int cameraId) {
2244f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                    CameraUtil.showErrorAndFinish(CameraActivity.this,
2254f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                            R.string.cannot_connect_camera);
2264f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                }
2274f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong
2284f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                @Override
2294f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                public void onReconnectionFailure(CameraManager mgr) {
2304f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                    CameraUtil.showErrorAndFinish(CameraActivity.this,
2314f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                            R.string.cannot_connect_camera);
2324f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong                }
2334f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong            };
2344f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong
235b84b9738c855a525dc1944165983cc3c342ce446Doris Liu    // close activity when screen turns off
236b84b9738c855a525dc1944165983cc3c342ce446Doris Liu    private BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() {
237b84b9738c855a525dc1944165983cc3c342ce446Doris Liu        @Override
238b84b9738c855a525dc1944165983cc3c342ce446Doris Liu        public void onReceive(Context context, Intent intent) {
239b84b9738c855a525dc1944165983cc3c342ce446Doris Liu            finish();
240b84b9738c855a525dc1944165983cc3c342ce446Doris Liu        }
241b84b9738c855a525dc1944165983cc3c342ce446Doris Liu    };
242b84b9738c855a525dc1944165983cc3c342ce446Doris Liu
2436a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    private static BroadcastReceiver sScreenOffReceiver;
244a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling
2456a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    private static class ScreenOffReceiver extends BroadcastReceiver {
2466a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong        @Override
2476a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong        public void onReceive(Context context, Intent intent) {
2486a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong            sFirstStartAfterScreenOn = true;
2496a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong        }
2506a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    }
2516a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong
2524ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling    private static int getImmersiveFlags() {
253638e6f06c877d90b907f66ea9c22b3c6b73c7384Sascha Haeberling        if (ApiHelper.HAS_HIDEYBARS) {
2544ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling            return View.SYSTEM_UI_FLAG_IMMERSIVE
2554ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling                    | View.SYSTEM_UI_FLAG_TRANSPARENT_STATUS
2564ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling                    | View.SYSTEM_UI_FLAG_TRANSPARENT_NAVIGATION
2574ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
2584ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling                    | View.SYSTEM_UI_FLAG_FULLSCREEN;
2594ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling        } else {
2604ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling            // Pre-KitKat we use lights-out mode.
2614ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling            return View.SYSTEM_UI_FLAG_LOW_PROFILE;
2624ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling        }
2634ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling    }
2644ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling
2656a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    public static boolean isFirstStartAfterScreenOn() {
2666a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong        return sFirstStartAfterScreenOn;
2676a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    }
2686a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong
2696a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    public static void resetFirstStartAfterScreenOn() {
2706a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong        sFirstStartAfterScreenOn = false;
2716a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong    }
2726a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong
27337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    private FilmStripView.Listener mFilmStripListener =
27437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            new FilmStripView.Listener() {
27537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                @Override
27637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                public void onDataPromoted(int dataID) {
27737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    removeData(dataID);
27837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                }
279e319aeabdc825f221df5af8a6ec080c6f5d41a94John Reck
28037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                @Override
28137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                public void onDataDemoted(int dataID) {
28237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    removeData(dataID);
28337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                }
284e319aeabdc825f221df5af8a6ec080c6f5d41a94John Reck
28537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                @Override
28637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                public void onDataFullScreenChange(int dataID, boolean full) {
2878566dd777cd219254c945240a31ac97de28792a2ztenghui                    boolean isCameraID = isCameraPreview(dataID);
2887b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                    if (!isCameraID) {
2897b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                        setActionBarVisibilityAndLightsOut(full);
290fa9e2cc9ccbcd746f5765cb7a0afebcdb60e2973ztenghui                    }
29137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                }
29237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling
2938566dd777cd219254c945240a31ac97de28792a2ztenghui                /**
2948566dd777cd219254c945240a31ac97de28792a2ztenghui                 * Check if the local data corresponding to dataID is the camera
2958566dd777cd219254c945240a31ac97de28792a2ztenghui                 * preview.
2968566dd777cd219254c945240a31ac97de28792a2ztenghui                 *
2978566dd777cd219254c945240a31ac97de28792a2ztenghui                 * @param dataID the ID of the local data
2988566dd777cd219254c945240a31ac97de28792a2ztenghui                 * @return true if the local data is not null and it is the
2998566dd777cd219254c945240a31ac97de28792a2ztenghui                 *         camera preview.
3008566dd777cd219254c945240a31ac97de28792a2ztenghui                 */
3018566dd777cd219254c945240a31ac97de28792a2ztenghui                private boolean isCameraPreview(int dataID) {
3028566dd777cd219254c945240a31ac97de28792a2ztenghui                    LocalData localData = mDataAdapter.getLocalData(dataID);
3038566dd777cd219254c945240a31ac97de28792a2ztenghui                    if (localData == null) {
3048566dd777cd219254c945240a31ac97de28792a2ztenghui                        Log.w(TAG, "Current data ID not found.");
3058566dd777cd219254c945240a31ac97de28792a2ztenghui                        return false;
3068566dd777cd219254c945240a31ac97de28792a2ztenghui                    }
3078566dd777cd219254c945240a31ac97de28792a2ztenghui                    return localData.getLocalDataType() == LocalData.LOCAL_CAMERA_PREVIEW;
3088566dd777cd219254c945240a31ac97de28792a2ztenghui                }
3098566dd777cd219254c945240a31ac97de28792a2ztenghui
31037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                @Override
31133035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                public void onCurrentDataChanged(final int dataID, final boolean current) {
31233035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                    runOnUiThread(new Runnable() {
31333035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                        @Override
31433035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                        public void run() {
3157b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                            LocalData currentData = mDataAdapter.getLocalData(dataID);
3167b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                            if (currentData == null) {
3177b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                Log.w(TAG, "Current data ID not found.");
3187b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                hidePanoStitchingProgress();
3197b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                return;
3207b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                            }
3217b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                            boolean isCameraID = currentData.getLocalDataType() ==
3227b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                    LocalData.LOCAL_CAMERA_PREVIEW;
32333035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                            if (!current) {
3247b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                if (isCameraID) {
3257b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                    mCurrentModule.onPreviewFocusChanged(false);
3267b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                    setActionBarVisibilityAndLightsOut(false);
3277b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                }
32833035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                hidePanoStitchingProgress();
32933035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                            } else {
3307b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                if (isCameraID) {
3317b265a6b2f55c6ae7afc30e63ba324c4084a5d8eztenghui                                    mCurrentModule.onPreviewFocusChanged(true);
332a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                                    // Don't show the action bar in Camera
333a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                                    // preview.
3345199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling                                    setActionBarVisibilityAndLightsOut(true);
335742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                                    if (mPendingDeletion) {
336742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                                        performDeletion();
337742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                                    }
3381ef76d4cbd73c02cb8d02cf4cde3f4cee81548d6Alan Newberger                                } else {
3391ef76d4cbd73c02cb8d02cf4cde3f4cee81548d6Alan Newberger                                    updateActionBarMenu(dataID);
3401ef76d4cbd73c02cb8d02cf4cde3f4cee81548d6Alan Newberger                                }
34133035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware
34233035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                Uri contentUri = currentData.getContentUri();
34333035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                if (contentUri == null) {
34433035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                    hidePanoStitchingProgress();
34533035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                    return;
34633035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                }
34733035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                int panoStitchingProgress = mPanoramaManager.getTaskProgress(
348a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                                        contentUri);
34933035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                if (panoStitchingProgress < 0) {
35033035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                    hidePanoStitchingProgress();
35133035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                    return;
35233035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                }
35333035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                showPanoStitchingProgress();
35433035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                                updateStitchingProgress(panoStitchingProgress);
35533035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                            }
35637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        }
35733035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                    });
35837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                }
359394023fb7e3c8d07d4aeafc30bf4b66ed481ebb7Sascha Haeberling
360394023fb7e3c8d07d4aeafc30bf4b66ed481ebb7Sascha Haeberling                @Override
3618566dd777cd219254c945240a31ac97de28792a2ztenghui                public boolean onToggleActionBarVisibility(int dataID) {
362394023fb7e3c8d07d4aeafc30bf4b66ed481ebb7Sascha Haeberling                    if (mActionBar.isShowing()) {
3635199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling                        setActionBarVisibilityAndLightsOut(true);
3644ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling                        return false;
365394023fb7e3c8d07d4aeafc30bf4b66ed481ebb7Sascha Haeberling                    } else {
3668566dd777cd219254c945240a31ac97de28792a2ztenghui                        // Don't show the action bar if that is the camera preview.
3678566dd777cd219254c945240a31ac97de28792a2ztenghui                        boolean isCameraID = isCameraPreview(dataID);
3688566dd777cd219254c945240a31ac97de28792a2ztenghui                        if (!isCameraID) {
3695199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling                            setActionBarVisibilityAndLightsOut(false);
3704ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling                            return true;
371fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui                        }
3724ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling                        return false;
373394023fb7e3c8d07d4aeafc30bf4b66ed481ebb7Sascha Haeberling                    }
374394023fb7e3c8d07d4aeafc30bf4b66ed481ebb7Sascha Haeberling                }
37537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            };
37637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling
3774ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling    public void gotoGallery() {
3784ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling        mFilmStripView.getController().goToNextItem();
3794ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling    }
3804ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling
3815199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling    /**
3825199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling     * If enabled, this hides the action bar and switches the system UI to
3835199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling     * lights-out mode.
3845199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling     */
3855199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling    private void setActionBarVisibilityAndLightsOut(boolean enabled) {
3864ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling        int visibility = DEFAULT_SYSTEM_UI_VISIBILITY | (enabled ? IMMERSIVE_FLAGS
3874ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling                : View.SYSTEM_UI_FLAG_VISIBLE);
3884ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling        mAboveFilmstripControlLayout
3894ed20592482d2ab2f3f48ee72d5b1c06bf009034Sascha Haeberling                .setSystemUiVisibility(visibility);
3905199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling        if (enabled) {
3915199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling            mActionBar.hide();
3925199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling        } else {
3935199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling            mActionBar.show();
3945199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling        }
3955199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling    }
3965199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling
39737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    private void hidePanoStitchingProgress() {
39837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        mPanoStitchingPanel.setVisibility(View.GONE);
39937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    }
40037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling
40137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    private void showPanoStitchingProgress() {
40237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        mPanoStitchingPanel.setVisibility(View.VISIBLE);
40337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    }
40437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling
40537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    private void updateStitchingProgress(int progress) {
40637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        mBottomProgress.setProgress(progress);
40737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling    }
4088872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
409cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private void setStandardShareIntent(Uri contentUri, String mimeType) {
41005804751ba07c8abcf422f57467d0ed3de95576cztenghui        mStandardShareIntent = getShareIntentFromType(mimeType);
41105804751ba07c8abcf422f57467d0ed3de95576cztenghui        if (mStandardShareIntent != null) {
41205804751ba07c8abcf422f57467d0ed3de95576cztenghui            mStandardShareIntent.putExtra(Intent.EXTRA_STREAM, contentUri);
41305804751ba07c8abcf422f57467d0ed3de95576cztenghui            mStandardShareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
41405804751ba07c8abcf422f57467d0ed3de95576cztenghui            if (mStandardShareActionProvider != null) {
41505804751ba07c8abcf422f57467d0ed3de95576cztenghui                mStandardShareActionProvider.setShareIntent(mStandardShareIntent);
41605804751ba07c8abcf422f57467d0ed3de95576cztenghui            }
417cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        }
41805804751ba07c8abcf422f57467d0ed3de95576cztenghui    }
41905804751ba07c8abcf422f57467d0ed3de95576cztenghui
42005804751ba07c8abcf422f57467d0ed3de95576cztenghui    /**
42105804751ba07c8abcf422f57467d0ed3de95576cztenghui     * Get the share intent according to the mimeType
42205804751ba07c8abcf422f57467d0ed3de95576cztenghui     *
42305804751ba07c8abcf422f57467d0ed3de95576cztenghui     * @param mimeType The mimeType of current data.
42405804751ba07c8abcf422f57467d0ed3de95576cztenghui     * @return the video/image's ShareIntent or null if mimeType is invalid.
42505804751ba07c8abcf422f57467d0ed3de95576cztenghui     */
42605804751ba07c8abcf422f57467d0ed3de95576cztenghui    private Intent getShareIntentFromType(String mimeType) {
42705804751ba07c8abcf422f57467d0ed3de95576cztenghui        // Lazily create the intent object.
42805804751ba07c8abcf422f57467d0ed3de95576cztenghui        if (mimeType.startsWith("video/")) {
42905804751ba07c8abcf422f57467d0ed3de95576cztenghui            if (mVideoShareIntent == null) {
43005804751ba07c8abcf422f57467d0ed3de95576cztenghui                mVideoShareIntent = new Intent(Intent.ACTION_SEND);
43105804751ba07c8abcf422f57467d0ed3de95576cztenghui                mVideoShareIntent.setType("video/*");
43205804751ba07c8abcf422f57467d0ed3de95576cztenghui            }
43305804751ba07c8abcf422f57467d0ed3de95576cztenghui            return mVideoShareIntent;
43405804751ba07c8abcf422f57467d0ed3de95576cztenghui        } else if (mimeType.startsWith("image/")) {
43505804751ba07c8abcf422f57467d0ed3de95576cztenghui            if (mImageShareIntent == null) {
43605804751ba07c8abcf422f57467d0ed3de95576cztenghui                mImageShareIntent = new Intent(Intent.ACTION_SEND);
43705804751ba07c8abcf422f57467d0ed3de95576cztenghui                mImageShareIntent.setType("image/*");
43805804751ba07c8abcf422f57467d0ed3de95576cztenghui            }
43905804751ba07c8abcf422f57467d0ed3de95576cztenghui            return mImageShareIntent;
440cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        }
44105804751ba07c8abcf422f57467d0ed3de95576cztenghui        Log.w(TAG, "unsupported mimeType " + mimeType);
44205804751ba07c8abcf422f57467d0ed3de95576cztenghui        return null;
443cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    }
444cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware
445cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    private void setPanoramaShareIntent(Uri contentUri) {
446cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        if (mPanoramaShareIntent == null) {
447cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware            mPanoramaShareIntent = new Intent(Intent.ACTION_SEND);
448cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        }
449cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        mPanoramaShareIntent.setType("application/vnd.google.panorama360+jpg");
450cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        mPanoramaShareIntent.putExtra(Intent.EXTRA_STREAM, contentUri);
451cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        if (mPanoramaShareActionProvider != null) {
452cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware            mPanoramaShareActionProvider.setShareIntent(mPanoramaShareIntent);
453cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        }
454cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware    }
455cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware
4560353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    /**
4570353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui     * According to the data type, make the menu items for supported operations
4580353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui     * visible.
459a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     *
460fae11a165e344a38811770c7d348eda214683edcSascha Haeberling     * @param dataID the data ID of the current item.
4610353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui     */
462fae11a165e344a38811770c7d348eda214683edcSascha Haeberling    private void updateActionBarMenu(int dataID) {
463fae11a165e344a38811770c7d348eda214683edcSascha Haeberling        LocalData currentData = mDataAdapter.getLocalData(dataID);
464fae11a165e344a38811770c7d348eda214683edcSascha Haeberling        int type = currentData.getLocalDataType();
465fae11a165e344a38811770c7d348eda214683edcSascha Haeberling
4660353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        if (mActionBarMenu == null) {
4670353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            return;
4680353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        }
4690353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui
4700353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        int supported = 0;
4710353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        switch (type) {
4720353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case LocalData.LOCAL_IMAGE:
4730353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                supported |= SUPPORT_DELETE | SUPPORT_ROTATE | SUPPORT_INFO
4740353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                        | SUPPORT_CROP | SUPPORT_SETAS | SUPPORT_EDIT
475cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                        | SUPPORT_SHARE | SUPPORT_SHOW_ON_MAP;
4760353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                break;
4770353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case LocalData.LOCAL_VIDEO:
478cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                supported |= SUPPORT_DELETE | SUPPORT_INFO | SUPPORT_TRIM
479cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                        | SUPPORT_SHARE;
4800353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                break;
4810353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case LocalData.LOCAL_PHOTO_SPHERE:
4820353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                supported |= SUPPORT_DELETE | SUPPORT_ROTATE | SUPPORT_INFO
4830353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                        | SUPPORT_CROP | SUPPORT_SETAS | SUPPORT_EDIT
484cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                        | SUPPORT_SHARE | SUPPORT_SHOW_ON_MAP;
485cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                break;
486cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware            case LocalData.LOCAL_360_PHOTO_SPHERE:
487cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                supported |= SUPPORT_DELETE | SUPPORT_ROTATE | SUPPORT_INFO
488cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                        | SUPPORT_CROP | SUPPORT_SETAS | SUPPORT_EDIT
489cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                        | SUPPORT_SHARE | SUPPORT_SHARE_PANORAMA360
4900353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                        | SUPPORT_SHOW_ON_MAP;
4910353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                break;
4920353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            default:
4930353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                break;
4940353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        }
4950353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui
4960353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        setMenuItemVisible(mActionBarMenu, R.id.action_delete,
4970353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                (supported & SUPPORT_DELETE) != 0);
4980353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        setMenuItemVisible(mActionBarMenu, R.id.action_rotate_ccw,
4990353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                (supported & SUPPORT_ROTATE) != 0);
5000353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        setMenuItemVisible(mActionBarMenu, R.id.action_rotate_cw,
5010353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                (supported & SUPPORT_ROTATE) != 0);
502cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        setMenuItemVisible(mActionBarMenu, R.id.action_details,
503cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                (supported & SUPPORT_INFO) != 0);
5040353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        setMenuItemVisible(mActionBarMenu, R.id.action_crop,
5050353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                (supported & SUPPORT_CROP) != 0);
5060353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        setMenuItemVisible(mActionBarMenu, R.id.action_setas,
5070353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                (supported & SUPPORT_SETAS) != 0);
5080353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        setMenuItemVisible(mActionBarMenu, R.id.action_edit,
5090353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                (supported & SUPPORT_EDIT) != 0);
510cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        setMenuItemVisible(mActionBarMenu, R.id.action_trim,
511cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware                (supported & SUPPORT_TRIM) != 0);
512cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware
51333035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        boolean standardShare = (supported & SUPPORT_SHARE) != 0;
51433035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        boolean panoramaShare = (supported & SUPPORT_SHARE_PANORAMA360) != 0;
51533035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        setMenuItemVisible(mActionBarMenu, R.id.action_share, standardShare);
51633035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        setMenuItemVisible(mActionBarMenu, R.id.action_share_panorama, panoramaShare);
51733035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware
51833035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        if (panoramaShare) {
51933035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            // For 360 PhotoSphere, relegate standard share to the overflow menu
52033035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            MenuItem item = mActionBarMenu.findItem(R.id.action_share);
52133035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            if (item != null) {
52233035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                item.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
52333035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                item.setTitle(getResources().getString(R.string.share_as_photo));
52433035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            }
52533035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            // And, promote "share as panorama" to action bar
52633035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            item = mActionBarMenu.findItem(R.id.action_share_panorama);
52733035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            if (item != null) {
52833035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
52933035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            }
530cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware            setPanoramaShareIntent(currentData.getContentUri());
531cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        }
53233035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        if (standardShare) {
53333035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            if (!panoramaShare) {
53433035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                MenuItem item = mActionBarMenu.findItem(R.id.action_share);
53533035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                if (item != null) {
53633035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                    item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
53733035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                    item.setTitle(getResources().getString(R.string.share));
53833035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware                }
53933035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            }
54033035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware            setStandardShareIntent(currentData.getContentUri(), currentData.getMimeType());
54133035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        }
542fae11a165e344a38811770c7d348eda214683edcSascha Haeberling
543fae11a165e344a38811770c7d348eda214683edcSascha Haeberling        boolean itemHasLocation = currentData.getLatLong() != null;
544fae11a165e344a38811770c7d348eda214683edcSascha Haeberling        setMenuItemVisible(mActionBarMenu, R.id.action_show_on_map,
545fae11a165e344a38811770c7d348eda214683edcSascha Haeberling                itemHasLocation && (supported & SUPPORT_SHOW_ON_MAP) != 0);
5460353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    }
5470353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui
5480353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    private void setMenuItemVisible(Menu menu, int itemId, boolean visible) {
5490353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        MenuItem item = menu.findItem(itemId);
5500353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        if (item != null)
5510353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            item.setVisible(visible);
5520353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    }
5530353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui
5546798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong    private ImageTaskManager.TaskListener mStitchingListener =
5556798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong            new ImageTaskManager.TaskListener() {
5566798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong                @Override
55737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                public void onTaskQueued(String filePath, final Uri imageUri) {
55837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    mMainHandler.post(new Runnable() {
55937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        @Override
56037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        public void run() {
56137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            notifyNewMedia(imageUri);
56237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        }
56337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    });
5646798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong                }
5656798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong
5666798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong                @Override
56737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                public void onTaskDone(String filePath, final Uri imageUri) {
56837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    Log.v(TAG, "onTaskDone:" + filePath);
56937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    mMainHandler.post(new Runnable() {
57037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        @Override
57137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        public void run() {
57237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            int doneID = mDataAdapter.findDataByContentUri(imageUri);
57337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            int currentDataId = mFilmStripView.getCurrentId();
57437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling
57537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            if (currentDataId == doneID) {
57637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                                hidePanoStitchingProgress();
57737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                                updateStitchingProgress(0);
57837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            }
57937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling
58037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            mDataAdapter.refresh(getContentResolver(), imageUri);
58137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        }
58237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    });
5836798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong                }
5846798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong
5856798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong                @Override
5866798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong                public void onTaskProgress(
58737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        String filePath, final Uri imageUri, final int progress) {
58837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    mMainHandler.post(new Runnable() {
58937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        @Override
59037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        public void run() {
59137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            int currentDataId = mFilmStripView.getCurrentId();
59237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            if (currentDataId == -1) {
59337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                                return;
59437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            }
59537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            if (imageUri.equals(
59637f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                                    mDataAdapter.getLocalData(currentDataId).getContentUri())) {
59737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                                updateStitchingProgress(progress);
59837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            }
59937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                        }
60037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    });
6016798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong                }
6026798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong            };
6036798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong
6046432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public MediaSaveService getMediaSaveService() {
6056432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return mMediaSaveService;
6068872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
6078872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
6086432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void notifyNewMedia(Uri uri) {
6096432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        ContentResolver cr = getContentResolver();
6106432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        String mimeType = cr.getType(uri);
6116432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (mimeType.startsWith("video/")) {
612b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong            sendBroadcast(new Intent(CameraUtil.ACTION_NEW_VIDEO, uri));
6136432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mDataAdapter.addNewVideo(cr, uri);
6146432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else if (mimeType.startsWith("image/")) {
615b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong            CameraUtil.broadcastNewPicture(this, uri);
6166432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mDataAdapter.addNewPhoto(cr, uri);
61737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        } else if (mimeType.startsWith("application/stitching-preview")) {
61837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            mDataAdapter.addNewPhoto(cr, uri);
6196432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else {
6206432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            android.util.Log.w(TAG, "Unknown new media with MIME type:"
6216432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                    + mimeType + ", uri:" + uri);
6226432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
6238872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
6248872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
6256432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private void removeData(int dataID) {
6266432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mDataAdapter.removeData(CameraActivity.this, dataID);
627742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        if (mDataAdapter.getTotalNumber() > 1) {
628742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            showUndoDeletionBar();
629742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        } else {
630742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // If camera preview is the only view left in filmstrip,
631742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // no need to show undo bar.
632742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            performDeletion();
633742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        }
6348872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
6358872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
6366432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private void bindMediaSaveService() {
6376432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        Intent intent = new Intent(this, MediaSaveService.class);
6386432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
6398872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
6408872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
6416432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private void unbindMediaSaveService() {
6426432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (mConnection != null) {
6436432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            unbindService(mConnection);
6446432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
6458872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
6468872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
6476432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    @Override
6480353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    public boolean onCreateOptionsMenu(Menu menu) {
6490353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        // Inflate the menu items for use in the action bar
6500353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        MenuInflater inflater = getMenuInflater();
6510353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        inflater.inflate(R.menu.operations, menu);
6520353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        mActionBarMenu = menu;
653cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware
654cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        // Configure the standard share action provider
655cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        MenuItem item = menu.findItem(R.id.action_share);
656cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        mStandardShareActionProvider = (ShareActionProvider) item.getActionProvider();
65733035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        mStandardShareActionProvider.setShareHistoryFileName("standard_share_history.xml");
658cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        if (mStandardShareIntent != null) {
659cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware            mStandardShareActionProvider.setShareIntent(mStandardShareIntent);
660cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        }
661cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware
662cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        // Configure the panorama share action provider
663cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        item = menu.findItem(R.id.action_share_panorama);
664cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        mPanoramaShareActionProvider = (ShareActionProvider) item.getActionProvider();
66533035c19cc47adfb738c20cef66652ae451c8e10Mangesh Ghiware        mPanoramaShareActionProvider.setShareHistoryFileName("panorama_share_history.xml");
666cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        if (mPanoramaShareIntent != null) {
667cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware            mPanoramaShareActionProvider.setShareIntent(mPanoramaShareIntent);
668cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware        }
669cd2eeb0efc4370f20e9836e20eb11cb974e3b00dMangesh Ghiware
6700353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        return super.onCreateOptionsMenu(menu);
6710353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    }
6720353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui
6730353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    @Override
6740353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    public boolean onOptionsItemSelected(MenuItem item) {
6756f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling        int currentDataId = mFilmStripView.getCurrentId();
6766f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling        if (currentDataId < 0) {
6776f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling            return false;
6786f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling        }
6796f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling        final LocalData localData = mDataAdapter.getLocalData(currentDataId);
6806f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling
6810353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        // Handle presses on the action bar items
6820353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        switch (item.getItemId()) {
6833f969c1735e2636bf22dfe44104d0e99924cca97Alan Newberger            case android.R.id.home:
6843f969c1735e2636bf22dfe44104d0e99924cca97Alan Newberger                // ActionBar's Up/Home button was clicked
6853f969c1735e2636bf22dfe44104d0e99924cca97Alan Newberger                mFilmStripView.getController().goToFirstItem();
6863f969c1735e2636bf22dfe44104d0e99924cca97Alan Newberger                return true;
6870353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case R.id.action_delete:
688e857cc90a98e280e2008beb03e2446bd642d2ec4Angus Kong                removeData(currentDataId);
6890353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
6900353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case R.id.action_edit:
69188ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling                launchEditor(localData);
6920353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
6930819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard            case R.id.action_trim: {
6946b9203214d828d72758943aca55adceab684a862ztenghui                // This is going to be handled by the Gallery app.
6956b9203214d828d72758943aca55adceab684a862ztenghui                Intent intent = new Intent(ACTION_TRIM_VIDEO);
6966b9203214d828d72758943aca55adceab684a862ztenghui                LocalData currentData = mDataAdapter.getLocalData(
6976b9203214d828d72758943aca55adceab684a862ztenghui                        mFilmStripView.getCurrentId());
6986b9203214d828d72758943aca55adceab684a862ztenghui                intent.setData(currentData.getContentUri());
6996b9203214d828d72758943aca55adceab684a862ztenghui                // We need the file path to wrap this into a RandomAccessFile.
7006b9203214d828d72758943aca55adceab684a862ztenghui                intent.putExtra(MEDIA_ITEM_PATH, currentData.getPath());
701b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                startActivityForResult(intent, REQ_CODE_DONT_SWITCH_TO_PREVIEW);
7020353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
7030819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard            }
7040353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case R.id.action_rotate_ccw:
705a16e7b50f3148f581439509279f242092e254309ztenghui                localData.rotate90Degrees(this, mDataAdapter, currentDataId, false);
7060353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
7070353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case R.id.action_rotate_cw:
708a16e7b50f3148f581439509279f242092e254309ztenghui                localData.rotate90Degrees(this, mDataAdapter, currentDataId, true);
7090353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
7100353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case R.id.action_crop:
7110353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                // TODO: add the functionality.
7120353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
7130819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard            case R.id.action_setas: {
7140819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard                Intent intent = new Intent(Intent.ACTION_ATTACH_DATA)
7150819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard                        .setDataAndType(localData.getContentUri(),
7160819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard                                localData.getMimeType())
7170819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard                        .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
7180819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard                intent.putExtra("mimeType", intent.getType());
719b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                startActivityForResult(Intent.createChooser(
720b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                        intent, getString(R.string.set_as)), REQ_CODE_DONT_SWITCH_TO_PREVIEW);
7210353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
7220819304bc06ffd3498d9fd0d8a148c50f0903c46nicolasroard            }
7230353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case R.id.action_details:
7246f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                (new AsyncTask<Void, Void, MediaDetails>() {
7256f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                    @Override
7266f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                    protected MediaDetails doInBackground(Void... params) {
7276f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                        return localData.getMediaDetails(CameraActivity.this);
7286f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                    }
7296f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling
7306f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                    @Override
7316f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                    protected void onPostExecute(MediaDetails mediaDetails) {
7326f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                        DetailsDialog.create(CameraActivity.this, mediaDetails).show();
7336f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                    }
7346f64b50db6565bc6454304fd20c0c4020b297bb7Sascha Haeberling                }).execute();
7350353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
7360353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            case R.id.action_show_on_map:
737fae11a165e344a38811770c7d348eda214683edcSascha Haeberling                double[] latLong = localData.getLatLong();
738fae11a165e344a38811770c7d348eda214683edcSascha Haeberling                if (latLong != null) {
739a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                    CameraUtil.showOnMap(this, latLong);
740fae11a165e344a38811770c7d348eda214683edcSascha Haeberling                }
7410353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return true;
7420353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui            default:
7430353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui                return super.onOptionsItemSelected(item);
7440353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui        }
7450353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    }
7460353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui
747fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui    private boolean isCaptureIntent() {
748fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui        if (MediaStore.ACTION_VIDEO_CAPTURE.equals(getIntent().getAction())
749fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui                || MediaStore.ACTION_IMAGE_CAPTURE.equals(getIntent().getAction())
750fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui                || MediaStore.ACTION_IMAGE_CAPTURE_SECURE.equals(getIntent().getAction())) {
751fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui            return true;
752fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui        } else {
753fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui            return false;
754fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui        }
755fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui    }
756fd43e3be3d69f48a97bdd9084e9549f41e963cc2ztenghui
7570353ca2e048543bd6e233b4c2110a1df1070cd3fztenghui    @Override
7586432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void onCreate(Bundle state) {
7596432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        super.onCreate(state);
76050df47071c776703a36dbc4cb90ec8d1df3c0f6eztenghui        getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
7616432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        setContentView(R.layout.camera_filmstrip);
762fa9e2cc9ccbcd746f5765cb7a0afebcdb60e2973ztenghui        mActionBar = getActionBar();
763fa9e2cc9ccbcd746f5765cb7a0afebcdb60e2973ztenghui
7646432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (ApiHelper.HAS_ROTATION_ANIMATION) {
7656432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            setRotationAnimation();
7666432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
7676432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        // Check if this is in the secure camera mode.
7686432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        Intent intent = getIntent();
7696432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        String action = intent.getAction();
770b84b9738c855a525dc1944165983cc3c342ce446Doris Liu        if (INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE.equals(action)
771b84b9738c855a525dc1944165983cc3c342ce446Doris Liu                || ACTION_IMAGE_CAPTURE_SECURE.equals(action)) {
7726432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mSecureCamera = true;
7736432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else {
7746432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mSecureCamera = intent.getBooleanExtra(SECURE_CAMERA_EXTRA, false);
7758872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
776b84b9738c855a525dc1944165983cc3c342ce446Doris Liu
777b84b9738c855a525dc1944165983cc3c342ce446Doris Liu        if (mSecureCamera) {
778b84b9738c855a525dc1944165983cc3c342ce446Doris Liu            // Change the window flags so that secure camera can show when locked
779b84b9738c855a525dc1944165983cc3c342ce446Doris Liu            Window win = getWindow();
780b84b9738c855a525dc1944165983cc3c342ce446Doris Liu            WindowManager.LayoutParams params = win.getAttributes();
781b84b9738c855a525dc1944165983cc3c342ce446Doris Liu            params.flags |= WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
782b84b9738c855a525dc1944165983cc3c342ce446Doris Liu            win.setAttributes(params);
783b84b9738c855a525dc1944165983cc3c342ce446Doris Liu
784b84b9738c855a525dc1944165983cc3c342ce446Doris Liu            // Filter for screen off so that we can finish secure camera activity
785b84b9738c855a525dc1944165983cc3c342ce446Doris Liu            // when screen is off.
7866432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
7876432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            registerReceiver(mScreenOffReceiver, filter);
7886a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong            // TODO: This static screen off event receiver is a workaround to the
7896a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong            // double onResume() invocation (onResume->onPause->onResume). We should
7906a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong            // find a better solution to this.
7916a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong            if (sScreenOffReceiver == null) {
7926a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong                sScreenOffReceiver = new ScreenOffReceiver();
7936a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong                registerReceiver(sScreenOffReceiver, filter);
7946a8e8a1a0f3e8e62cd350733e275047475380d6bAngus Kong            }
795b84b9738c855a525dc1944165983cc3c342ce446Doris Liu        }
796653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        mAboveFilmstripControlLayout =
797653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong                (FrameLayout) findViewById(R.id.camera_above_filmstrip_layout);
798653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        mAboveFilmstripControlLayout.setFitsSystemWindows(true);
7995199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling        // Hide action bar first since we are in full screen mode first, and
8005199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling        // switch the system UI to lights-out mode.
8015199c2078f3aea06732015ce8ad354c066a2f4ecSascha Haeberling        setActionBarVisibilityAndLightsOut(true);
802ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mPanoramaManager = AppManagerFactory.getInstance(this)
803ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                .getPanoramaStitchingManager();
8046798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong        mPanoramaManager.addTaskListener(mStitchingListener);
8056432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        LayoutInflater inflater = getLayoutInflater();
8066432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        View rootLayout = inflater.inflate(R.layout.camera, null, false);
807653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        mCameraModuleRootView = rootLayout.findViewById(R.id.camera_app_root);
808fa9e2cc9ccbcd746f5765cb7a0afebcdb60e2973ztenghui        mPanoStitchingPanel = findViewById(R.id.pano_stitching_progress_panel);
80937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        mBottomProgress = (ProgressBar) findViewById(R.id.pano_stitching_progress_bar);
8108e5e4eedb25a4589342660b928935acca4375fc7Angus Kong        mCameraPreviewData = new CameraPreviewData(rootLayout,
8118e5e4eedb25a4589342660b928935acca4375fc7Angus Kong                FilmStripView.ImageData.SIZE_FULL,
8128e5e4eedb25a4589342660b928935acca4375fc7Angus Kong                FilmStripView.ImageData.SIZE_FULL);
81337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        // Put a CameraPreviewData at the first position.
8148e5e4eedb25a4589342660b928935acca4375fc7Angus Kong        mWrappedDataAdapter = new FixedFirstDataAdapter(
8158e5e4eedb25a4589342660b928935acca4375fc7Angus Kong                new CameraDataAdapter(new ColorDrawable(
8168e5e4eedb25a4589342660b928935acca4375fc7Angus Kong                        getResources().getColor(R.color.photo_placeholder))),
8178e5e4eedb25a4589342660b928935acca4375fc7Angus Kong                mCameraPreviewData);
8186432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mFilmStripView = (FilmStripView) findViewById(R.id.filmstrip_view);
8196432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mFilmStripView.setViewGap(
8206432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                getResources().getDimensionPixelSize(R.dimen.camera_film_strip_gap));
821f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling        mPanoramaViewHelper = new PanoramaViewHelper(this);
822f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling        mPanoramaViewHelper.onCreate();
823f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling        mFilmStripView.setPanoramaViewHelper(mPanoramaViewHelper);
8246432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        // Set up the camera preview first so the preview shows up ASAP.
8256432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mFilmStripView.setListener(mFilmStripListener);
8262654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling
8272654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        int moduleIndex = -1;
8282a7f44cac888de5683d05bef5708f846ee950f43Doris Liu        if (MediaStore.INTENT_ACTION_VIDEO_CAMERA.equals(getIntent().getAction())
8292a7f44cac888de5683d05bef5708f846ee950f43Doris Liu                || MediaStore.ACTION_VIDEO_CAPTURE.equals(getIntent().getAction())) {
830ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            moduleIndex = ModuleSwitcher.VIDEO_MODULE_INDEX;
8312654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        } else if (MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA.equals(getIntent().getAction())
8322654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling                || MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE.equals(getIntent()
8332654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling                        .getAction())
8342654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling                || MediaStore.ACTION_IMAGE_CAPTURE.equals(getIntent().getAction())
8352654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling                || MediaStore.ACTION_IMAGE_CAPTURE_SECURE.equals(getIntent().getAction())) {
836ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            moduleIndex = ModuleSwitcher.PHOTO_MODULE_INDEX;
8372a7f44cac888de5683d05bef5708f846ee950f43Doris Liu        } else {
8382654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling            // If the activity has not been started using an explicit intent,
8392654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling            // read the module index from the last time the user changed modes
8402654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
8412654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling            moduleIndex = prefs.getInt(PREF_STARTUP_MODULE_INDEX, -1);
842a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunk            if ((moduleIndex == ModuleSwitcher.GCAM_MODULE_INDEX &&
843a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunk                    !GcamHelper.hasGcamCapture(this)) || moduleIndex < 0) {
844ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                moduleIndex = ModuleSwitcher.PHOTO_MODULE_INDEX;
8452654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling            }
8462a7f44cac888de5683d05bef5708f846ee950f43Doris Liu        }
8472654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling
8486432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mOrientationListener = new MyOrientationEventListener(this);
849ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        setModuleFromIndex(moduleIndex);
850ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        mCurrentModule.init(this, mCameraModuleRootView);
8516432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mMainHandler = new Handler(getMainLooper());
85237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling
85337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        if (!mSecureCamera) {
85437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            mDataAdapter = mWrappedDataAdapter;
855dcccc510652b835fdbd39310a07849af8203052aAngus Kong            mFilmStripView.setDataAdapter(mDataAdapter);
856a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong            if (!isCaptureIntent()) {
857a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong                mDataAdapter.requestLoad(getContentResolver());
858a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong            }
85937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        } else {
860a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            // Put a lock placeholder as the last image by setting its date to
861a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            // 0.
86237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            ImageView v = (ImageView) getLayoutInflater().inflate(
86337f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    R.layout.secure_album_placeholder, null);
86437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            mDataAdapter = new FixedLastDataAdapter(
86537f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                    mWrappedDataAdapter,
866bd26069d391830856c57c2141cd2efbc8423d871Angus Kong                    new SimpleViewData(
86737f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            v,
86837f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            v.getDrawable().getIntrinsicWidth(),
86937f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            v.getDrawable().getIntrinsicHeight(),
87037f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling                            0, 0));
87137f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            // Flush out all the original data.
87237f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling            mDataAdapter.flush();
873dcccc510652b835fdbd39310a07849af8203052aAngus Kong            mFilmStripView.setDataAdapter(mDataAdapter);
87437f3611bbdc787c996a99894dcef7d8fb77e3f7cSascha Haeberling        }
8758872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
8768872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
8776432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private void setRotationAnimation() {
8786432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        int rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE;
8796432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE;
8806432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        Window win = getWindow();
8816432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        WindowManager.LayoutParams winParams = win.getAttributes();
8826432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        winParams.rotationAnimation = rotationAnimation;
8836432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        win.setAttributes(winParams);
8848872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
8858872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
8868872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
8876432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void onUserInteraction() {
8886432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        super.onUserInteraction();
8896432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mCurrentModule.onUserInteraction();
89009106a41ee6acc6b20553662cb9b730702a8f08aDoris Liu    }
8918872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
8928872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
893742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    public boolean dispatchTouchEvent(MotionEvent ev) {
894742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        boolean result = super.dispatchTouchEvent(ev);
895742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
896742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // Real deletion is postponed until the next user interaction after
897742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // the gesture that triggers deletion. Until real deletion is performed,
898742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // users can click the undo button to bring back the image that they
899742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // chose to delete.
900742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            if (mPendingDeletion && !mIsUndoingDeletion) {
901742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                 performDeletion();
902742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            }
903742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        }
904742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        return result;
905742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    }
906742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu
907742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    @Override
9088872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void onPause() {
9098872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mOrientationListener.disable();
9108872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mCurrentModule.onPauseBeforeSuper();
9118872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        super.onPause();
9128872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mCurrentModule.onPauseAfterSuper();
9138872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
9148872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
9158872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
916b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
917b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        if (requestCode == REQ_CODE_EDIT && resultCode == RESULT_OK) {
918b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling            Uri uri = data.getData();
919b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling            ContentResolver contentResolver = getContentResolver();
920b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling            if (uri == null) {
921b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                // If we don't have a particular uri returned, then we have
922b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                // to refresh all, it is not optimal, but works best so far.
923b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                // Also don't requestLoad() when in secure camera mode.
924b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                if (!mSecureCamera) {
925b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                    mDataAdapter.requestLoad(contentResolver);
926b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                }
927b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling            } else {
928b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling                mDataAdapter.refresh(contentResolver, uri);
929b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling            }
930b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        }
931b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling
932b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        if (requestCode == REQ_CODE_DONT_SWITCH_TO_PREVIEW | requestCode == REQ_CODE_EDIT) {
933b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling            mResetToPreviewOnResume = false;
934b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        } else {
935b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling            super.onActivityResult(requestCode, resultCode, data);
936b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        }
937b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    }
938b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling
939b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling    @Override
9408872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void onResume() {
941ce2b94917098f211cacaaebaa0f6b40021d3e3faAngus Kong        // TODO: Handle this in OrientationManager.
942a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        // Auto-rotate off
9433cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu        if (Settings.System.getInt(getContentResolver(),
944a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                Settings.System.ACCELEROMETER_ROTATION, 0) == 0) {
9453cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
9463cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu            mAutoRotateScreen = false;
9473cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu        } else {
9483cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
9493cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu            mAutoRotateScreen = true;
9503cf565c4242a9deab7da5eb84fc302c79d594f11Doris Liu        }
9518872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mOrientationListener.enable();
9528872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mCurrentModule.onResumeBeforeSuper();
9538872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        super.onResume();
9548872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mCurrentModule.onResumeAfterSuper();
9558872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
9566798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong        setSwipingEnabled(true);
957b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling
958b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        if (mResetToPreviewOnResume) {
959b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling            // Go to the preview on resume.
960b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling            mFilmStripView.getController().goToFirstItem();
961b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        }
962b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        // Default is showing the preview, unless disabled by explicitly
963b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        // starting an activity we want to return from to the filmstrip rather
964b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        // than the preview.
965b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        mResetToPreviewOnResume = true;
9666798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong    }
9676798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong
9686798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong    @Override
9696798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong    public void onStart() {
9706798c34ddb5248f038f351674c6a6c7a20992c8cAngus Kong        super.onStart();
9717e374eb0a450ed2689b556ab42a0a88c8f74df2eAngus Kong        bindMediaSaveService();
972f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling        mPanoramaViewHelper.onStart();
973f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling    }
974f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling
975f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling    @Override
976f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling    protected void onStop() {
977f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling        super.onStop();
978f1f5186f7d3fd8bf35009d9e65a43914c664d82bSascha Haeberling        mPanoramaViewHelper.onStop();
9797e374eb0a450ed2689b556ab42a0a88c8f74df2eAngus Kong        unbindMediaSaveService();
98008650187c1f1a2d1ef7f754be0f479a29958daaaMichael Kolb    }
98108650187c1f1a2d1ef7f754be0f479a29958daaaMichael Kolb
9828872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
9836432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void onDestroy() {
984a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        if (mSecureCamera) {
985a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            unregisterReceiver(mScreenOffReceiver);
986a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        }
9876432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        super.onDestroy();
9888872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
9898872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
9908872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
9916432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void onConfigurationChanged(Configuration config) {
9926432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        super.onConfigurationChanged(config);
9936432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mCurrentModule.onConfigurationChanged(config);
9948872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
9958872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
9968872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
9976432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public boolean onKeyDown(int keyCode, KeyEvent event) {
998a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        if (mCurrentModule.onKeyDown(keyCode, event)) {
999a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            return true;
1000a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        }
10016432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        // Prevent software keyboard or voice search from showing up.
10026432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (keyCode == KeyEvent.KEYCODE_SEARCH
10036432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                || keyCode == KeyEvent.KEYCODE_MENU) {
1004a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            if (event.isLongPress()) {
1005a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling                return true;
1006a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            }
10076432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
10086432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
10096432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return super.onKeyDown(keyCode, event);
10108872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10118872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10128872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
10136432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public boolean onKeyUp(int keyCode, KeyEvent event) {
1014a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        if (mCurrentModule.onKeyUp(keyCode, event)) {
1015a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            return true;
1016a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        }
10176432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return super.onKeyUp(keyCode, event);
10188872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10198872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10205f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger    @Override
10215f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger    public void onBackPressed() {
10225f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger        if (!mFilmStripView.inCameraFullscreen()) {
10235f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger            mFilmStripView.getController().goToFirstItem();
10245f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger        } else if (!mCurrentModule.onBackPressed()) {
10255f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger            super.onBackPressed();
10265f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger        }
10275f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger    }
10285f6b50deaf46fb546ebf6d0d6244ebf7fb79c7caAlan Newberger
10296432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public boolean isAutoRotateScreen() {
10306432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return mAutoRotateScreen;
10318872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10328872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10336432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    protected void updateStorageSpace() {
10346432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mStorageSpace = Storage.getAvailableSpace();
10358872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10368872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10376432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    protected long getStorageSpace() {
10386432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return mStorageSpace;
10398872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10408872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10416432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    protected void updateStorageSpaceAndHint() {
10426432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        updateStorageSpace();
10436432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        updateStorageHint(mStorageSpace);
10448872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10458872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10466432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    protected void updateStorageHint() {
10476432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        updateStorageHint(mStorageSpace);
10488872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10498872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10506432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    protected boolean updateStorageHintOnResume() {
10516432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return true;
10526432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
10536432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
10546432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    protected void updateStorageHint(long storageSpace) {
10556432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        String message = null;
10566432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (storageSpace == Storage.UNAVAILABLE) {
10576432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            message = getString(R.string.no_storage);
10586432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else if (storageSpace == Storage.PREPARING) {
10596432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            message = getString(R.string.preparing_sd);
10606432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else if (storageSpace == Storage.UNKNOWN_SIZE) {
10616432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            message = getString(R.string.access_sd_fail);
10626432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else if (storageSpace <= Storage.LOW_STORAGE_THRESHOLD) {
10636432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            message = getString(R.string.spaceIsLow_content);
10648872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
10656432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
10666432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        if (message != null) {
10676432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            if (mStorageHint == null) {
10686432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                mStorageHint = OnScreenHint.makeText(this, message);
10696432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            } else {
10706432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                mStorageHint.setText(message);
10716432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            }
10726432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mStorageHint.show();
10736432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        } else if (mStorageHint != null) {
10746432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mStorageHint.cancel();
10756432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu            mStorageHint = null;
10768872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
10778872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10788872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10796432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    protected void setResultEx(int resultCode) {
10806432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mResultCodeForTesting = resultCode;
10816432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        setResult(resultCode);
10828872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10838872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10846432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    protected void setResultEx(int resultCode, Intent data) {
10856432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mResultCodeForTesting = resultCode;
10866432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        mResultDataForTesting = data;
10876432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        setResult(resultCode, data);
10888872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10898872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10906432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public int getResultCode() {
10916432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return mResultCodeForTesting;
10928872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10938872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10946432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public Intent getResultData() {
10956432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return mResultDataForTesting;
10968872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
10978872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
10986432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public boolean isSecureCamera() {
10996432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        return mSecureCamera;
11008872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
11018872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
11028872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
1103ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void onModuleSelected(int moduleIndex) {
1104a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        if (mCurrentModuleIndex == moduleIndex) {
1105a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling            return;
1106a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        }
11076432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
11086432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        CameraHolder.instance().keep();
11096432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        closeModule(mCurrentModule);
11102654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        setModuleFromIndex(moduleIndex);
11112654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling
11122654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        openModule(mCurrentModule);
11132654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        mCurrentModule.onOrientationChanged(mLastRawOrientation);
11142654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        if (mMediaSaveService != null) {
11152654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling            mCurrentModule.onMediaSaveServiceConnected(mMediaSaveService);
11162654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        }
11172654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling
11182654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        // Store the module index so we can use it the next time the Camera
11192654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        // starts up.
11202654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
11212654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        prefs.edit().putInt(PREF_STARTUP_MODULE_INDEX, moduleIndex).apply();
11222654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling    }
11232654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling
11242654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling    /**
1125a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     * Sets the mCurrentModuleIndex, creates a new module instance for the given
1126a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     * index an sets it as mCurrentModule.
11272654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling     */
11282654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling    private void setModuleFromIndex(int moduleIndex) {
11292654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        mCurrentModuleIndex = moduleIndex;
11302654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling        switch (moduleIndex) {
113115125661ad968cf4d40989a9bc88d11189beb0b3Sascha Haeberling            case ModuleSwitcher.VIDEO_MODULE_INDEX:
11326432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                mCurrentModule = new VideoModule();
11336432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                break;
1134ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
113515125661ad968cf4d40989a9bc88d11189beb0b3Sascha Haeberling            case ModuleSwitcher.PHOTO_MODULE_INDEX:
11366432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                mCurrentModule = new PhotoModule();
11376432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                break;
1138ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
113915125661ad968cf4d40989a9bc88d11189beb0b3Sascha Haeberling            case ModuleSwitcher.WIDE_ANGLE_PANO_MODULE_INDEX:
1140ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                mCurrentModule = new WideAnglePanoramaModule();
1141ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                break;
1142ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong
114315125661ad968cf4d40989a9bc88d11189beb0b3Sascha Haeberling            case ModuleSwitcher.LIGHTCYCLE_MODULE_INDEX:
11448e963a5a6016d246184ed65906f9d103e92b17e2Sascha Haeberling                mCurrentModule = PhotoSphereHelper.createPanoramaModule();
11456432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu                break;
1146a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunk            case ModuleSwitcher.GCAM_MODULE_INDEX:
1147a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunk                // Force immediate release of Camera instance
1148a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunk                CameraHolder.instance().strongRelease();
1149a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunk                mCurrentModule = GcamHelper.createGcamModule();
1150a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunk                break;
11512654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling            default:
115215125661ad968cf4d40989a9bc88d11189beb0b3Sascha Haeberling                // Fall back to photo mode.
115315125661ad968cf4d40989a9bc88d11189beb0b3Sascha Haeberling                mCurrentModule = new PhotoModule();
115415125661ad968cf4d40989a9bc88d11189beb0b3Sascha Haeberling                mCurrentModuleIndex = ModuleSwitcher.PHOTO_MODULE_INDEX;
11552654dd9bb6a7d917dab1a48e2182c4f49fe71f11Sascha Haeberling                break;
11566432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        }
11578872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
11588872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
115988ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling    /**
116088ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling     * Launches an ACTION_EDIT intent for the given local data item.
116188ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling     */
116288ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling    public void launchEditor(LocalData data) {
116388ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling        Intent intent = new Intent(Intent.ACTION_EDIT)
116488ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling                .setDataAndType(data.getContentUri(), data.getMimeType())
116588ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling                .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
1166b7639c641f2ed5d0c60546349c3aa9e90c026878Sascha Haeberling        startActivityForResult(Intent.createChooser(intent, null), REQ_CODE_EDIT);
116788ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling    }
116888ef7664ba6a888fa5da8693091674e152b56192Sascha Haeberling
1169a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling    /**
1170a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     * Launch the tiny planet editor.
1171a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     *
1172a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     * @param data the data must be a 360 degree stereographically mapped
1173a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     *            panoramic image. It will not be modified, instead a new item
1174a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     *            with the result will be added to the filmstrip.
1175a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     */
1176a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling    public void launchTinyPlanetEditor(LocalData data) {
1177a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        TinyPlanetFragment fragment = new TinyPlanetFragment();
1178a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        Bundle bundle = new Bundle();
1179a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        bundle.putString(TinyPlanetFragment.ARGUMENT_URI, data.getContentUri().toString());
1180a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        bundle.putString(TinyPlanetFragment.ARGUMENT_TITLE, data.getTitle());
1181a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        fragment.setArguments(bundle);
1182a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling        fragment.show(getFragmentManager(), "tiny_planet");
1183a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling    }
1184a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling
11856432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private void openModule(CameraModule module) {
1186653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        module.init(this, mCameraModuleRootView);
11876432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        module.onResumeBeforeSuper();
11886432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        module.onResumeAfterSuper();
11898872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
11908872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
11916432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    private void closeModule(CameraModule module) {
11926432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        module.onPauseBeforeSuper();
11936432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu        module.onPauseAfterSuper();
1194653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        ((ViewGroup) mCameraModuleRootView).removeAllViews();
1195653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong    }
1196653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong
1197742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    private void performDeletion() {
1198742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        if (!mPendingDeletion) {
1199742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            return;
1200742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        }
1201742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        hideUndoDeletionBar(false);
1202742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        mDataAdapter.executeDeletion(CameraActivity.this);
1203742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    }
1204742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu
1205742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    public void showUndoDeletionBar() {
1206742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        if (mPendingDeletion) {
1207742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            performDeletion();
1208742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        }
1209742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        Log.v(TAG, "showing undo bar");
1210742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        mPendingDeletion = true;
1211653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        if (mUndoDeletionBar == null) {
1212653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong            ViewGroup v = (ViewGroup) getLayoutInflater().inflate(
1213653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong                    R.layout.undo_bar, mAboveFilmstripControlLayout, true);
1214653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong            mUndoDeletionBar = (ViewGroup) v.findViewById(R.id.camera_undo_deletion_bar);
1215653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong            View button = mUndoDeletionBar.findViewById(R.id.camera_undo_deletion_button);
1216653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong            button.setOnClickListener(new View.OnClickListener() {
1217653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong                @Override
1218653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong                public void onClick(View view) {
1219653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong                    mDataAdapter.undoDataRemoval();
1220742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                    hideUndoDeletionBar(true);
1221742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                }
1222742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            });
1223742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // Setting undo bar clickable to avoid touch events going through
1224742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // the bar to the buttons (eg. edit button, etc) underneath the bar.
1225742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            mUndoDeletionBar.setClickable(true);
1226742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // When there is user interaction going on with the undo button, we
1227742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            // do not want to hide the undo bar.
1228742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            button.setOnTouchListener(new View.OnTouchListener() {
1229742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                @Override
1230742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                public boolean onTouch(View v, MotionEvent event) {
1231742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                    if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
1232742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                        mIsUndoingDeletion = true;
1233742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                    } else if (event.getActionMasked() == MotionEvent.ACTION_UP) {
1234742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                        mIsUndoingDeletion =false;
1235742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                    }
1236742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                    return false;
1237653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong                }
1238653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong            });
1239653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        }
1240653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        mUndoDeletionBar.setAlpha(0f);
1241653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        mUndoDeletionBar.setVisibility(View.VISIBLE);
1242742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        mUndoDeletionBar.animate().setDuration(200).alpha(1f).setListener(null).start();
1243653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong    }
1244653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong
1245742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu    private void hideUndoDeletionBar(boolean withAnimation) {
1246653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        Log.v(TAG, "Hiding undo deletion bar");
1247742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu        mPendingDeletion = false;
1248653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        if (mUndoDeletionBar != null) {
1249742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            if (withAnimation) {
1250742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                mUndoDeletionBar.animate()
1251742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                        .setDuration(200)
1252742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                        .alpha(0f)
1253742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                        .setListener(new Animator.AnimatorListener() {
1254742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            @Override
1255742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            public void onAnimationStart(Animator animation) {
1256742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                                // Do nothing.
1257742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            }
1258742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu
1259742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            @Override
1260742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            public void onAnimationEnd(Animator animation) {
1261742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                                mUndoDeletionBar.setVisibility(View.GONE);
1262742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            }
1263742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu
1264742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            @Override
1265742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            public void onAnimationCancel(Animator animation) {
1266742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                                // Do nothing.
1267742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            }
1268742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu
1269742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            @Override
1270742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            public void onAnimationRepeat(Animator animation) {
1271742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                                // Do nothing.
1272742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                            }
1273742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                        })
1274742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                        .start();
1275742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            } else {
1276742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu                mUndoDeletionBar.setVisibility(View.GONE);
1277742cd5b18e1899bee1d430b61891238c0f3502b6Doris Liu            }
1278653c43be6e58be54cf2ac3c8efb2d65ac20bd03bAngus Kong        }
12798872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
12808872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
12818872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
12826432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void onShowSwitcherPopup() {
12836432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    }
12846432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu
1285a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong    /**
1286a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     * Enable/disable swipe-to-filmstrip. Will always disable swipe if in
1287a5a08d7642a1fdf961b057cc90e76c4c93103c15Sascha Haeberling     * capture intent.
1288a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong     *
1289a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong     * @param enable {@code true} to enable swipe.
1290a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong     */
12916432cd65159731a28d9239426b0f0f4d7c44fa98Doris Liu    public void setSwipingEnabled(boolean enable) {
1292a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong        if (isCaptureIntent()) {
1293a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong            mCameraPreviewData.lockPreview(true);
1294a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong        } else {
1295a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong            mCameraPreviewData.lockPreview(!enable);
1296a71946012df0eee8fe4859a22da3c56feba0344eAngus Kong        }
12978872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
12988872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
12998872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    // Accessor methods for getting latency times used in performance testing
13008872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public long getAutoFocusTime() {
13018872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return (mCurrentModule instanceof PhotoModule) ?
13028872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                ((PhotoModule) mCurrentModule).mAutoFocusTime : -1;
13038872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
13048872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
13058872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public long getShutterLag() {
13068872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return (mCurrentModule instanceof PhotoModule) ?
13078872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                ((PhotoModule) mCurrentModule).mShutterLag : -1;
13088872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
13098872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
13108872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public long getShutterToPictureDisplayedTime() {
13118872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return (mCurrentModule instanceof PhotoModule) ?
13128872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                ((PhotoModule) mCurrentModule).mShutterToPictureDisplayedTime : -1;
13138872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
13148872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
13158872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public long getPictureDisplayedToJpegCallbackTime() {
13168872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return (mCurrentModule instanceof PhotoModule) ?
13178872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                ((PhotoModule) mCurrentModule).mPictureDisplayedToJpegCallbackTime : -1;
13188872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
13198872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
13208872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public long getJpegCallbackFinishTime() {
13218872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return (mCurrentModule instanceof PhotoModule) ?
13228872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                ((PhotoModule) mCurrentModule).mJpegCallbackFinishTime : -1;
13238872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
13248872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
13258872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public long getCaptureStartTime() {
13268872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return (mCurrentModule instanceof PhotoModule) ?
13278872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                ((PhotoModule) mCurrentModule).mCaptureStartTime : -1;
13288872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
13298872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
13308872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public boolean isRecording() {
13318872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return (mCurrentModule instanceof VideoModule) ?
13328872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                ((VideoModule) mCurrentModule).isRecording() : false;
13338872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
13344f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong
13354f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong    public CameraOpenErrorCallback getCameraOpenErrorCallback() {
13364f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong        return mCameraOpenErrorCallback;
13374f795b878843e59810ec1dca05b7cdb37b5614c5Angus Kong    }
13388872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb}
1339