Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2012 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | package com.android.camera; |
| 18 | |
Doris Liu | 742cd5b | 2013-09-12 16:17:43 -0700 | [diff] [blame] | 19 | import android.animation.Animator; |
Mangesh Ghiware | a5682ab | 2013-09-19 09:24:23 -0700 | [diff] [blame] | 20 | import android.annotation.TargetApi; |
ztenghui | fa9e2cc | 2013-08-09 17:37:15 -0700 | [diff] [blame] | 21 | import android.app.ActionBar; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 22 | import android.app.Activity; |
Mangesh Ghiware | 30968d0 | 2013-10-02 14:38:12 -0700 | [diff] [blame] | 23 | import android.content.ActivityNotFoundException; |
Doris Liu | b84b973 | 2013-06-18 17:14:26 -0700 | [diff] [blame] | 24 | import android.content.BroadcastReceiver; |
Angus Kong | 86d3631 | 2013-01-31 18:22:44 -0800 | [diff] [blame] | 25 | import android.content.ComponentName; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 26 | import android.content.ContentResolver; |
Michael Kolb | 0865018 | 2013-02-25 19:43:56 -0800 | [diff] [blame] | 27 | import android.content.Context; |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 28 | import android.content.Intent; |
Doris Liu | b84b973 | 2013-06-18 17:14:26 -0700 | [diff] [blame] | 29 | import android.content.IntentFilter; |
Angus Kong | 86d3631 | 2013-01-31 18:22:44 -0800 | [diff] [blame] | 30 | import android.content.ServiceConnection; |
Sascha Haeberling | 2654dd9 | 2013-08-28 15:28:57 -0700 | [diff] [blame] | 31 | import android.content.SharedPreferences; |
Doris Liu | 3cf565c | 2013-02-15 10:55:37 -0800 | [diff] [blame] | 32 | import android.content.pm.ActivityInfo; |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 33 | import android.content.res.Configuration; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 34 | import android.graphics.drawable.ColorDrawable; |
| 35 | import android.net.Uri; |
Mangesh Ghiware | a5682ab | 2013-09-19 09:24:23 -0700 | [diff] [blame] | 36 | import android.nfc.NfcAdapter; |
| 37 | import android.nfc.NfcAdapter.CreateBeamUrisCallback; |
| 38 | import android.nfc.NfcEvent; |
Sascha Haeberling | 6f64b50 | 2013-08-14 16:23:18 -0700 | [diff] [blame] | 39 | import android.os.AsyncTask; |
Mangesh Ghiware | a5682ab | 2013-09-19 09:24:23 -0700 | [diff] [blame] | 40 | import android.os.Build; |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 41 | import android.os.Bundle; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 42 | import android.os.Handler; |
Angus Kong | 86d3631 | 2013-01-31 18:22:44 -0800 | [diff] [blame] | 43 | import android.os.IBinder; |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 44 | import android.os.Looper; |
| 45 | import android.os.Message; |
Sascha Haeberling | 2654dd9 | 2013-08-28 15:28:57 -0700 | [diff] [blame] | 46 | import android.preference.PreferenceManager; |
Doris Liu | 2a7f44c | 2013-08-12 15:18:53 -0700 | [diff] [blame] | 47 | import android.provider.MediaStore; |
Doris Liu | 3cf565c | 2013-02-15 10:55:37 -0800 | [diff] [blame] | 48 | import android.provider.Settings; |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 49 | import android.util.Log; |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 50 | import android.view.KeyEvent; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 51 | import android.view.LayoutInflater; |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 52 | import android.view.Menu; |
| 53 | import android.view.MenuInflater; |
| 54 | import android.view.MenuItem; |
Doris Liu | 742cd5b | 2013-09-12 16:17:43 -0700 | [diff] [blame] | 55 | import android.view.MotionEvent; |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 56 | import android.view.OrientationEventListener; |
| 57 | import android.view.View; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 58 | import android.view.ViewGroup; |
Michael Kolb | 0865018 | 2013-02-25 19:43:56 -0800 | [diff] [blame] | 59 | import android.view.Window; |
| 60 | import android.view.WindowManager; |
Angus Kong | 653c43b | 2013-08-21 18:28:43 -0700 | [diff] [blame] | 61 | import android.widget.FrameLayout; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 62 | import android.widget.ImageView; |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 63 | import android.widget.ProgressBar; |
Mangesh Ghiware | cd2eeb0 | 2013-08-23 13:28:21 -0700 | [diff] [blame] | 64 | import android.widget.ShareActionProvider; |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 65 | |
Sascha Haeberling | 03e0145 | 2013-10-07 13:21:33 -0700 | [diff] [blame] | 66 | import com.android.camera.CameraManager.CameraOpenErrorCallback; |
Angus Kong | ed15d1a | 2013-08-19 15:06:12 -0700 | [diff] [blame] | 67 | import com.android.camera.app.AppManagerFactory; |
Angus Kong | fd4fc0e | 2013-11-07 15:38:09 -0800 | [diff] [blame^] | 68 | import com.android.camera.app.MediaSaver; |
Ruben Brunk | 7cfcafd | 2013-10-17 15:41:44 -0700 | [diff] [blame] | 69 | import com.android.camera.app.PlaceholderManager; |
Angus Kong | ed15d1a | 2013-08-19 15:06:12 -0700 | [diff] [blame] | 70 | import com.android.camera.app.PanoramaStitchingManager; |
nicolasroard | 19ab725 | 2013-09-18 16:54:05 -0700 | [diff] [blame] | 71 | import com.android.camera.crop.CropActivity; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 72 | import com.android.camera.data.CameraDataAdapter; |
Angus Kong | 8e5e4ee | 2013-07-30 11:36:00 -0700 | [diff] [blame] | 73 | import com.android.camera.data.CameraPreviewData; |
| 74 | import com.android.camera.data.FixedFirstDataAdapter; |
| 75 | import com.android.camera.data.FixedLastDataAdapter; |
Angus Kong | 3250987 | 2013-10-02 16:53:40 -0700 | [diff] [blame] | 76 | import com.android.camera.data.InProgressDataWrapper; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 77 | import com.android.camera.data.LocalData; |
Angus Kong | 8e5e4ee | 2013-07-30 11:36:00 -0700 | [diff] [blame] | 78 | import com.android.camera.data.LocalDataAdapter; |
ztenghui | 064d600 | 2013-09-05 15:47:58 -0700 | [diff] [blame] | 79 | import com.android.camera.data.LocalMediaObserver; |
Sascha Haeberling | 6f64b50 | 2013-08-14 16:23:18 -0700 | [diff] [blame] | 80 | import com.android.camera.data.MediaDetails; |
Angus Kong | bd26069 | 2013-08-07 14:52:56 -0700 | [diff] [blame] | 81 | import com.android.camera.data.SimpleViewData; |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 82 | import com.android.camera.tinyplanet.TinyPlanetFragment; |
Sascha Haeberling | 6f64b50 | 2013-08-14 16:23:18 -0700 | [diff] [blame] | 83 | import com.android.camera.ui.DetailsDialog; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 84 | import com.android.camera.ui.FilmStripView; |
Sascha Haeberling | 03e0145 | 2013-10-07 13:21:33 -0700 | [diff] [blame] | 85 | import com.android.camera.ui.ModuleSwitcher; |
Sascha Haeberling | 88ef766 | 2013-08-15 17:19:22 -0700 | [diff] [blame] | 86 | import com.android.camera.util.ApiHelper; |
Angus Kong | b50b5cb | 2013-08-09 14:55:20 -0700 | [diff] [blame] | 87 | import com.android.camera.util.CameraUtil; |
Ruben Brunk | a9d66bd | 2013-09-06 11:56:32 -0700 | [diff] [blame] | 88 | import com.android.camera.util.GcamHelper; |
Alan Newberger | 761306f | 2013-10-30 12:51:21 -0700 | [diff] [blame] | 89 | import com.android.camera.util.IntentHelper; |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 90 | import com.android.camera.util.PhotoSphereHelper; |
Sascha Haeberling | 88ef766 | 2013-08-15 17:19:22 -0700 | [diff] [blame] | 91 | import com.android.camera.util.PhotoSphereHelper.PanoramaViewHelper; |
Sascha Haeberling | 03e0145 | 2013-10-07 13:21:33 -0700 | [diff] [blame] | 92 | import com.android.camera.util.RefocusHelper; |
Sascha Haeberling | 8e963a5 | 2013-08-06 11:43:02 -0700 | [diff] [blame] | 93 | import com.android.camera2.R; |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 94 | |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 95 | public class CameraActivity extends Activity |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 96 | implements ModuleSwitcher.ModuleSwitchListener, |
| 97 | ActionBar.OnMenuVisibilityListener { |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 98 | |
| 99 | private static final String TAG = "CAM_Activity"; |
| 100 | |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 101 | private static final String INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE = |
| 102 | "android.media.action.STILL_IMAGE_CAMERA_SECURE"; |
| 103 | public static final String ACTION_IMAGE_CAPTURE_SECURE = |
| 104 | "android.media.action.IMAGE_CAPTURE_SECURE"; |
ztenghui | 6b92032 | 2013-08-16 16:21:22 -0700 | [diff] [blame] | 105 | public static final String ACTION_TRIM_VIDEO = |
| 106 | "com.android.camera.action.TRIM"; |
| 107 | public static final String MEDIA_ITEM_PATH = "media-item-path"; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 108 | |
| 109 | // The intent extra for camera from secure lock screen. True if the gallery |
| 110 | // should only show newly captured pictures. sSecureAlbumId does not |
| 111 | // increment. This is used when switching between camera, camcorder, and |
| 112 | // panorama. If the extra is not set, it is in the normal camera mode. |
| 113 | public static final String SECURE_CAMERA_EXTRA = "secure_camera"; |
| 114 | |
Sascha Haeberling | b7639c6 | 2013-09-09 14:42:43 -0700 | [diff] [blame] | 115 | /** |
| 116 | * Request code from an activity we started that indicated that we do not |
| 117 | * want to reset the view to the preview in onResume. |
| 118 | */ |
| 119 | public static final int REQ_CODE_DONT_SWITCH_TO_PREVIEW = 142; |
| 120 | |
Ruben Brunk | d217ed0 | 2013-10-08 23:31:13 -0700 | [diff] [blame] | 121 | public static final int REQ_CODE_GCAM_DEBUG_POSTCAPTURE = 999; |
| 122 | |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 123 | private static final int HIDE_ACTION_BAR = 1; |
| 124 | private static final long SHOW_ACTION_BAR_TIMEOUT_MS = 3000; |
| 125 | |
Sascha Haeberling | b7639c6 | 2013-09-09 14:42:43 -0700 | [diff] [blame] | 126 | /** Whether onResume should reset the view to the preview. */ |
| 127 | private boolean mResetToPreviewOnResume = true; |
| 128 | |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 129 | // Supported operations at FilmStripView. Different data has different |
| 130 | // set of supported operations. |
| 131 | private static final int SUPPORT_DELETE = 1 << 0; |
| 132 | private static final int SUPPORT_ROTATE = 1 << 1; |
| 133 | private static final int SUPPORT_INFO = 1 << 2; |
| 134 | private static final int SUPPORT_CROP = 1 << 3; |
| 135 | private static final int SUPPORT_SETAS = 1 << 4; |
| 136 | private static final int SUPPORT_EDIT = 1 << 5; |
| 137 | private static final int SUPPORT_TRIM = 1 << 6; |
Mangesh Ghiware | cd2eeb0 | 2013-08-23 13:28:21 -0700 | [diff] [blame] | 138 | private static final int SUPPORT_SHARE = 1 << 7; |
| 139 | private static final int SUPPORT_SHARE_PANORAMA360 = 1 << 8; |
| 140 | private static final int SUPPORT_SHOW_ON_MAP = 1 << 9; |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 141 | private static final int SUPPORT_ALL = 0xffffffff; |
| 142 | |
Sascha Haeberling | 6f64b50 | 2013-08-14 16:23:18 -0700 | [diff] [blame] | 143 | /** This data adapter is used by FilmStripView. */ |
Angus Kong | 8e5e4ee | 2013-07-30 11:36:00 -0700 | [diff] [blame] | 144 | private LocalDataAdapter mDataAdapter; |
| 145 | /** This data adapter represents the real local camera data. */ |
| 146 | private LocalDataAdapter mWrappedDataAdapter; |
| 147 | |
Angus Kong | 6798c34 | 2013-07-16 15:14:58 -0700 | [diff] [blame] | 148 | private PanoramaStitchingManager mPanoramaManager; |
Ruben Brunk | 7cfcafd | 2013-10-17 15:41:44 -0700 | [diff] [blame] | 149 | private PlaceholderManager mPlaceholderManager; |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 150 | private int mCurrentModuleIndex; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 151 | private CameraModule mCurrentModule; |
Angus Kong | 653c43b | 2013-08-21 18:28:43 -0700 | [diff] [blame] | 152 | private FrameLayout mAboveFilmstripControlLayout; |
| 153 | private View mCameraModuleRootView; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 154 | private FilmStripView mFilmStripView; |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 155 | private ProgressBar mBottomProgress; |
| 156 | private View mPanoStitchingPanel; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 157 | private int mResultCodeForTesting; |
| 158 | private Intent mResultDataForTesting; |
| 159 | private OnScreenHint mStorageHint; |
Angus Kong | 2dcc0a9 | 2013-09-25 13:00:08 -0700 | [diff] [blame] | 160 | private long mStorageSpaceBytes = Storage.LOW_STORAGE_THRESHOLD_BYTES; |
Doris Liu | 3cf565c | 2013-02-15 10:55:37 -0800 | [diff] [blame] | 161 | private boolean mAutoRotateScreen; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 162 | private boolean mSecureCamera; |
Angus Kong | 6a8e8a1 | 2013-07-19 14:55:07 -0700 | [diff] [blame] | 163 | // This is a hack to speed up the start of SecureCamera. |
| 164 | private static boolean sFirstStartAfterScreenOn = true; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 165 | private int mLastRawOrientation; |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 166 | private MyOrientationEventListener mOrientationListener; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 167 | private Handler mMainHandler; |
Sascha Haeberling | f1f5186 | 2013-07-31 11:28:21 -0700 | [diff] [blame] | 168 | private PanoramaViewHelper mPanoramaViewHelper; |
Angus Kong | 8e5e4ee | 2013-07-30 11:36:00 -0700 | [diff] [blame] | 169 | private CameraPreviewData mCameraPreviewData; |
ztenghui | fa9e2cc | 2013-08-09 17:37:15 -0700 | [diff] [blame] | 170 | private ActionBar mActionBar; |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 171 | private OnActionBarVisibilityListener mOnActionBarVisibilityListener = null; |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 172 | private Menu mActionBarMenu; |
Angus Kong | 653c43b | 2013-08-21 18:28:43 -0700 | [diff] [blame] | 173 | private ViewGroup mUndoDeletionBar; |
Doris Liu | 742cd5b | 2013-09-12 16:17:43 -0700 | [diff] [blame] | 174 | private boolean mIsUndoingDeletion = false; |
Doris Liu | 3cf565c | 2013-02-15 10:55:37 -0800 | [diff] [blame] | 175 | |
Mangesh Ghiware | a5682ab | 2013-09-19 09:24:23 -0700 | [diff] [blame] | 176 | private Uri[] mNfcPushUris = new Uri[1]; |
| 177 | |
Mangesh Ghiware | cd2eeb0 | 2013-08-23 13:28:21 -0700 | [diff] [blame] | 178 | private ShareActionProvider mStandardShareActionProvider; |
| 179 | private Intent mStandardShareIntent; |
| 180 | private ShareActionProvider mPanoramaShareActionProvider; |
| 181 | private Intent mPanoramaShareIntent; |
ztenghui | 064d600 | 2013-09-05 15:47:58 -0700 | [diff] [blame] | 182 | private LocalMediaObserver mLocalImagesObserver; |
| 183 | private LocalMediaObserver mLocalVideosObserver; |
Mangesh Ghiware | cd2eeb0 | 2013-08-23 13:28:21 -0700 | [diff] [blame] | 184 | |
Sascha Haeberling | 5199c20 | 2013-09-05 17:10:19 -0700 | [diff] [blame] | 185 | private final int DEFAULT_SYSTEM_UI_VISIBILITY = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
| 186 | | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; |
Doris Liu | 742cd5b | 2013-09-12 16:17:43 -0700 | [diff] [blame] | 187 | private boolean mPendingDeletion = false; |
Sascha Haeberling | 5199c20 | 2013-09-05 17:10:19 -0700 | [diff] [blame] | 188 | |
ztenghui | 0580475 | 2013-09-17 11:33:02 -0700 | [diff] [blame] | 189 | private Intent mVideoShareIntent; |
| 190 | private Intent mImageShareIntent; |
| 191 | |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 192 | private class MyOrientationEventListener |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 193 | extends OrientationEventListener { |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 194 | public MyOrientationEventListener(Context context) { |
| 195 | super(context); |
| 196 | } |
| 197 | |
| 198 | @Override |
| 199 | public void onOrientationChanged(int orientation) { |
| 200 | // We keep the last known orientation. So if the user first orient |
| 201 | // the camera then point the camera to floor or sky, we still have |
| 202 | // the correct orientation. |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 203 | if (orientation == ORIENTATION_UNKNOWN) { |
| 204 | return; |
| 205 | } |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 206 | mLastRawOrientation = orientation; |
| 207 | mCurrentModule.onOrientationChanged(orientation); |
| 208 | } |
| 209 | } |
| 210 | |
Angus Kong | fd4fc0e | 2013-11-07 15:38:09 -0800 | [diff] [blame^] | 211 | private MediaSaver mMediaSaver; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 212 | private ServiceConnection mConnection = new ServiceConnection() { |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 213 | @Override |
| 214 | public void onServiceConnected(ComponentName className, IBinder b) { |
Angus Kong | fd4fc0e | 2013-11-07 15:38:09 -0800 | [diff] [blame^] | 215 | mMediaSaver = ((MediaSaveService.LocalBinder) b).getService(); |
| 216 | mCurrentModule.onMediaSaverAvailable(mMediaSaver); |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 217 | } |
| 218 | |
| 219 | @Override |
| 220 | public void onServiceDisconnected(ComponentName className) { |
Angus Kong | fd4fc0e | 2013-11-07 15:38:09 -0800 | [diff] [blame^] | 221 | if (mMediaSaver != null) { |
| 222 | mMediaSaver.setQueueListener(null); |
| 223 | mMediaSaver = null; |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 224 | } |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 225 | } |
| 226 | }; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 227 | |
Angus Kong | 4f795b8 | 2013-09-16 14:25:35 -0700 | [diff] [blame] | 228 | private CameraOpenErrorCallback mCameraOpenErrorCallback = |
| 229 | new CameraOpenErrorCallback() { |
| 230 | @Override |
| 231 | public void onCameraDisabled(int cameraId) { |
| 232 | CameraUtil.showErrorAndFinish(CameraActivity.this, |
| 233 | R.string.camera_disabled); |
| 234 | } |
| 235 | |
| 236 | @Override |
| 237 | public void onDeviceOpenFailure(int cameraId) { |
| 238 | CameraUtil.showErrorAndFinish(CameraActivity.this, |
| 239 | R.string.cannot_connect_camera); |
| 240 | } |
| 241 | |
| 242 | @Override |
| 243 | public void onReconnectionFailure(CameraManager mgr) { |
| 244 | CameraUtil.showErrorAndFinish(CameraActivity.this, |
| 245 | R.string.cannot_connect_camera); |
| 246 | } |
| 247 | }; |
| 248 | |
Doris Liu | b84b973 | 2013-06-18 17:14:26 -0700 | [diff] [blame] | 249 | // close activity when screen turns off |
| 250 | private BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() { |
| 251 | @Override |
| 252 | public void onReceive(Context context, Intent intent) { |
| 253 | finish(); |
| 254 | } |
| 255 | }; |
| 256 | |
Angus Kong | 6a8e8a1 | 2013-07-19 14:55:07 -0700 | [diff] [blame] | 257 | private static BroadcastReceiver sScreenOffReceiver; |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 258 | |
Angus Kong | 6a8e8a1 | 2013-07-19 14:55:07 -0700 | [diff] [blame] | 259 | private static class ScreenOffReceiver extends BroadcastReceiver { |
| 260 | @Override |
| 261 | public void onReceive(Context context, Intent intent) { |
| 262 | sFirstStartAfterScreenOn = true; |
| 263 | } |
| 264 | } |
| 265 | |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 266 | private class MainHandler extends Handler { |
| 267 | public MainHandler(Looper looper) { |
| 268 | super(looper); |
| 269 | } |
| 270 | |
| 271 | @Override |
| 272 | public void handleMessage(Message msg) { |
| 273 | if (msg.what == HIDE_ACTION_BAR) { |
| 274 | removeMessages(HIDE_ACTION_BAR); |
| 275 | CameraActivity.this.setSystemBarsVisibility(false); |
| 276 | } |
| 277 | } |
| 278 | } |
| 279 | |
| 280 | public interface OnActionBarVisibilityListener { |
| 281 | public void onActionBarVisibilityChanged(boolean isVisible); |
| 282 | } |
| 283 | |
| 284 | public void setOnActionBarVisibilityListener(OnActionBarVisibilityListener listener) { |
| 285 | mOnActionBarVisibilityListener = listener; |
| 286 | } |
| 287 | |
Angus Kong | 6a8e8a1 | 2013-07-19 14:55:07 -0700 | [diff] [blame] | 288 | public static boolean isFirstStartAfterScreenOn() { |
| 289 | return sFirstStartAfterScreenOn; |
| 290 | } |
| 291 | |
| 292 | public static void resetFirstStartAfterScreenOn() { |
| 293 | sFirstStartAfterScreenOn = false; |
| 294 | } |
| 295 | |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 296 | private FilmStripView.Listener mFilmStripListener = |
| 297 | new FilmStripView.Listener() { |
| 298 | @Override |
| 299 | public void onDataPromoted(int dataID) { |
| 300 | removeData(dataID); |
| 301 | } |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 302 | |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 303 | @Override |
| 304 | public void onDataDemoted(int dataID) { |
| 305 | removeData(dataID); |
| 306 | } |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 307 | |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 308 | @Override |
| 309 | public void onDataFullScreenChange(int dataID, boolean full) { |
ztenghui | 8566dd7 | 2013-09-12 14:56:56 -0700 | [diff] [blame] | 310 | boolean isCameraID = isCameraPreview(dataID); |
ztenghui | 7b265a6 | 2013-09-09 14:58:44 -0700 | [diff] [blame] | 311 | if (!isCameraID) { |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 312 | if (!full) { |
| 313 | // Always show action bar in filmstrip mode |
| 314 | CameraActivity.this.setSystemBarsVisibility(true, false); |
| 315 | } else if (mActionBar.isShowing()) { |
| 316 | // Hide action bar after time out in full screen mode |
| 317 | mMainHandler.sendEmptyMessageDelayed(HIDE_ACTION_BAR, |
| 318 | SHOW_ACTION_BAR_TIMEOUT_MS); |
| 319 | } |
ztenghui | fa9e2cc | 2013-08-09 17:37:15 -0700 | [diff] [blame] | 320 | } |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 321 | } |
| 322 | |
ztenghui | 8566dd7 | 2013-09-12 14:56:56 -0700 | [diff] [blame] | 323 | /** |
| 324 | * Check if the local data corresponding to dataID is the camera |
| 325 | * preview. |
| 326 | * |
| 327 | * @param dataID the ID of the local data |
| 328 | * @return true if the local data is not null and it is the |
| 329 | * camera preview. |
| 330 | */ |
| 331 | private boolean isCameraPreview(int dataID) { |
| 332 | LocalData localData = mDataAdapter.getLocalData(dataID); |
| 333 | if (localData == null) { |
| 334 | Log.w(TAG, "Current data ID not found."); |
| 335 | return false; |
| 336 | } |
| 337 | return localData.getLocalDataType() == LocalData.LOCAL_CAMERA_PREVIEW; |
| 338 | } |
| 339 | |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 340 | @Override |
Erin Dahlgren | 3044d8c | 2013-10-10 18:23:45 -0700 | [diff] [blame] | 341 | public void onReload() { |
| 342 | setPreviewControlsVisibility(true); |
ztenghui | 17f1e65 | 2013-11-06 14:20:31 -0800 | [diff] [blame] | 343 | CameraActivity.this.setSystemBarsVisibility(false); |
Erin Dahlgren | 3044d8c | 2013-10-10 18:23:45 -0700 | [diff] [blame] | 344 | } |
| 345 | |
| 346 | @Override |
| 347 | public void onCurrentDataCentered(int dataID) { |
| 348 | if (dataID != 0 && !mFilmStripView.isCameraPreview()) { |
| 349 | // For now, We ignore all items that are not the camera preview. |
| 350 | return; |
| 351 | } |
| 352 | |
| 353 | if(!arePreviewControlsVisible()) { |
| 354 | setPreviewControlsVisibility(true); |
Erin Dahlgren | fd7f0a9 | 2013-10-21 10:08:54 -0700 | [diff] [blame] | 355 | CameraActivity.this.setSystemBarsVisibility(false); |
Erin Dahlgren | 3044d8c | 2013-10-10 18:23:45 -0700 | [diff] [blame] | 356 | } |
| 357 | } |
| 358 | |
| 359 | @Override |
| 360 | public void onCurrentDataOffCentered(int dataID) { |
| 361 | if (dataID != 0 && !mFilmStripView.isCameraPreview()) { |
| 362 | // For now, We ignore all items that are not the camera preview. |
| 363 | return; |
| 364 | } |
| 365 | |
| 366 | if (arePreviewControlsVisible()) { |
| 367 | setPreviewControlsVisibility(false); |
| 368 | } |
| 369 | } |
| 370 | |
| 371 | @Override |
Angus Kong | 02cafdf | 2013-10-13 19:26:02 -0700 | [diff] [blame] | 372 | public void onDataFocusChanged(final int dataID, final boolean focused) { |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 373 | // Delay hiding action bar if there is any user interaction |
| 374 | if (mMainHandler.hasMessages(HIDE_ACTION_BAR)) { |
| 375 | mMainHandler.removeMessages(HIDE_ACTION_BAR); |
| 376 | mMainHandler.sendEmptyMessageDelayed(HIDE_ACTION_BAR, |
| 377 | SHOW_ACTION_BAR_TIMEOUT_MS); |
| 378 | } |
Angus Kong | 02cafdf | 2013-10-13 19:26:02 -0700 | [diff] [blame] | 379 | // TODO: This callback is UI event callback, should always |
| 380 | // happen on UI thread. Find the reason for this |
| 381 | // runOnUiThread() and fix it. |
Mangesh Ghiware | 33035c1 | 2013-08-23 13:28:21 -0700 | [diff] [blame] | 382 | runOnUiThread(new Runnable() { |
| 383 | @Override |
| 384 | public void run() { |
ztenghui | 7b265a6 | 2013-09-09 14:58:44 -0700 | [diff] [blame] | 385 | LocalData currentData = mDataAdapter.getLocalData(dataID); |
| 386 | if (currentData == null) { |
| 387 | Log.w(TAG, "Current data ID not found."); |
| 388 | hidePanoStitchingProgress(); |
| 389 | return; |
| 390 | } |
| 391 | boolean isCameraID = currentData.getLocalDataType() == |
| 392 | LocalData.LOCAL_CAMERA_PREVIEW; |
Angus Kong | 02cafdf | 2013-10-13 19:26:02 -0700 | [diff] [blame] | 393 | if (!focused) { |
ztenghui | 7b265a6 | 2013-09-09 14:58:44 -0700 | [diff] [blame] | 394 | if (isCameraID) { |
| 395 | mCurrentModule.onPreviewFocusChanged(false); |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 396 | CameraActivity.this.setSystemBarsVisibility(true); |
ztenghui | 7b265a6 | 2013-09-09 14:58:44 -0700 | [diff] [blame] | 397 | } |
Mangesh Ghiware | 33035c1 | 2013-08-23 13:28:21 -0700 | [diff] [blame] | 398 | hidePanoStitchingProgress(); |
| 399 | } else { |
ztenghui | 7b265a6 | 2013-09-09 14:58:44 -0700 | [diff] [blame] | 400 | if (isCameraID) { |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 401 | // Don't show the action bar in Camera |
| 402 | // preview. |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 403 | CameraActivity.this.setSystemBarsVisibility(false); |
Erin Dahlgren | 3044d8c | 2013-10-10 18:23:45 -0700 | [diff] [blame] | 404 | |
Doris Liu | 742cd5b | 2013-09-12 16:17:43 -0700 | [diff] [blame] | 405 | if (mPendingDeletion) { |
| 406 | performDeletion(); |
| 407 | } |
Alan Newberger | 1ef76d4 | 2013-09-04 19:01:59 -0700 | [diff] [blame] | 408 | } else { |
| 409 | updateActionBarMenu(dataID); |
| 410 | } |
ztenghui | 2c3d9a5 | 2013-09-03 11:27:21 -0700 | [diff] [blame] | 411 | |
Mangesh Ghiware | 33035c1 | 2013-08-23 13:28:21 -0700 | [diff] [blame] | 412 | Uri contentUri = currentData.getContentUri(); |
| 413 | if (contentUri == null) { |
| 414 | hidePanoStitchingProgress(); |
| 415 | return; |
| 416 | } |
| 417 | int panoStitchingProgress = mPanoramaManager.getTaskProgress( |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 418 | contentUri); |
Mangesh Ghiware | 33035c1 | 2013-08-23 13:28:21 -0700 | [diff] [blame] | 419 | if (panoStitchingProgress < 0) { |
| 420 | hidePanoStitchingProgress(); |
| 421 | return; |
| 422 | } |
| 423 | showPanoStitchingProgress(); |
| 424 | updateStitchingProgress(panoStitchingProgress); |
| 425 | } |
ztenghui | 2c3d9a5 | 2013-09-03 11:27:21 -0700 | [diff] [blame] | 426 | } |
Mangesh Ghiware | 33035c1 | 2013-08-23 13:28:21 -0700 | [diff] [blame] | 427 | }); |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 428 | } |
Sascha Haeberling | 394023f | 2013-08-15 15:57:29 -0700 | [diff] [blame] | 429 | |
| 430 | @Override |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 431 | public void onToggleSystemDecorsVisibility(int dataID) { |
| 432 | // If action bar is showing, hide it immediately, otherwise |
| 433 | // show action bar and hide it later |
Sascha Haeberling | 394023f | 2013-08-15 15:57:29 -0700 | [diff] [blame] | 434 | if (mActionBar.isShowing()) { |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 435 | CameraActivity.this.setSystemBarsVisibility(false); |
Sascha Haeberling | 394023f | 2013-08-15 15:57:29 -0700 | [diff] [blame] | 436 | } else { |
ztenghui | 8566dd7 | 2013-09-12 14:56:56 -0700 | [diff] [blame] | 437 | // Don't show the action bar if that is the camera preview. |
| 438 | boolean isCameraID = isCameraPreview(dataID); |
| 439 | if (!isCameraID) { |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 440 | CameraActivity.this.setSystemBarsVisibility(true, true); |
ztenghui | fd43e3b | 2013-09-03 11:30:11 -0700 | [diff] [blame] | 441 | } |
Sascha Haeberling | 394023f | 2013-08-15 15:57:29 -0700 | [diff] [blame] | 442 | } |
| 443 | } |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 444 | |
| 445 | @Override |
| 446 | public void setSystemDecorsVisibility(boolean visible) { |
| 447 | CameraActivity.this.setSystemBarsVisibility(visible); |
| 448 | } |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 449 | }; |
| 450 | |
Sascha Haeberling | 4ed2059 | 2013-09-13 11:58:33 -0700 | [diff] [blame] | 451 | public void gotoGallery() { |
| 452 | mFilmStripView.getController().goToNextItem(); |
| 453 | } |
| 454 | |
Sascha Haeberling | 5199c20 | 2013-09-05 17:10:19 -0700 | [diff] [blame] | 455 | /** |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 456 | * If {@param visible} is false, this hides the action bar and switches the system UI |
| 457 | * to lights-out mode. |
Sascha Haeberling | 5199c20 | 2013-09-05 17:10:19 -0700 | [diff] [blame] | 458 | */ |
Doris Liu | 97cb1ea | 2013-10-11 16:54:51 -0700 | [diff] [blame] | 459 | // TODO: This should not be called outside of the activity. |
Sascha Haeberling | 4ec139d | 2013-10-09 23:46:20 -0700 | [diff] [blame] | 460 | public void setSystemBarsVisibility(boolean visible) { |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 461 | setSystemBarsVisibility(visible, false); |
| 462 | } |
| 463 | |
| 464 | /** |
| 465 | * If {@param visible} is false, this hides the action bar and switches the |
| 466 | * system UI to lights-out mode. If {@param hideLater} is true, a delayed message |
| 467 | * will be sent after a timeout to hide the action bar. |
| 468 | */ |
| 469 | private void setSystemBarsVisibility(boolean visible, boolean hideLater) { |
| 470 | mMainHandler.removeMessages(HIDE_ACTION_BAR); |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 471 | |
ztenghui | 17f1e65 | 2013-11-06 14:20:31 -0800 | [diff] [blame] | 472 | int currentSystemUIVisibility = mAboveFilmstripControlLayout.getSystemUiVisibility(); |
| 473 | int newSystemUIVisibility = DEFAULT_SYSTEM_UI_VISIBILITY | |
| 474 | (visible ? View.SYSTEM_UI_FLAG_VISIBLE : |
| 475 | View.SYSTEM_UI_FLAG_LOW_PROFILE | View.SYSTEM_UI_FLAG_FULLSCREEN); |
| 476 | if (newSystemUIVisibility != currentSystemUIVisibility) { |
| 477 | mAboveFilmstripControlLayout.setSystemUiVisibility(newSystemUIVisibility); |
| 478 | } |
Doris Liu | 97cb1ea | 2013-10-11 16:54:51 -0700 | [diff] [blame] | 479 | |
ztenghui | 17f1e65 | 2013-11-06 14:20:31 -0800 | [diff] [blame] | 480 | boolean currentActionBarVisibility = mActionBar.isShowing(); |
| 481 | if (visible != currentActionBarVisibility) { |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 482 | if (visible) { |
| 483 | mActionBar.show(); |
| 484 | } else { |
| 485 | mActionBar.hide(); |
| 486 | } |
| 487 | if (mOnActionBarVisibilityListener != null) { |
| 488 | mOnActionBarVisibilityListener.onActionBarVisibilityChanged(visible); |
| 489 | } |
| 490 | } |
| 491 | |
| 492 | // Now delay hiding the bars |
| 493 | if (visible && hideLater) { |
| 494 | mMainHandler.sendEmptyMessageDelayed(HIDE_ACTION_BAR, SHOW_ACTION_BAR_TIMEOUT_MS); |
Sascha Haeberling | 5199c20 | 2013-09-05 17:10:19 -0700 | [diff] [blame] | 495 | } |
Sascha Haeberling | 5199c20 | 2013-09-05 17:10:19 -0700 | [diff] [blame] | 496 | } |
| 497 | |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 498 | private void hidePanoStitchingProgress() { |
| 499 | mPanoStitchingPanel.setVisibility(View.GONE); |
| 500 | } |
| 501 | |
| 502 | private void showPanoStitchingProgress() { |
| 503 | mPanoStitchingPanel.setVisibility(View.VISIBLE); |
| 504 | } |
| 505 | |
| 506 | private void updateStitchingProgress(int progress) { |
| 507 | mBottomProgress.setProgress(progress); |
| 508 | } |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 509 | |
Mangesh Ghiware | a5682ab | 2013-09-19 09:24:23 -0700 | [diff] [blame] | 510 | @TargetApi(Build.VERSION_CODES.JELLY_BEAN) |
| 511 | private void setupNfcBeamPush() { |
| 512 | NfcAdapter adapter = NfcAdapter.getDefaultAdapter(CameraActivity.this); |
| 513 | if (adapter == null) { |
| 514 | return; |
| 515 | } |
| 516 | |
| 517 | if (!ApiHelper.HAS_SET_BEAM_PUSH_URIS) { |
| 518 | // Disable beaming |
| 519 | adapter.setNdefPushMessage(null, CameraActivity.this); |
| 520 | return; |
| 521 | } |
| 522 | |
| 523 | adapter.setBeamPushUris(null, CameraActivity.this); |
| 524 | adapter.setBeamPushUrisCallback(new CreateBeamUrisCallback() { |
| 525 | @Override |
| 526 | public Uri[] createBeamUris(NfcEvent event) { |
| 527 | return mNfcPushUris; |
| 528 | } |
| 529 | }, CameraActivity.this); |
| 530 | } |
| 531 | |
| 532 | private void setNfcBeamPushUri(Uri uri) { |
| 533 | mNfcPushUris[0] = uri; |
| 534 | } |
| 535 | |
Mangesh Ghiware | cd2eeb0 | 2013-08-23 13:28:21 -0700 | [diff] [blame] | 536 | private void setStandardShareIntent(Uri contentUri, String mimeType) { |
ztenghui | 0580475 | 2013-09-17 11:33:02 -0700 | [diff] [blame] | 537 | mStandardShareIntent = getShareIntentFromType(mimeType); |
| 538 | if (mStandardShareIntent != null) { |
| 539 | mStandardShareIntent.putExtra(Intent.EXTRA_STREAM, contentUri); |
| 540 | mStandardShareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); |
| 541 | if (mStandardShareActionProvider != null) { |
| 542 | mStandardShareActionProvider.setShareIntent(mStandardShareIntent); |
| 543 | } |
Mangesh Ghiware | cd2eeb0 | 2013-08-23 13:28:21 -0700 | [diff] [blame] | 544 | } |
ztenghui | 0580475 | 2013-09-17 11:33:02 -0700 | [diff] [blame] | 545 | } |
| 546 | |
| 547 | /** |
| 548 | * Get the share intent according to the mimeType |
| 549 | * |
| 550 | * @param mimeType The mimeType of current data. |
| 551 | * @return the video/image's ShareIntent or null if mimeType is invalid. |
| 552 | */ |
| 553 | private Intent getShareIntentFromType(String mimeType) { |
| 554 | // Lazily create the intent object. |
| 555 | if (mimeType.startsWith("video/")) { |
| 556 | if (mVideoShareIntent == null) { |
| 557 | mVideoShareIntent = new Intent(Intent.ACTION_SEND); |
| 558 | mVideoShareIntent.setType("video/*"); |
| 559 | } |
| 560 | return mVideoShareIntent; |
| 561 | } else if (mimeType.startsWith("image/")) { |
| 562 | if (mImageShareIntent == null) { |
| 563 | mImageShareIntent = new Intent(Intent.ACTION_SEND); |
| 564 | mImageShareIntent.setType("image/*"); |
| 565 | } |
| 566 | return mImageShareIntent; |
Mangesh Ghiware | cd2eeb0 | 2013-08-23 13:28:21 -0700 | [diff] [blame] | 567 | } |
ztenghui | 0580475 | 2013-09-17 11:33:02 -0700 | [diff] [blame] | 568 | Log.w(TAG, "unsupported mimeType " + mimeType); |
| 569 | return null; |
Mangesh Ghiware | cd2eeb0 | 2013-08-23 13:28:21 -0700 | [diff] [blame] | 570 | } |
| 571 | |
| 572 | private void setPanoramaShareIntent(Uri contentUri) { |
| 573 | if (mPanoramaShareIntent == null) { |
| 574 | mPanoramaShareIntent = new Intent(Intent.ACTION_SEND); |
| 575 | } |
| 576 | mPanoramaShareIntent.setType("application/vnd.google.panorama360+jpg"); |
| 577 | mPanoramaShareIntent.putExtra(Intent.EXTRA_STREAM, contentUri); |
| 578 | if (mPanoramaShareActionProvider != null) { |
| 579 | mPanoramaShareActionProvider.setShareIntent(mPanoramaShareIntent); |
| 580 | } |
| 581 | } |
| 582 | |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 583 | @Override |
| 584 | public void onMenuVisibilityChanged(boolean isVisible) { |
| 585 | // If menu is showing, we need to make sure action bar does not go away. |
| 586 | mMainHandler.removeMessages(HIDE_ACTION_BAR); |
| 587 | if (!isVisible) { |
| 588 | mMainHandler.sendEmptyMessageDelayed(HIDE_ACTION_BAR, SHOW_ACTION_BAR_TIMEOUT_MS); |
| 589 | } |
| 590 | } |
| 591 | |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 592 | /** |
| 593 | * According to the data type, make the menu items for supported operations |
| 594 | * visible. |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 595 | * |
Sascha Haeberling | fae11a1 | 2013-08-15 14:29:49 -0700 | [diff] [blame] | 596 | * @param dataID the data ID of the current item. |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 597 | */ |
Sascha Haeberling | fae11a1 | 2013-08-15 14:29:49 -0700 | [diff] [blame] | 598 | private void updateActionBarMenu(int dataID) { |
| 599 | LocalData currentData = mDataAdapter.getLocalData(dataID); |
Erin Dahlgren | d4f69ed | 2013-10-01 13:42:51 -0700 | [diff] [blame] | 600 | if (currentData == null) { |
| 601 | return; |
| 602 | } |
Sascha Haeberling | fae11a1 | 2013-08-15 14:29:49 -0700 | [diff] [blame] | 603 | int type = currentData.getLocalDataType(); |
| 604 | |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 605 | if (mActionBarMenu == null) { |
| 606 | return; |
| 607 | } |
| 608 | |
| 609 | int supported = 0; |
Angus Kong | 3250987 | 2013-10-02 16:53:40 -0700 | [diff] [blame] | 610 | |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 611 | switch (type) { |
| 612 | case LocalData.LOCAL_IMAGE: |
| 613 | supported |= SUPPORT_DELETE | SUPPORT_ROTATE | SUPPORT_INFO |
| 614 | | SUPPORT_CROP | SUPPORT_SETAS | SUPPORT_EDIT |
Mangesh Ghiware | cd2eeb0 | 2013-08-23 13:28:21 -0700 | [diff] [blame] | 615 | | SUPPORT_SHARE | SUPPORT_SHOW_ON_MAP; |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 616 | break; |
| 617 | case LocalData.LOCAL_VIDEO: |
Mangesh Ghiware | cd2eeb0 | 2013-08-23 13:28:21 -0700 | [diff] [blame] | 618 | supported |= SUPPORT_DELETE | SUPPORT_INFO | SUPPORT_TRIM |
| 619 | | SUPPORT_SHARE; |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 620 | break; |
| 621 | case LocalData.LOCAL_PHOTO_SPHERE: |
| 622 | supported |= SUPPORT_DELETE | SUPPORT_ROTATE | SUPPORT_INFO |
| 623 | | SUPPORT_CROP | SUPPORT_SETAS | SUPPORT_EDIT |
Mangesh Ghiware | cd2eeb0 | 2013-08-23 13:28:21 -0700 | [diff] [blame] | 624 | | SUPPORT_SHARE | SUPPORT_SHOW_ON_MAP; |
| 625 | break; |
| 626 | case LocalData.LOCAL_360_PHOTO_SPHERE: |
| 627 | supported |= SUPPORT_DELETE | SUPPORT_ROTATE | SUPPORT_INFO |
| 628 | | SUPPORT_CROP | SUPPORT_SETAS | SUPPORT_EDIT |
| 629 | | SUPPORT_SHARE | SUPPORT_SHARE_PANORAMA360 |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 630 | | SUPPORT_SHOW_ON_MAP; |
| 631 | break; |
| 632 | default: |
| 633 | break; |
| 634 | } |
| 635 | |
ztenghui | e941cbe | 2013-10-02 17:31:47 -0700 | [diff] [blame] | 636 | // In secure camera mode, we only support delete operation. |
| 637 | if (isSecureCamera()) { |
| 638 | supported &= SUPPORT_DELETE; |
| 639 | } |
| 640 | |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 641 | setMenuItemVisible(mActionBarMenu, R.id.action_delete, |
| 642 | (supported & SUPPORT_DELETE) != 0); |
| 643 | setMenuItemVisible(mActionBarMenu, R.id.action_rotate_ccw, |
| 644 | (supported & SUPPORT_ROTATE) != 0); |
| 645 | setMenuItemVisible(mActionBarMenu, R.id.action_rotate_cw, |
| 646 | (supported & SUPPORT_ROTATE) != 0); |
Mangesh Ghiware | cd2eeb0 | 2013-08-23 13:28:21 -0700 | [diff] [blame] | 647 | setMenuItemVisible(mActionBarMenu, R.id.action_details, |
| 648 | (supported & SUPPORT_INFO) != 0); |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 649 | setMenuItemVisible(mActionBarMenu, R.id.action_crop, |
| 650 | (supported & SUPPORT_CROP) != 0); |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 651 | setMenuItemVisible(mActionBarMenu, R.id.action_setas, |
| 652 | (supported & SUPPORT_SETAS) != 0); |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 653 | setMenuItemVisible(mActionBarMenu, R.id.action_edit, |
| 654 | (supported & SUPPORT_EDIT) != 0); |
Mangesh Ghiware | cd2eeb0 | 2013-08-23 13:28:21 -0700 | [diff] [blame] | 655 | setMenuItemVisible(mActionBarMenu, R.id.action_trim, |
| 656 | (supported & SUPPORT_TRIM) != 0); |
| 657 | |
Mangesh Ghiware | 33035c1 | 2013-08-23 13:28:21 -0700 | [diff] [blame] | 658 | boolean standardShare = (supported & SUPPORT_SHARE) != 0; |
| 659 | boolean panoramaShare = (supported & SUPPORT_SHARE_PANORAMA360) != 0; |
| 660 | setMenuItemVisible(mActionBarMenu, R.id.action_share, standardShare); |
| 661 | setMenuItemVisible(mActionBarMenu, R.id.action_share_panorama, panoramaShare); |
| 662 | |
| 663 | if (panoramaShare) { |
| 664 | // For 360 PhotoSphere, relegate standard share to the overflow menu |
| 665 | MenuItem item = mActionBarMenu.findItem(R.id.action_share); |
| 666 | if (item != null) { |
| 667 | item.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); |
| 668 | item.setTitle(getResources().getString(R.string.share_as_photo)); |
| 669 | } |
| 670 | // And, promote "share as panorama" to action bar |
| 671 | item = mActionBarMenu.findItem(R.id.action_share_panorama); |
| 672 | if (item != null) { |
| 673 | item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); |
| 674 | } |
Mangesh Ghiware | cd2eeb0 | 2013-08-23 13:28:21 -0700 | [diff] [blame] | 675 | setPanoramaShareIntent(currentData.getContentUri()); |
| 676 | } |
Mangesh Ghiware | 33035c1 | 2013-08-23 13:28:21 -0700 | [diff] [blame] | 677 | if (standardShare) { |
| 678 | if (!panoramaShare) { |
| 679 | MenuItem item = mActionBarMenu.findItem(R.id.action_share); |
| 680 | if (item != null) { |
| 681 | item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); |
| 682 | item.setTitle(getResources().getString(R.string.share)); |
| 683 | } |
| 684 | } |
| 685 | setStandardShareIntent(currentData.getContentUri(), currentData.getMimeType()); |
Mangesh Ghiware | a5682ab | 2013-09-19 09:24:23 -0700 | [diff] [blame] | 686 | setNfcBeamPushUri(currentData.getContentUri()); |
Mangesh Ghiware | 33035c1 | 2013-08-23 13:28:21 -0700 | [diff] [blame] | 687 | } |
Sascha Haeberling | fae11a1 | 2013-08-15 14:29:49 -0700 | [diff] [blame] | 688 | |
| 689 | boolean itemHasLocation = currentData.getLatLong() != null; |
| 690 | setMenuItemVisible(mActionBarMenu, R.id.action_show_on_map, |
| 691 | itemHasLocation && (supported & SUPPORT_SHOW_ON_MAP) != 0); |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 692 | } |
| 693 | |
| 694 | private void setMenuItemVisible(Menu menu, int itemId, boolean visible) { |
| 695 | MenuItem item = menu.findItem(itemId); |
| 696 | if (item != null) |
| 697 | item.setVisible(visible); |
| 698 | } |
| 699 | |
Ruben Brunk | 7cfcafd | 2013-10-17 15:41:44 -0700 | [diff] [blame] | 700 | private ImageTaskManager.TaskListener mPlaceholderListener = |
| 701 | new ImageTaskManager.TaskListener() { |
| 702 | |
| 703 | @Override |
| 704 | public void onTaskQueued(String filePath, final Uri imageUri) { |
| 705 | mMainHandler.post(new Runnable() { |
| 706 | @Override |
| 707 | public void run() { |
| 708 | notifyNewMedia(imageUri); |
| 709 | int dataID = mDataAdapter.findDataByContentUri(imageUri); |
| 710 | if (dataID != -1) { |
| 711 | LocalData d = mDataAdapter.getLocalData(dataID); |
| 712 | InProgressDataWrapper newData = new InProgressDataWrapper(d, true); |
| 713 | mDataAdapter.updateData(dataID, newData); |
| 714 | } |
| 715 | } |
| 716 | }); |
| 717 | } |
| 718 | |
| 719 | @Override |
| 720 | public void onTaskDone(String filePath, final Uri imageUri) { |
| 721 | mMainHandler.post(new Runnable() { |
| 722 | @Override |
| 723 | public void run() { |
| 724 | mDataAdapter.refresh(getContentResolver(), imageUri); |
| 725 | } |
| 726 | }); |
| 727 | } |
| 728 | |
| 729 | @Override |
| 730 | public void onTaskProgress(String filePath, Uri imageUri, int progress) { |
| 731 | // Do nothing |
| 732 | } |
| 733 | }; |
| 734 | |
Angus Kong | 6798c34 | 2013-07-16 15:14:58 -0700 | [diff] [blame] | 735 | private ImageTaskManager.TaskListener mStitchingListener = |
| 736 | new ImageTaskManager.TaskListener() { |
| 737 | @Override |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 738 | public void onTaskQueued(String filePath, final Uri imageUri) { |
| 739 | mMainHandler.post(new Runnable() { |
| 740 | @Override |
| 741 | public void run() { |
| 742 | notifyNewMedia(imageUri); |
Angus Kong | 3250987 | 2013-10-02 16:53:40 -0700 | [diff] [blame] | 743 | int dataID = mDataAdapter.findDataByContentUri(imageUri); |
| 744 | if (dataID != -1) { |
| 745 | // Don't allow special UI actions (swipe to |
| 746 | // delete, for example) on in-progress data. |
| 747 | LocalData d = mDataAdapter.getLocalData(dataID); |
| 748 | InProgressDataWrapper newData = new InProgressDataWrapper(d); |
| 749 | mDataAdapter.updateData(dataID, newData); |
| 750 | } |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 751 | } |
| 752 | }); |
Angus Kong | 6798c34 | 2013-07-16 15:14:58 -0700 | [diff] [blame] | 753 | } |
| 754 | |
| 755 | @Override |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 756 | public void onTaskDone(String filePath, final Uri imageUri) { |
| 757 | Log.v(TAG, "onTaskDone:" + filePath); |
| 758 | mMainHandler.post(new Runnable() { |
| 759 | @Override |
| 760 | public void run() { |
| 761 | int doneID = mDataAdapter.findDataByContentUri(imageUri); |
| 762 | int currentDataId = mFilmStripView.getCurrentId(); |
| 763 | |
| 764 | if (currentDataId == doneID) { |
| 765 | hidePanoStitchingProgress(); |
| 766 | updateStitchingProgress(0); |
| 767 | } |
| 768 | |
| 769 | mDataAdapter.refresh(getContentResolver(), imageUri); |
| 770 | } |
| 771 | }); |
Angus Kong | 6798c34 | 2013-07-16 15:14:58 -0700 | [diff] [blame] | 772 | } |
| 773 | |
| 774 | @Override |
| 775 | public void onTaskProgress( |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 776 | String filePath, final Uri imageUri, final int progress) { |
| 777 | mMainHandler.post(new Runnable() { |
| 778 | @Override |
| 779 | public void run() { |
| 780 | int currentDataId = mFilmStripView.getCurrentId(); |
| 781 | if (currentDataId == -1) { |
| 782 | return; |
| 783 | } |
| 784 | if (imageUri.equals( |
| 785 | mDataAdapter.getLocalData(currentDataId).getContentUri())) { |
| 786 | updateStitchingProgress(progress); |
| 787 | } |
| 788 | } |
| 789 | }); |
Angus Kong | 6798c34 | 2013-07-16 15:14:58 -0700 | [diff] [blame] | 790 | } |
| 791 | }; |
| 792 | |
Angus Kong | fd4fc0e | 2013-11-07 15:38:09 -0800 | [diff] [blame^] | 793 | public MediaSaver getMediaSaver() { |
| 794 | return mMediaSaver; |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 795 | } |
| 796 | |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 797 | public void notifyNewMedia(Uri uri) { |
| 798 | ContentResolver cr = getContentResolver(); |
| 799 | String mimeType = cr.getType(uri); |
| 800 | if (mimeType.startsWith("video/")) { |
Angus Kong | b50b5cb | 2013-08-09 14:55:20 -0700 | [diff] [blame] | 801 | sendBroadcast(new Intent(CameraUtil.ACTION_NEW_VIDEO, uri)); |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 802 | mDataAdapter.addNewVideo(cr, uri); |
| 803 | } else if (mimeType.startsWith("image/")) { |
Angus Kong | b50b5cb | 2013-08-09 14:55:20 -0700 | [diff] [blame] | 804 | CameraUtil.broadcastNewPicture(this, uri); |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 805 | mDataAdapter.addNewPhoto(cr, uri); |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 806 | } else if (mimeType.startsWith("application/stitching-preview")) { |
| 807 | mDataAdapter.addNewPhoto(cr, uri); |
Ruben Brunk | 7cfcafd | 2013-10-17 15:41:44 -0700 | [diff] [blame] | 808 | } else if (mimeType.startsWith(PlaceholderManager.PLACEHOLDER_MIME_TYPE)) { |
| 809 | mDataAdapter.addNewPhoto(cr, uri); |
Doris Liu | 48239f4 | 2013-03-04 22:19:10 -0800 | [diff] [blame] | 810 | } else { |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 811 | android.util.Log.w(TAG, "Unknown new media with MIME type:" |
| 812 | + mimeType + ", uri:" + uri); |
Doris Liu | 48239f4 | 2013-03-04 22:19:10 -0800 | [diff] [blame] | 813 | } |
| 814 | } |
| 815 | |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 816 | private void removeData(int dataID) { |
| 817 | mDataAdapter.removeData(CameraActivity.this, dataID); |
Doris Liu | 742cd5b | 2013-09-12 16:17:43 -0700 | [diff] [blame] | 818 | if (mDataAdapter.getTotalNumber() > 1) { |
| 819 | showUndoDeletionBar(); |
| 820 | } else { |
| 821 | // If camera preview is the only view left in filmstrip, |
| 822 | // no need to show undo bar. |
Doris Liu | f2c1433 | 2013-09-26 11:24:37 -0700 | [diff] [blame] | 823 | mPendingDeletion = true; |
Doris Liu | 742cd5b | 2013-09-12 16:17:43 -0700 | [diff] [blame] | 824 | performDeletion(); |
| 825 | } |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 826 | } |
| 827 | |
Angus Kong | 86d3631 | 2013-01-31 18:22:44 -0800 | [diff] [blame] | 828 | private void bindMediaSaveService() { |
| 829 | Intent intent = new Intent(this, MediaSaveService.class); |
Angus Kong | 86d3631 | 2013-01-31 18:22:44 -0800 | [diff] [blame] | 830 | bindService(intent, mConnection, Context.BIND_AUTO_CREATE); |
| 831 | } |
| 832 | |
| 833 | private void unbindMediaSaveService() { |
Michael Kolb | 955e5c5 | 2013-03-22 14:11:57 -0700 | [diff] [blame] | 834 | if (mConnection != null) { |
| 835 | unbindService(mConnection); |
| 836 | } |
Angus Kong | 86d3631 | 2013-01-31 18:22:44 -0800 | [diff] [blame] | 837 | } |
| 838 | |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 839 | @Override |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 840 | public boolean onCreateOptionsMenu(Menu menu) { |
| 841 | // Inflate the menu items for use in the action bar |
| 842 | MenuInflater inflater = getMenuInflater(); |
| 843 | inflater.inflate(R.menu.operations, menu); |
| 844 | mActionBarMenu = menu; |
Mangesh Ghiware | cd2eeb0 | 2013-08-23 13:28:21 -0700 | [diff] [blame] | 845 | |
| 846 | // Configure the standard share action provider |
| 847 | MenuItem item = menu.findItem(R.id.action_share); |
| 848 | mStandardShareActionProvider = (ShareActionProvider) item.getActionProvider(); |
Mangesh Ghiware | 33035c1 | 2013-08-23 13:28:21 -0700 | [diff] [blame] | 849 | mStandardShareActionProvider.setShareHistoryFileName("standard_share_history.xml"); |
Mangesh Ghiware | cd2eeb0 | 2013-08-23 13:28:21 -0700 | [diff] [blame] | 850 | if (mStandardShareIntent != null) { |
| 851 | mStandardShareActionProvider.setShareIntent(mStandardShareIntent); |
| 852 | } |
| 853 | |
| 854 | // Configure the panorama share action provider |
| 855 | item = menu.findItem(R.id.action_share_panorama); |
| 856 | mPanoramaShareActionProvider = (ShareActionProvider) item.getActionProvider(); |
Mangesh Ghiware | 33035c1 | 2013-08-23 13:28:21 -0700 | [diff] [blame] | 857 | mPanoramaShareActionProvider.setShareHistoryFileName("panorama_share_history.xml"); |
Mangesh Ghiware | cd2eeb0 | 2013-08-23 13:28:21 -0700 | [diff] [blame] | 858 | if (mPanoramaShareIntent != null) { |
| 859 | mPanoramaShareActionProvider.setShareIntent(mPanoramaShareIntent); |
| 860 | } |
| 861 | |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 862 | return super.onCreateOptionsMenu(menu); |
| 863 | } |
| 864 | |
| 865 | @Override |
| 866 | public boolean onOptionsItemSelected(MenuItem item) { |
Sascha Haeberling | 6f64b50 | 2013-08-14 16:23:18 -0700 | [diff] [blame] | 867 | int currentDataId = mFilmStripView.getCurrentId(); |
| 868 | if (currentDataId < 0) { |
| 869 | return false; |
| 870 | } |
| 871 | final LocalData localData = mDataAdapter.getLocalData(currentDataId); |
| 872 | |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 873 | // Handle presses on the action bar items |
| 874 | switch (item.getItemId()) { |
Alan Newberger | 3f969c1 | 2013-08-23 10:10:30 -0700 | [diff] [blame] | 875 | case android.R.id.home: |
| 876 | // ActionBar's Up/Home button was clicked |
Mangesh Ghiware | 30968d0 | 2013-10-02 14:38:12 -0700 | [diff] [blame] | 877 | try { |
Alan Newberger | 761306f | 2013-10-30 12:51:21 -0700 | [diff] [blame] | 878 | startActivity(IntentHelper.getGalleryIntent(this)); |
Mangesh Ghiware | 30968d0 | 2013-10-02 14:38:12 -0700 | [diff] [blame] | 879 | return true; |
| 880 | } catch (ActivityNotFoundException e) { |
Alan Newberger | 761306f | 2013-10-30 12:51:21 -0700 | [diff] [blame] | 881 | Log.w(TAG, "Failed to launch gallery activity, closing"); |
Mangesh Ghiware | 30968d0 | 2013-10-02 14:38:12 -0700 | [diff] [blame] | 882 | finish(); |
Mangesh Ghiware | 5df64b0 | 2013-09-18 18:25:26 -0700 | [diff] [blame] | 883 | } |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 884 | case R.id.action_delete: |
Angus Kong | e857cc9 | 2013-08-19 14:46:20 -0700 | [diff] [blame] | 885 | removeData(currentDataId); |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 886 | return true; |
| 887 | case R.id.action_edit: |
Sascha Haeberling | 88ef766 | 2013-08-15 17:19:22 -0700 | [diff] [blame] | 888 | launchEditor(localData); |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 889 | return true; |
nicolasroard | 0819304 | 2013-08-20 09:19:23 -0700 | [diff] [blame] | 890 | case R.id.action_trim: { |
ztenghui | 6b92032 | 2013-08-16 16:21:22 -0700 | [diff] [blame] | 891 | // This is going to be handled by the Gallery app. |
| 892 | Intent intent = new Intent(ACTION_TRIM_VIDEO); |
| 893 | LocalData currentData = mDataAdapter.getLocalData( |
| 894 | mFilmStripView.getCurrentId()); |
| 895 | intent.setData(currentData.getContentUri()); |
| 896 | // We need the file path to wrap this into a RandomAccessFile. |
| 897 | intent.putExtra(MEDIA_ITEM_PATH, currentData.getPath()); |
Sascha Haeberling | b7639c6 | 2013-09-09 14:42:43 -0700 | [diff] [blame] | 898 | startActivityForResult(intent, REQ_CODE_DONT_SWITCH_TO_PREVIEW); |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 899 | return true; |
nicolasroard | 0819304 | 2013-08-20 09:19:23 -0700 | [diff] [blame] | 900 | } |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 901 | case R.id.action_rotate_ccw: |
ztenghui | a16e7b5 | 2013-08-23 11:47:56 -0700 | [diff] [blame] | 902 | localData.rotate90Degrees(this, mDataAdapter, currentDataId, false); |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 903 | return true; |
| 904 | case R.id.action_rotate_cw: |
ztenghui | a16e7b5 | 2013-08-23 11:47:56 -0700 | [diff] [blame] | 905 | localData.rotate90Degrees(this, mDataAdapter, currentDataId, true); |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 906 | return true; |
nicolasroard | 19ab725 | 2013-09-18 16:54:05 -0700 | [diff] [blame] | 907 | case R.id.action_crop: { |
| 908 | Intent intent = new Intent(CropActivity.CROP_ACTION); |
| 909 | intent.setClass(this, CropActivity.class); |
| 910 | intent.setDataAndType(localData.getContentUri(), localData.getMimeType()) |
| 911 | .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); |
| 912 | startActivityForResult(intent, REQ_CODE_DONT_SWITCH_TO_PREVIEW); |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 913 | return true; |
nicolasroard | 19ab725 | 2013-09-18 16:54:05 -0700 | [diff] [blame] | 914 | } |
nicolasroard | 0819304 | 2013-08-20 09:19:23 -0700 | [diff] [blame] | 915 | case R.id.action_setas: { |
| 916 | Intent intent = new Intent(Intent.ACTION_ATTACH_DATA) |
| 917 | .setDataAndType(localData.getContentUri(), |
| 918 | localData.getMimeType()) |
| 919 | .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); |
| 920 | intent.putExtra("mimeType", intent.getType()); |
Sascha Haeberling | b7639c6 | 2013-09-09 14:42:43 -0700 | [diff] [blame] | 921 | startActivityForResult(Intent.createChooser( |
| 922 | intent, getString(R.string.set_as)), REQ_CODE_DONT_SWITCH_TO_PREVIEW); |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 923 | return true; |
nicolasroard | 0819304 | 2013-08-20 09:19:23 -0700 | [diff] [blame] | 924 | } |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 925 | case R.id.action_details: |
Sascha Haeberling | 6f64b50 | 2013-08-14 16:23:18 -0700 | [diff] [blame] | 926 | (new AsyncTask<Void, Void, MediaDetails>() { |
| 927 | @Override |
| 928 | protected MediaDetails doInBackground(Void... params) { |
| 929 | return localData.getMediaDetails(CameraActivity.this); |
| 930 | } |
| 931 | |
| 932 | @Override |
| 933 | protected void onPostExecute(MediaDetails mediaDetails) { |
Sascha Haeberling | 64cea6a | 2013-10-10 20:12:07 -0700 | [diff] [blame] | 934 | if (mediaDetails != null) { |
| 935 | DetailsDialog.create(CameraActivity.this, mediaDetails).show(); |
| 936 | } |
Sascha Haeberling | 6f64b50 | 2013-08-14 16:23:18 -0700 | [diff] [blame] | 937 | } |
| 938 | }).execute(); |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 939 | return true; |
| 940 | case R.id.action_show_on_map: |
Sascha Haeberling | fae11a1 | 2013-08-15 14:29:49 -0700 | [diff] [blame] | 941 | double[] latLong = localData.getLatLong(); |
| 942 | if (latLong != null) { |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 943 | CameraUtil.showOnMap(this, latLong); |
Sascha Haeberling | fae11a1 | 2013-08-15 14:29:49 -0700 | [diff] [blame] | 944 | } |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 945 | return true; |
| 946 | default: |
| 947 | return super.onOptionsItemSelected(item); |
| 948 | } |
| 949 | } |
| 950 | |
ztenghui | fd43e3b | 2013-09-03 11:30:11 -0700 | [diff] [blame] | 951 | private boolean isCaptureIntent() { |
| 952 | if (MediaStore.ACTION_VIDEO_CAPTURE.equals(getIntent().getAction()) |
| 953 | || MediaStore.ACTION_IMAGE_CAPTURE.equals(getIntent().getAction()) |
| 954 | || MediaStore.ACTION_IMAGE_CAPTURE_SECURE.equals(getIntent().getAction())) { |
| 955 | return true; |
| 956 | } else { |
| 957 | return false; |
| 958 | } |
| 959 | } |
| 960 | |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 961 | @Override |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 962 | public void onCreate(Bundle state) { |
| 963 | super.onCreate(state); |
Sascha Haeberling | 048bf4d | 2013-10-06 17:49:51 -0700 | [diff] [blame] | 964 | GcamHelper.init(getContentResolver()); |
| 965 | |
ztenghui | 50df470 | 2013-08-13 15:53:57 -0700 | [diff] [blame] | 966 | getWindow().requestFeature(Window.FEATURE_ACTION_BAR); |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 967 | setContentView(R.layout.camera_filmstrip); |
ztenghui | fa9e2cc | 2013-08-09 17:37:15 -0700 | [diff] [blame] | 968 | mActionBar = getActionBar(); |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 969 | mActionBar.addOnMenuVisibilityListener(this); |
ztenghui | fa9e2cc | 2013-08-09 17:37:15 -0700 | [diff] [blame] | 970 | |
Michael Kolb | 0865018 | 2013-02-25 19:43:56 -0800 | [diff] [blame] | 971 | if (ApiHelper.HAS_ROTATION_ANIMATION) { |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 972 | setRotationAnimation(); |
Michael Kolb | 0865018 | 2013-02-25 19:43:56 -0800 | [diff] [blame] | 973 | } |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 974 | |
| 975 | mMainHandler = new MainHandler(getMainLooper()); |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 976 | // Check if this is in the secure camera mode. |
| 977 | Intent intent = getIntent(); |
| 978 | String action = intent.getAction(); |
Doris Liu | b84b973 | 2013-06-18 17:14:26 -0700 | [diff] [blame] | 979 | if (INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE.equals(action) |
| 980 | || ACTION_IMAGE_CAPTURE_SECURE.equals(action)) { |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 981 | mSecureCamera = true; |
| 982 | } else { |
| 983 | mSecureCamera = intent.getBooleanExtra(SECURE_CAMERA_EXTRA, false); |
| 984 | } |
Doris Liu | b84b973 | 2013-06-18 17:14:26 -0700 | [diff] [blame] | 985 | |
| 986 | if (mSecureCamera) { |
| 987 | // Change the window flags so that secure camera can show when locked |
| 988 | Window win = getWindow(); |
| 989 | WindowManager.LayoutParams params = win.getAttributes(); |
| 990 | params.flags |= WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; |
| 991 | win.setAttributes(params); |
| 992 | |
| 993 | // Filter for screen off so that we can finish secure camera activity |
| 994 | // when screen is off. |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 995 | IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF); |
| 996 | registerReceiver(mScreenOffReceiver, filter); |
Angus Kong | 6a8e8a1 | 2013-07-19 14:55:07 -0700 | [diff] [blame] | 997 | // TODO: This static screen off event receiver is a workaround to the |
| 998 | // double onResume() invocation (onResume->onPause->onResume). We should |
| 999 | // find a better solution to this. |
| 1000 | if (sScreenOffReceiver == null) { |
| 1001 | sScreenOffReceiver = new ScreenOffReceiver(); |
| 1002 | registerReceiver(sScreenOffReceiver, filter); |
| 1003 | } |
Doris Liu | b84b973 | 2013-06-18 17:14:26 -0700 | [diff] [blame] | 1004 | } |
Angus Kong | 653c43b | 2013-08-21 18:28:43 -0700 | [diff] [blame] | 1005 | mAboveFilmstripControlLayout = |
| 1006 | (FrameLayout) findViewById(R.id.camera_above_filmstrip_layout); |
| 1007 | mAboveFilmstripControlLayout.setFitsSystemWindows(true); |
Sascha Haeberling | 5199c20 | 2013-09-05 17:10:19 -0700 | [diff] [blame] | 1008 | // Hide action bar first since we are in full screen mode first, and |
| 1009 | // switch the system UI to lights-out mode. |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 1010 | this.setSystemBarsVisibility(false); |
Angus Kong | ed15d1a | 2013-08-19 15:06:12 -0700 | [diff] [blame] | 1011 | mPanoramaManager = AppManagerFactory.getInstance(this) |
| 1012 | .getPanoramaStitchingManager(); |
Ruben Brunk | 7cfcafd | 2013-10-17 15:41:44 -0700 | [diff] [blame] | 1013 | mPlaceholderManager = AppManagerFactory.getInstance(this) |
| 1014 | .getGcamProcessingManager(); |
Angus Kong | 6798c34 | 2013-07-16 15:14:58 -0700 | [diff] [blame] | 1015 | mPanoramaManager.addTaskListener(mStitchingListener); |
Ruben Brunk | 7cfcafd | 2013-10-17 15:41:44 -0700 | [diff] [blame] | 1016 | mPlaceholderManager.addTaskListener(mPlaceholderListener); |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1017 | LayoutInflater inflater = getLayoutInflater(); |
| 1018 | View rootLayout = inflater.inflate(R.layout.camera, null, false); |
Angus Kong | 653c43b | 2013-08-21 18:28:43 -0700 | [diff] [blame] | 1019 | mCameraModuleRootView = rootLayout.findViewById(R.id.camera_app_root); |
ztenghui | fa9e2cc | 2013-08-09 17:37:15 -0700 | [diff] [blame] | 1020 | mPanoStitchingPanel = findViewById(R.id.pano_stitching_progress_panel); |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 1021 | mBottomProgress = (ProgressBar) findViewById(R.id.pano_stitching_progress_bar); |
Angus Kong | 8e5e4ee | 2013-07-30 11:36:00 -0700 | [diff] [blame] | 1022 | mCameraPreviewData = new CameraPreviewData(rootLayout, |
| 1023 | FilmStripView.ImageData.SIZE_FULL, |
| 1024 | FilmStripView.ImageData.SIZE_FULL); |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 1025 | // Put a CameraPreviewData at the first position. |
Angus Kong | 8e5e4ee | 2013-07-30 11:36:00 -0700 | [diff] [blame] | 1026 | mWrappedDataAdapter = new FixedFirstDataAdapter( |
| 1027 | new CameraDataAdapter(new ColorDrawable( |
| 1028 | getResources().getColor(R.color.photo_placeholder))), |
| 1029 | mCameraPreviewData); |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1030 | mFilmStripView = (FilmStripView) findViewById(R.id.filmstrip_view); |
| 1031 | mFilmStripView.setViewGap( |
| 1032 | getResources().getDimensionPixelSize(R.dimen.camera_film_strip_gap)); |
Sascha Haeberling | f1f5186 | 2013-07-31 11:28:21 -0700 | [diff] [blame] | 1033 | mPanoramaViewHelper = new PanoramaViewHelper(this); |
| 1034 | mPanoramaViewHelper.onCreate(); |
| 1035 | mFilmStripView.setPanoramaViewHelper(mPanoramaViewHelper); |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1036 | // Set up the camera preview first so the preview shows up ASAP. |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1037 | mFilmStripView.setListener(mFilmStripListener); |
Sascha Haeberling | 2654dd9 | 2013-08-28 15:28:57 -0700 | [diff] [blame] | 1038 | |
| 1039 | int moduleIndex = -1; |
Doris Liu | 2a7f44c | 2013-08-12 15:18:53 -0700 | [diff] [blame] | 1040 | if (MediaStore.INTENT_ACTION_VIDEO_CAMERA.equals(getIntent().getAction()) |
| 1041 | || MediaStore.ACTION_VIDEO_CAPTURE.equals(getIntent().getAction())) { |
Angus Kong | ed15d1a | 2013-08-19 15:06:12 -0700 | [diff] [blame] | 1042 | moduleIndex = ModuleSwitcher.VIDEO_MODULE_INDEX; |
Sascha Haeberling | 2654dd9 | 2013-08-28 15:28:57 -0700 | [diff] [blame] | 1043 | } else if (MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA.equals(getIntent().getAction()) |
| 1044 | || MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE.equals(getIntent() |
| 1045 | .getAction()) |
| 1046 | || MediaStore.ACTION_IMAGE_CAPTURE.equals(getIntent().getAction()) |
| 1047 | || MediaStore.ACTION_IMAGE_CAPTURE_SECURE.equals(getIntent().getAction())) { |
Angus Kong | ed15d1a | 2013-08-19 15:06:12 -0700 | [diff] [blame] | 1048 | moduleIndex = ModuleSwitcher.PHOTO_MODULE_INDEX; |
Doris Liu | 2a7f44c | 2013-08-12 15:18:53 -0700 | [diff] [blame] | 1049 | } else { |
Sascha Haeberling | 2654dd9 | 2013-08-28 15:28:57 -0700 | [diff] [blame] | 1050 | // If the activity has not been started using an explicit intent, |
| 1051 | // read the module index from the last time the user changed modes |
| 1052 | SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); |
Angus Kong | 0fb819b | 2013-10-08 13:44:19 -0700 | [diff] [blame] | 1053 | moduleIndex = prefs.getInt(CameraSettings.KEY_STARTUP_MODULE_INDEX, -1); |
Ruben Brunk | a9d66bd | 2013-09-06 11:56:32 -0700 | [diff] [blame] | 1054 | if ((moduleIndex == ModuleSwitcher.GCAM_MODULE_INDEX && |
Sascha Haeberling | 98f38bb | 2013-09-24 18:58:34 -0700 | [diff] [blame] | 1055 | !GcamHelper.hasGcamCapture()) || moduleIndex < 0) { |
Angus Kong | ed15d1a | 2013-08-19 15:06:12 -0700 | [diff] [blame] | 1056 | moduleIndex = ModuleSwitcher.PHOTO_MODULE_INDEX; |
Sascha Haeberling | 2654dd9 | 2013-08-28 15:28:57 -0700 | [diff] [blame] | 1057 | } |
Doris Liu | 2a7f44c | 2013-08-12 15:18:53 -0700 | [diff] [blame] | 1058 | } |
Sascha Haeberling | 2654dd9 | 2013-08-28 15:28:57 -0700 | [diff] [blame] | 1059 | |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1060 | mOrientationListener = new MyOrientationEventListener(this); |
Angus Kong | ed15d1a | 2013-08-19 15:06:12 -0700 | [diff] [blame] | 1061 | setModuleFromIndex(moduleIndex); |
| 1062 | mCurrentModule.init(this, mCameraModuleRootView); |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 1063 | |
| 1064 | if (!mSecureCamera) { |
| 1065 | mDataAdapter = mWrappedDataAdapter; |
Angus Kong | dcccc51 | 2013-08-08 17:06:03 -0700 | [diff] [blame] | 1066 | mFilmStripView.setDataAdapter(mDataAdapter); |
Angus Kong | a719460 | 2013-09-06 17:20:15 -0700 | [diff] [blame] | 1067 | if (!isCaptureIntent()) { |
| 1068 | mDataAdapter.requestLoad(getContentResolver()); |
| 1069 | } |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 1070 | } else { |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 1071 | // Put a lock placeholder as the last image by setting its date to |
| 1072 | // 0. |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 1073 | ImageView v = (ImageView) getLayoutInflater().inflate( |
| 1074 | R.layout.secure_album_placeholder, null); |
Angus Kong | 690dc47 | 2013-09-21 14:48:51 -0700 | [diff] [blame] | 1075 | v.setOnClickListener(new View.OnClickListener() { |
| 1076 | @Override |
| 1077 | public void onClick(View view) { |
Alan Newberger | 761306f | 2013-10-30 12:51:21 -0700 | [diff] [blame] | 1078 | try { |
| 1079 | startActivity(IntentHelper.getGalleryIntent(CameraActivity.this)); |
| 1080 | } catch (ActivityNotFoundException e) { |
| 1081 | Log.w(TAG, "Failed to launch gallery activity, closing"); |
| 1082 | } |
Angus Kong | 690dc47 | 2013-09-21 14:48:51 -0700 | [diff] [blame] | 1083 | finish(); |
| 1084 | } |
| 1085 | }); |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 1086 | mDataAdapter = new FixedLastDataAdapter( |
| 1087 | mWrappedDataAdapter, |
Angus Kong | bd26069 | 2013-08-07 14:52:56 -0700 | [diff] [blame] | 1088 | new SimpleViewData( |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 1089 | v, |
| 1090 | v.getDrawable().getIntrinsicWidth(), |
| 1091 | v.getDrawable().getIntrinsicHeight(), |
| 1092 | 0, 0)); |
| 1093 | // Flush out all the original data. |
| 1094 | mDataAdapter.flush(); |
Angus Kong | dcccc51 | 2013-08-08 17:06:03 -0700 | [diff] [blame] | 1095 | mFilmStripView.setDataAdapter(mDataAdapter); |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 1096 | } |
Mangesh Ghiware | a5682ab | 2013-09-19 09:24:23 -0700 | [diff] [blame] | 1097 | |
| 1098 | setupNfcBeamPush(); |
ztenghui | 064d600 | 2013-09-05 15:47:58 -0700 | [diff] [blame] | 1099 | |
Doris Liu | 2b86d87 | 2013-09-26 15:23:41 -0700 | [diff] [blame] | 1100 | mLocalImagesObserver = new LocalMediaObserver(); |
| 1101 | mLocalVideosObserver = new LocalMediaObserver(); |
ztenghui | 064d600 | 2013-09-05 15:47:58 -0700 | [diff] [blame] | 1102 | |
| 1103 | getContentResolver().registerContentObserver( |
| 1104 | MediaStore.Images.Media.EXTERNAL_CONTENT_URI, true, |
| 1105 | mLocalImagesObserver); |
| 1106 | getContentResolver().registerContentObserver( |
| 1107 | MediaStore.Video.Media.EXTERNAL_CONTENT_URI, true, |
| 1108 | mLocalVideosObserver); |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 1109 | } |
| 1110 | |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1111 | private void setRotationAnimation() { |
Michael Kolb | 0865018 | 2013-02-25 19:43:56 -0800 | [diff] [blame] | 1112 | int rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1113 | rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE; |
Michael Kolb | 0865018 | 2013-02-25 19:43:56 -0800 | [diff] [blame] | 1114 | Window win = getWindow(); |
| 1115 | WindowManager.LayoutParams winParams = win.getAttributes(); |
| 1116 | winParams.rotationAnimation = rotationAnimation; |
| 1117 | win.setAttributes(winParams); |
| 1118 | } |
| 1119 | |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 1120 | @Override |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 1121 | public void onUserInteraction() { |
| 1122 | super.onUserInteraction(); |
| 1123 | mCurrentModule.onUserInteraction(); |
| 1124 | } |
| 1125 | |
| 1126 | @Override |
Doris Liu | 742cd5b | 2013-09-12 16:17:43 -0700 | [diff] [blame] | 1127 | public boolean dispatchTouchEvent(MotionEvent ev) { |
| 1128 | boolean result = super.dispatchTouchEvent(ev); |
| 1129 | if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) { |
| 1130 | // Real deletion is postponed until the next user interaction after |
| 1131 | // the gesture that triggers deletion. Until real deletion is performed, |
| 1132 | // users can click the undo button to bring back the image that they |
| 1133 | // chose to delete. |
| 1134 | if (mPendingDeletion && !mIsUndoingDeletion) { |
| 1135 | performDeletion(); |
| 1136 | } |
| 1137 | } |
| 1138 | return result; |
| 1139 | } |
| 1140 | |
| 1141 | @Override |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1142 | public void onPause() { |
Doris Liu | f2c1433 | 2013-09-26 11:24:37 -0700 | [diff] [blame] | 1143 | // Delete photos that are pending deletion |
| 1144 | performDeletion(); |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1145 | mOrientationListener.disable(); |
| 1146 | mCurrentModule.onPauseBeforeSuper(); |
| 1147 | super.onPause(); |
| 1148 | mCurrentModule.onPauseAfterSuper(); |
Doris Liu | 2b86d87 | 2013-09-26 15:23:41 -0700 | [diff] [blame] | 1149 | |
| 1150 | mLocalImagesObserver.setActivityPaused(true); |
| 1151 | mLocalVideosObserver.setActivityPaused(true); |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1152 | } |
| 1153 | |
| 1154 | @Override |
Sascha Haeberling | b7639c6 | 2013-09-09 14:42:43 -0700 | [diff] [blame] | 1155 | protected void onActivityResult(int requestCode, int resultCode, Intent data) { |
ztenghui | 064d600 | 2013-09-05 15:47:58 -0700 | [diff] [blame] | 1156 | if (requestCode == REQ_CODE_DONT_SWITCH_TO_PREVIEW) { |
Sascha Haeberling | b7639c6 | 2013-09-09 14:42:43 -0700 | [diff] [blame] | 1157 | mResetToPreviewOnResume = false; |
| 1158 | } else { |
| 1159 | super.onActivityResult(requestCode, resultCode, data); |
| 1160 | } |
| 1161 | } |
| 1162 | |
| 1163 | @Override |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1164 | public void onResume() { |
Angus Kong | ce2b949 | 2013-09-05 17:49:06 -0700 | [diff] [blame] | 1165 | // TODO: Handle this in OrientationManager. |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 1166 | // Auto-rotate off |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1167 | if (Settings.System.getInt(getContentResolver(), |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 1168 | Settings.System.ACCELEROMETER_ROTATION, 0) == 0) { |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1169 | setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); |
| 1170 | mAutoRotateScreen = false; |
| 1171 | } else { |
| 1172 | setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR); |
| 1173 | mAutoRotateScreen = true; |
| 1174 | } |
| 1175 | mOrientationListener.enable(); |
| 1176 | mCurrentModule.onResumeBeforeSuper(); |
| 1177 | super.onResume(); |
| 1178 | mCurrentModule.onResumeAfterSuper(); |
| 1179 | |
Angus Kong | 6798c34 | 2013-07-16 15:14:58 -0700 | [diff] [blame] | 1180 | setSwipingEnabled(true); |
Sascha Haeberling | b7639c6 | 2013-09-09 14:42:43 -0700 | [diff] [blame] | 1181 | |
| 1182 | if (mResetToPreviewOnResume) { |
| 1183 | // Go to the preview on resume. |
| 1184 | mFilmStripView.getController().goToFirstItem(); |
| 1185 | } |
| 1186 | // Default is showing the preview, unless disabled by explicitly |
| 1187 | // starting an activity we want to return from to the filmstrip rather |
| 1188 | // than the preview. |
| 1189 | mResetToPreviewOnResume = true; |
ztenghui | 064d600 | 2013-09-05 15:47:58 -0700 | [diff] [blame] | 1190 | |
Doris Liu | 2b86d87 | 2013-09-26 15:23:41 -0700 | [diff] [blame] | 1191 | if (mLocalVideosObserver.isMediaDataChangedDuringPause() |
| 1192 | || mLocalImagesObserver.isMediaDataChangedDuringPause()) { |
Angus Kong | 2d5c747 | 2013-10-12 23:48:46 -0700 | [diff] [blame] | 1193 | if (!mSecureCamera) { |
| 1194 | // If it's secure camera, requestLoad() should not be called |
| 1195 | // as it will load all the data. |
| 1196 | mDataAdapter.requestLoad(getContentResolver()); |
| 1197 | } |
ztenghui | 064d600 | 2013-09-05 15:47:58 -0700 | [diff] [blame] | 1198 | } |
Doris Liu | 2b86d87 | 2013-09-26 15:23:41 -0700 | [diff] [blame] | 1199 | mLocalImagesObserver.setActivityPaused(false); |
| 1200 | mLocalVideosObserver.setActivityPaused(false); |
Angus Kong | 6798c34 | 2013-07-16 15:14:58 -0700 | [diff] [blame] | 1201 | } |
| 1202 | |
| 1203 | @Override |
| 1204 | public void onStart() { |
| 1205 | super.onStart(); |
Angus Kong | 7e374eb | 2013-08-21 11:27:35 -0700 | [diff] [blame] | 1206 | bindMediaSaveService(); |
Sascha Haeberling | f1f5186 | 2013-07-31 11:28:21 -0700 | [diff] [blame] | 1207 | mPanoramaViewHelper.onStart(); |
| 1208 | } |
| 1209 | |
| 1210 | @Override |
| 1211 | protected void onStop() { |
| 1212 | super.onStop(); |
| 1213 | mPanoramaViewHelper.onStop(); |
Angus Kong | 7e374eb | 2013-08-21 11:27:35 -0700 | [diff] [blame] | 1214 | unbindMediaSaveService(); |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1215 | } |
| 1216 | |
| 1217 | @Override |
| 1218 | public void onDestroy() { |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 1219 | if (mSecureCamera) { |
| 1220 | unregisterReceiver(mScreenOffReceiver); |
| 1221 | } |
ztenghui | 064d600 | 2013-09-05 15:47:58 -0700 | [diff] [blame] | 1222 | getContentResolver().unregisterContentObserver(mLocalImagesObserver); |
| 1223 | getContentResolver().unregisterContentObserver(mLocalVideosObserver); |
| 1224 | |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1225 | super.onDestroy(); |
| 1226 | } |
| 1227 | |
| 1228 | @Override |
| 1229 | public void onConfigurationChanged(Configuration config) { |
| 1230 | super.onConfigurationChanged(config); |
| 1231 | mCurrentModule.onConfigurationChanged(config); |
| 1232 | } |
| 1233 | |
| 1234 | @Override |
| 1235 | public boolean onKeyDown(int keyCode, KeyEvent event) { |
Doris Liu | dba16ae | 2013-10-03 15:31:40 -0700 | [diff] [blame] | 1236 | if (mFilmStripView.inCameraFullscreen()) { |
| 1237 | if (mCurrentModule.onKeyDown(keyCode, event)) { |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 1238 | return true; |
| 1239 | } |
Doris Liu | dba16ae | 2013-10-03 15:31:40 -0700 | [diff] [blame] | 1240 | // Prevent software keyboard or voice search from showing up. |
| 1241 | if (keyCode == KeyEvent.KEYCODE_SEARCH |
| 1242 | || keyCode == KeyEvent.KEYCODE_MENU) { |
| 1243 | if (event.isLongPress()) { |
| 1244 | return true; |
| 1245 | } |
| 1246 | } |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1247 | } |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1248 | |
| 1249 | return super.onKeyDown(keyCode, event); |
| 1250 | } |
| 1251 | |
| 1252 | @Override |
| 1253 | public boolean onKeyUp(int keyCode, KeyEvent event) { |
Doris Liu | dba16ae | 2013-10-03 15:31:40 -0700 | [diff] [blame] | 1254 | if (mFilmStripView.inCameraFullscreen() && mCurrentModule.onKeyUp(keyCode, event)) { |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 1255 | return true; |
| 1256 | } |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1257 | return super.onKeyUp(keyCode, event); |
| 1258 | } |
| 1259 | |
Alan Newberger | 5f6b50d | 2013-08-30 15:19:48 -0700 | [diff] [blame] | 1260 | @Override |
| 1261 | public void onBackPressed() { |
| 1262 | if (!mFilmStripView.inCameraFullscreen()) { |
| 1263 | mFilmStripView.getController().goToFirstItem(); |
| 1264 | } else if (!mCurrentModule.onBackPressed()) { |
| 1265 | super.onBackPressed(); |
| 1266 | } |
| 1267 | } |
| 1268 | |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1269 | public boolean isAutoRotateScreen() { |
| 1270 | return mAutoRotateScreen; |
| 1271 | } |
| 1272 | |
| 1273 | protected void updateStorageSpace() { |
Angus Kong | 2dcc0a9 | 2013-09-25 13:00:08 -0700 | [diff] [blame] | 1274 | mStorageSpaceBytes = Storage.getAvailableSpace(); |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1275 | } |
| 1276 | |
Angus Kong | 2dcc0a9 | 2013-09-25 13:00:08 -0700 | [diff] [blame] | 1277 | protected long getStorageSpaceBytes() { |
| 1278 | return mStorageSpaceBytes; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1279 | } |
| 1280 | |
| 1281 | protected void updateStorageSpaceAndHint() { |
| 1282 | updateStorageSpace(); |
Angus Kong | 2dcc0a9 | 2013-09-25 13:00:08 -0700 | [diff] [blame] | 1283 | updateStorageHint(mStorageSpaceBytes); |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1284 | } |
| 1285 | |
| 1286 | protected void updateStorageHint(long storageSpace) { |
| 1287 | String message = null; |
| 1288 | if (storageSpace == Storage.UNAVAILABLE) { |
| 1289 | message = getString(R.string.no_storage); |
| 1290 | } else if (storageSpace == Storage.PREPARING) { |
| 1291 | message = getString(R.string.preparing_sd); |
| 1292 | } else if (storageSpace == Storage.UNKNOWN_SIZE) { |
| 1293 | message = getString(R.string.access_sd_fail); |
Angus Kong | 2dcc0a9 | 2013-09-25 13:00:08 -0700 | [diff] [blame] | 1294 | } else if (storageSpace <= Storage.LOW_STORAGE_THRESHOLD_BYTES) { |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1295 | message = getString(R.string.spaceIsLow_content); |
| 1296 | } |
| 1297 | |
| 1298 | if (message != null) { |
| 1299 | if (mStorageHint == null) { |
| 1300 | mStorageHint = OnScreenHint.makeText(this, message); |
| 1301 | } else { |
| 1302 | mStorageHint.setText(message); |
| 1303 | } |
| 1304 | mStorageHint.show(); |
| 1305 | } else if (mStorageHint != null) { |
| 1306 | mStorageHint.cancel(); |
| 1307 | mStorageHint = null; |
| 1308 | } |
| 1309 | } |
| 1310 | |
| 1311 | protected void setResultEx(int resultCode) { |
| 1312 | mResultCodeForTesting = resultCode; |
| 1313 | setResult(resultCode); |
| 1314 | } |
| 1315 | |
| 1316 | protected void setResultEx(int resultCode, Intent data) { |
| 1317 | mResultCodeForTesting = resultCode; |
| 1318 | mResultDataForTesting = data; |
| 1319 | setResult(resultCode, data); |
| 1320 | } |
| 1321 | |
| 1322 | public int getResultCode() { |
| 1323 | return mResultCodeForTesting; |
| 1324 | } |
| 1325 | |
| 1326 | public Intent getResultData() { |
| 1327 | return mResultDataForTesting; |
| 1328 | } |
| 1329 | |
| 1330 | public boolean isSecureCamera() { |
| 1331 | return mSecureCamera; |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 1332 | } |
| 1333 | |
| 1334 | @Override |
Angus Kong | ed15d1a | 2013-08-19 15:06:12 -0700 | [diff] [blame] | 1335 | public void onModuleSelected(int moduleIndex) { |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 1336 | if (mCurrentModuleIndex == moduleIndex) { |
| 1337 | return; |
| 1338 | } |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1339 | |
| 1340 | CameraHolder.instance().keep(); |
| 1341 | closeModule(mCurrentModule); |
Sascha Haeberling | 2654dd9 | 2013-08-28 15:28:57 -0700 | [diff] [blame] | 1342 | setModuleFromIndex(moduleIndex); |
| 1343 | |
| 1344 | openModule(mCurrentModule); |
| 1345 | mCurrentModule.onOrientationChanged(mLastRawOrientation); |
Angus Kong | fd4fc0e | 2013-11-07 15:38:09 -0800 | [diff] [blame^] | 1346 | if (mMediaSaver != null) { |
| 1347 | mCurrentModule.onMediaSaverAvailable(mMediaSaver); |
Sascha Haeberling | 2654dd9 | 2013-08-28 15:28:57 -0700 | [diff] [blame] | 1348 | } |
| 1349 | |
| 1350 | // Store the module index so we can use it the next time the Camera |
| 1351 | // starts up. |
| 1352 | SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); |
Angus Kong | 0fb819b | 2013-10-08 13:44:19 -0700 | [diff] [blame] | 1353 | prefs.edit().putInt(CameraSettings.KEY_STARTUP_MODULE_INDEX, moduleIndex).apply(); |
Sascha Haeberling | 2654dd9 | 2013-08-28 15:28:57 -0700 | [diff] [blame] | 1354 | } |
| 1355 | |
| 1356 | /** |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 1357 | * Sets the mCurrentModuleIndex, creates a new module instance for the given |
| 1358 | * index an sets it as mCurrentModule. |
Sascha Haeberling | 2654dd9 | 2013-08-28 15:28:57 -0700 | [diff] [blame] | 1359 | */ |
| 1360 | private void setModuleFromIndex(int moduleIndex) { |
| 1361 | mCurrentModuleIndex = moduleIndex; |
| 1362 | switch (moduleIndex) { |
Sascha Haeberling | 1512566 | 2013-09-17 15:44:22 -0700 | [diff] [blame] | 1363 | case ModuleSwitcher.VIDEO_MODULE_INDEX: |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1364 | mCurrentModule = new VideoModule(); |
| 1365 | break; |
Angus Kong | ed15d1a | 2013-08-19 15:06:12 -0700 | [diff] [blame] | 1366 | |
Sascha Haeberling | 1512566 | 2013-09-17 15:44:22 -0700 | [diff] [blame] | 1367 | case ModuleSwitcher.PHOTO_MODULE_INDEX: |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1368 | mCurrentModule = new PhotoModule(); |
| 1369 | break; |
Angus Kong | ed15d1a | 2013-08-19 15:06:12 -0700 | [diff] [blame] | 1370 | |
Sascha Haeberling | 1512566 | 2013-09-17 15:44:22 -0700 | [diff] [blame] | 1371 | case ModuleSwitcher.WIDE_ANGLE_PANO_MODULE_INDEX: |
Angus Kong | ed15d1a | 2013-08-19 15:06:12 -0700 | [diff] [blame] | 1372 | mCurrentModule = new WideAnglePanoramaModule(); |
| 1373 | break; |
Angus Kong | ed15d1a | 2013-08-19 15:06:12 -0700 | [diff] [blame] | 1374 | |
Sascha Haeberling | 1512566 | 2013-09-17 15:44:22 -0700 | [diff] [blame] | 1375 | case ModuleSwitcher.LIGHTCYCLE_MODULE_INDEX: |
Sascha Haeberling | 8e963a5 | 2013-08-06 11:43:02 -0700 | [diff] [blame] | 1376 | mCurrentModule = PhotoSphereHelper.createPanoramaModule(); |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1377 | break; |
Ruben Brunk | a9d66bd | 2013-09-06 11:56:32 -0700 | [diff] [blame] | 1378 | case ModuleSwitcher.GCAM_MODULE_INDEX: |
| 1379 | // Force immediate release of Camera instance |
| 1380 | CameraHolder.instance().strongRelease(); |
| 1381 | mCurrentModule = GcamHelper.createGcamModule(); |
| 1382 | break; |
Sascha Haeberling | 03e0145 | 2013-10-07 13:21:33 -0700 | [diff] [blame] | 1383 | case ModuleSwitcher.REFOCUS_MODULE_INDEX: |
| 1384 | mCurrentModule = RefocusHelper.createRefocusModule(); |
| 1385 | break; |
Sascha Haeberling | 2654dd9 | 2013-08-28 15:28:57 -0700 | [diff] [blame] | 1386 | default: |
Sascha Haeberling | 1512566 | 2013-09-17 15:44:22 -0700 | [diff] [blame] | 1387 | // Fall back to photo mode. |
| 1388 | mCurrentModule = new PhotoModule(); |
| 1389 | mCurrentModuleIndex = ModuleSwitcher.PHOTO_MODULE_INDEX; |
Sascha Haeberling | 2654dd9 | 2013-08-28 15:28:57 -0700 | [diff] [blame] | 1390 | break; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1391 | } |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 1392 | } |
| 1393 | |
Sascha Haeberling | 88ef766 | 2013-08-15 17:19:22 -0700 | [diff] [blame] | 1394 | /** |
| 1395 | * Launches an ACTION_EDIT intent for the given local data item. |
| 1396 | */ |
| 1397 | public void launchEditor(LocalData data) { |
| 1398 | Intent intent = new Intent(Intent.ACTION_EDIT) |
| 1399 | .setDataAndType(data.getContentUri(), data.getMimeType()) |
| 1400 | .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); |
Erin Dahlgren | 05a0492 | 2013-11-07 11:35:10 -0800 | [diff] [blame] | 1401 | try { |
| 1402 | startActivityForResult(intent, REQ_CODE_DONT_SWITCH_TO_PREVIEW); |
| 1403 | } catch (ActivityNotFoundException e) { |
| 1404 | startActivityForResult(Intent.createChooser(intent, null), |
| 1405 | REQ_CODE_DONT_SWITCH_TO_PREVIEW); |
| 1406 | } |
Sascha Haeberling | 88ef766 | 2013-08-15 17:19:22 -0700 | [diff] [blame] | 1407 | } |
| 1408 | |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 1409 | /** |
| 1410 | * Launch the tiny planet editor. |
| 1411 | * |
| 1412 | * @param data the data must be a 360 degree stereographically mapped |
| 1413 | * panoramic image. It will not be modified, instead a new item |
| 1414 | * with the result will be added to the filmstrip. |
| 1415 | */ |
| 1416 | public void launchTinyPlanetEditor(LocalData data) { |
| 1417 | TinyPlanetFragment fragment = new TinyPlanetFragment(); |
| 1418 | Bundle bundle = new Bundle(); |
| 1419 | bundle.putString(TinyPlanetFragment.ARGUMENT_URI, data.getContentUri().toString()); |
| 1420 | bundle.putString(TinyPlanetFragment.ARGUMENT_TITLE, data.getTitle()); |
| 1421 | fragment.setArguments(bundle); |
| 1422 | fragment.show(getFragmentManager(), "tiny_planet"); |
| 1423 | } |
| 1424 | |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1425 | private void openModule(CameraModule module) { |
Angus Kong | 653c43b | 2013-08-21 18:28:43 -0700 | [diff] [blame] | 1426 | module.init(this, mCameraModuleRootView); |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1427 | module.onResumeBeforeSuper(); |
| 1428 | module.onResumeAfterSuper(); |
| 1429 | } |
| 1430 | |
| 1431 | private void closeModule(CameraModule module) { |
| 1432 | module.onPauseBeforeSuper(); |
| 1433 | module.onPauseAfterSuper(); |
Angus Kong | 653c43b | 2013-08-21 18:28:43 -0700 | [diff] [blame] | 1434 | ((ViewGroup) mCameraModuleRootView).removeAllViews(); |
| 1435 | } |
| 1436 | |
Doris Liu | 742cd5b | 2013-09-12 16:17:43 -0700 | [diff] [blame] | 1437 | private void performDeletion() { |
| 1438 | if (!mPendingDeletion) { |
| 1439 | return; |
| 1440 | } |
| 1441 | hideUndoDeletionBar(false); |
| 1442 | mDataAdapter.executeDeletion(CameraActivity.this); |
Erin Dahlgren | fd7f0a9 | 2013-10-21 10:08:54 -0700 | [diff] [blame] | 1443 | |
| 1444 | int currentId = mFilmStripView.getCurrentId(); |
| 1445 | updateActionBarMenu(currentId); |
| 1446 | mFilmStripListener.onCurrentDataCentered(currentId); |
Doris Liu | 742cd5b | 2013-09-12 16:17:43 -0700 | [diff] [blame] | 1447 | } |
| 1448 | |
| 1449 | public void showUndoDeletionBar() { |
| 1450 | if (mPendingDeletion) { |
| 1451 | performDeletion(); |
| 1452 | } |
| 1453 | Log.v(TAG, "showing undo bar"); |
| 1454 | mPendingDeletion = true; |
Angus Kong | 653c43b | 2013-08-21 18:28:43 -0700 | [diff] [blame] | 1455 | if (mUndoDeletionBar == null) { |
Angus Kong | 653c43b | 2013-08-21 18:28:43 -0700 | [diff] [blame] | 1456 | ViewGroup v = (ViewGroup) getLayoutInflater().inflate( |
| 1457 | R.layout.undo_bar, mAboveFilmstripControlLayout, true); |
| 1458 | mUndoDeletionBar = (ViewGroup) v.findViewById(R.id.camera_undo_deletion_bar); |
| 1459 | View button = mUndoDeletionBar.findViewById(R.id.camera_undo_deletion_button); |
| 1460 | button.setOnClickListener(new View.OnClickListener() { |
| 1461 | @Override |
| 1462 | public void onClick(View view) { |
| 1463 | mDataAdapter.undoDataRemoval(); |
Doris Liu | 742cd5b | 2013-09-12 16:17:43 -0700 | [diff] [blame] | 1464 | hideUndoDeletionBar(true); |
| 1465 | } |
| 1466 | }); |
| 1467 | // Setting undo bar clickable to avoid touch events going through |
| 1468 | // the bar to the buttons (eg. edit button, etc) underneath the bar. |
| 1469 | mUndoDeletionBar.setClickable(true); |
| 1470 | // When there is user interaction going on with the undo button, we |
| 1471 | // do not want to hide the undo bar. |
| 1472 | button.setOnTouchListener(new View.OnTouchListener() { |
| 1473 | @Override |
| 1474 | public boolean onTouch(View v, MotionEvent event) { |
| 1475 | if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { |
| 1476 | mIsUndoingDeletion = true; |
| 1477 | } else if (event.getActionMasked() == MotionEvent.ACTION_UP) { |
| 1478 | mIsUndoingDeletion =false; |
| 1479 | } |
| 1480 | return false; |
Angus Kong | 653c43b | 2013-08-21 18:28:43 -0700 | [diff] [blame] | 1481 | } |
| 1482 | }); |
| 1483 | } |
| 1484 | mUndoDeletionBar.setAlpha(0f); |
| 1485 | mUndoDeletionBar.setVisibility(View.VISIBLE); |
Doris Liu | 742cd5b | 2013-09-12 16:17:43 -0700 | [diff] [blame] | 1486 | mUndoDeletionBar.animate().setDuration(200).alpha(1f).setListener(null).start(); |
Angus Kong | 653c43b | 2013-08-21 18:28:43 -0700 | [diff] [blame] | 1487 | } |
| 1488 | |
Doris Liu | 742cd5b | 2013-09-12 16:17:43 -0700 | [diff] [blame] | 1489 | private void hideUndoDeletionBar(boolean withAnimation) { |
Angus Kong | 653c43b | 2013-08-21 18:28:43 -0700 | [diff] [blame] | 1490 | Log.v(TAG, "Hiding undo deletion bar"); |
Doris Liu | 742cd5b | 2013-09-12 16:17:43 -0700 | [diff] [blame] | 1491 | mPendingDeletion = false; |
Angus Kong | 653c43b | 2013-08-21 18:28:43 -0700 | [diff] [blame] | 1492 | if (mUndoDeletionBar != null) { |
Doris Liu | 742cd5b | 2013-09-12 16:17:43 -0700 | [diff] [blame] | 1493 | if (withAnimation) { |
| 1494 | mUndoDeletionBar.animate() |
| 1495 | .setDuration(200) |
| 1496 | .alpha(0f) |
| 1497 | .setListener(new Animator.AnimatorListener() { |
| 1498 | @Override |
| 1499 | public void onAnimationStart(Animator animation) { |
| 1500 | // Do nothing. |
| 1501 | } |
| 1502 | |
| 1503 | @Override |
| 1504 | public void onAnimationEnd(Animator animation) { |
| 1505 | mUndoDeletionBar.setVisibility(View.GONE); |
| 1506 | } |
| 1507 | |
| 1508 | @Override |
| 1509 | public void onAnimationCancel(Animator animation) { |
| 1510 | // Do nothing. |
| 1511 | } |
| 1512 | |
| 1513 | @Override |
| 1514 | public void onAnimationRepeat(Animator animation) { |
| 1515 | // Do nothing. |
| 1516 | } |
| 1517 | }) |
| 1518 | .start(); |
| 1519 | } else { |
| 1520 | mUndoDeletionBar.setVisibility(View.GONE); |
| 1521 | } |
Angus Kong | 653c43b | 2013-08-21 18:28:43 -0700 | [diff] [blame] | 1522 | } |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 1523 | } |
| 1524 | |
| 1525 | @Override |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1526 | public void onShowSwitcherPopup() { |
| 1527 | } |
| 1528 | |
Angus Kong | a719460 | 2013-09-06 17:20:15 -0700 | [diff] [blame] | 1529 | /** |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 1530 | * Enable/disable swipe-to-filmstrip. Will always disable swipe if in |
| 1531 | * capture intent. |
Angus Kong | a719460 | 2013-09-06 17:20:15 -0700 | [diff] [blame] | 1532 | * |
| 1533 | * @param enable {@code true} to enable swipe. |
| 1534 | */ |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1535 | public void setSwipingEnabled(boolean enable) { |
Angus Kong | a719460 | 2013-09-06 17:20:15 -0700 | [diff] [blame] | 1536 | if (isCaptureIntent()) { |
| 1537 | mCameraPreviewData.lockPreview(true); |
| 1538 | } else { |
| 1539 | mCameraPreviewData.lockPreview(!enable); |
| 1540 | } |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 1541 | } |
| 1542 | |
Erin Dahlgren | 3044d8c | 2013-10-10 18:23:45 -0700 | [diff] [blame] | 1543 | |
| 1544 | /** |
| 1545 | * Check whether camera controls are visible. |
| 1546 | * |
| 1547 | * @return whether controls are visible. |
| 1548 | */ |
| 1549 | private boolean arePreviewControlsVisible() { |
| 1550 | return mCurrentModule.arePreviewControlsVisible(); |
| 1551 | } |
| 1552 | |
| 1553 | /** |
| 1554 | * Show or hide the {@link CameraControls} using the current module's |
| 1555 | * implementation of {@link #onPreviewFocusChanged}. |
| 1556 | * |
| 1557 | * @param showControls whether to show camera controls. |
| 1558 | */ |
| 1559 | private void setPreviewControlsVisibility(boolean showControls) { |
| 1560 | mCurrentModule.onPreviewFocusChanged(showControls); |
| 1561 | } |
| 1562 | |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 1563 | // Accessor methods for getting latency times used in performance testing |
| 1564 | public long getAutoFocusTime() { |
| 1565 | return (mCurrentModule instanceof PhotoModule) ? |
| 1566 | ((PhotoModule) mCurrentModule).mAutoFocusTime : -1; |
| 1567 | } |
| 1568 | |
| 1569 | public long getShutterLag() { |
| 1570 | return (mCurrentModule instanceof PhotoModule) ? |
| 1571 | ((PhotoModule) mCurrentModule).mShutterLag : -1; |
| 1572 | } |
| 1573 | |
| 1574 | public long getShutterToPictureDisplayedTime() { |
| 1575 | return (mCurrentModule instanceof PhotoModule) ? |
| 1576 | ((PhotoModule) mCurrentModule).mShutterToPictureDisplayedTime : -1; |
| 1577 | } |
| 1578 | |
| 1579 | public long getPictureDisplayedToJpegCallbackTime() { |
| 1580 | return (mCurrentModule instanceof PhotoModule) ? |
| 1581 | ((PhotoModule) mCurrentModule).mPictureDisplayedToJpegCallbackTime : -1; |
| 1582 | } |
| 1583 | |
| 1584 | public long getJpegCallbackFinishTime() { |
| 1585 | return (mCurrentModule instanceof PhotoModule) ? |
| 1586 | ((PhotoModule) mCurrentModule).mJpegCallbackFinishTime : -1; |
| 1587 | } |
| 1588 | |
| 1589 | public long getCaptureStartTime() { |
| 1590 | return (mCurrentModule instanceof PhotoModule) ? |
| 1591 | ((PhotoModule) mCurrentModule).mCaptureStartTime : -1; |
| 1592 | } |
| 1593 | |
| 1594 | public boolean isRecording() { |
| 1595 | return (mCurrentModule instanceof VideoModule) ? |
| 1596 | ((VideoModule) mCurrentModule).isRecording() : false; |
| 1597 | } |
Angus Kong | 4f795b8 | 2013-09-16 14:25:35 -0700 | [diff] [blame] | 1598 | |
| 1599 | public CameraOpenErrorCallback getCameraOpenErrorCallback() { |
| 1600 | return mCameraOpenErrorCallback; |
| 1601 | } |
Ruben Brunk | d217ed0 | 2013-10-08 23:31:13 -0700 | [diff] [blame] | 1602 | |
| 1603 | // For debugging purposes only. |
| 1604 | public CameraModule getCurrentModule() { |
| 1605 | return mCurrentModule; |
| 1606 | } |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 1607 | } |