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; |
Angus Kong | 01054e9 | 2013-12-10 11:06:18 -0800 | [diff] [blame] | 23 | import android.app.AlertDialog; |
Mangesh Ghiware | 30968d0 | 2013-10-02 14:38:12 -0700 | [diff] [blame] | 24 | import android.content.ActivityNotFoundException; |
Doris Liu | b84b973 | 2013-06-18 17:14:26 -0700 | [diff] [blame] | 25 | import android.content.BroadcastReceiver; |
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; |
Sascha Haeberling | 2654dd9 | 2013-08-28 15:28:57 -0700 | [diff] [blame] | 30 | import android.content.SharedPreferences; |
Doris Liu | 3cf565c | 2013-02-15 10:55:37 -0800 | [diff] [blame] | 31 | import android.content.pm.ActivityInfo; |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 32 | import android.content.res.Configuration; |
Angus Kong | 9f1db52 | 2013-11-09 16:25:59 -0800 | [diff] [blame] | 33 | import android.graphics.Bitmap; |
Erin Dahlgren | c120b0f | 2013-11-19 10:53:49 -0800 | [diff] [blame] | 34 | import android.graphics.Color; |
Doris Liu | 70da918 | 2013-12-17 18:41:15 -0800 | [diff] [blame] | 35 | import android.graphics.Matrix; |
Angus Kong | 9f1db52 | 2013-11-09 16:25:59 -0800 | [diff] [blame] | 36 | import android.graphics.SurfaceTexture; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 37 | import android.graphics.drawable.ColorDrawable; |
| 38 | import android.net.Uri; |
Mangesh Ghiware | a5682ab | 2013-09-19 09:24:23 -0700 | [diff] [blame] | 39 | import android.nfc.NfcAdapter; |
| 40 | import android.nfc.NfcAdapter.CreateBeamUrisCallback; |
| 41 | import android.nfc.NfcEvent; |
Mangesh Ghiware | a5682ab | 2013-09-19 09:24:23 -0700 | [diff] [blame] | 42 | import android.os.Build; |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 43 | import android.os.Bundle; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 44 | import android.os.Handler; |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 45 | import android.os.Looper; |
| 46 | import android.os.Message; |
Sascha Haeberling | 2654dd9 | 2013-08-28 15:28:57 -0700 | [diff] [blame] | 47 | import android.preference.PreferenceManager; |
Doris Liu | 2a7f44c | 2013-08-12 15:18:53 -0700 | [diff] [blame] | 48 | import android.provider.MediaStore; |
Doris Liu | 3cf565c | 2013-02-15 10:55:37 -0800 | [diff] [blame] | 49 | import android.provider.Settings; |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 50 | import android.util.Log; |
Erin Dahlgren | c120b0f | 2013-11-19 10:53:49 -0800 | [diff] [blame] | 51 | import android.view.Gravity; |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 52 | import android.view.KeyEvent; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 53 | import android.view.LayoutInflater; |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 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.View; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 57 | import android.view.ViewGroup; |
Michael Kolb | 0865018 | 2013-02-25 19:43:56 -0800 | [diff] [blame] | 58 | import android.view.Window; |
| 59 | import android.view.WindowManager; |
Angus Kong | 653c43b | 2013-08-21 18:28:43 -0700 | [diff] [blame] | 60 | import android.widget.FrameLayout; |
Erin Dahlgren | c120b0f | 2013-11-19 10:53:49 -0800 | [diff] [blame] | 61 | import android.widget.FrameLayout.LayoutParams; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 62 | import android.widget.ImageView; |
Erin Dahlgren | c120b0f | 2013-11-19 10:53:49 -0800 | [diff] [blame] | 63 | import android.widget.PopupWindow; |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 64 | import android.widget.ProgressBar; |
Mangesh Ghiware | cd2eeb0 | 2013-08-23 13:28:21 -0700 | [diff] [blame] | 65 | import android.widget.ShareActionProvider; |
Sascha Haeberling | a63dbb6 | 2013-11-22 11:55:32 -0800 | [diff] [blame] | 66 | import android.widget.TextView; |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 67 | |
Angus Kong | 9f1db52 | 2013-11-09 16:25:59 -0800 | [diff] [blame] | 68 | import com.android.camera.app.AppController; |
Doris Liu | f55f3c4 | 2013-11-20 00:24:46 -0800 | [diff] [blame] | 69 | import com.android.camera.app.CameraAppUI; |
Angus Kong | 20fad24 | 2013-11-11 18:23:46 -0800 | [diff] [blame] | 70 | import com.android.camera.app.CameraController; |
| 71 | import com.android.camera.app.CameraManager; |
| 72 | import com.android.camera.app.CameraManagerFactory; |
| 73 | import com.android.camera.app.CameraProvider; |
Angus Kong | c4e6656 | 2013-11-22 23:03:21 -0800 | [diff] [blame] | 74 | import com.android.camera.app.CameraServices; |
Kevin Gabayan | ffbc43c | 2013-12-09 11:41:50 -0800 | [diff] [blame] | 75 | import com.android.camera.app.LocationManager; |
Angus Kong | 20fad24 | 2013-11-11 18:23:46 -0800 | [diff] [blame] | 76 | import com.android.camera.app.ModuleManagerImpl; |
Angus Kong | 9f1db52 | 2013-11-09 16:25:59 -0800 | [diff] [blame] | 77 | import com.android.camera.app.OrientationManager; |
| 78 | import com.android.camera.app.OrientationManagerImpl; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 79 | import com.android.camera.data.CameraDataAdapter; |
Angus Kong | 8e5e4ee | 2013-07-30 11:36:00 -0700 | [diff] [blame] | 80 | import com.android.camera.data.FixedLastDataAdapter; |
Angus Kong | 3250987 | 2013-10-02 16:53:40 -0700 | [diff] [blame] | 81 | import com.android.camera.data.InProgressDataWrapper; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 82 | import com.android.camera.data.LocalData; |
Angus Kong | 8e5e4ee | 2013-07-30 11:36:00 -0700 | [diff] [blame] | 83 | import com.android.camera.data.LocalDataAdapter; |
ztenghui | 064d600 | 2013-09-05 15:47:58 -0700 | [diff] [blame] | 84 | import com.android.camera.data.LocalMediaObserver; |
Angus Kong | 8a2350a | 2013-12-16 15:02:34 -0800 | [diff] [blame] | 85 | import com.android.camera.data.PanoramaMetadataLoader; |
| 86 | import com.android.camera.data.RgbzMetadataLoader; |
Angus Kong | bd26069 | 2013-08-07 14:52:56 -0700 | [diff] [blame] | 87 | import com.android.camera.data.SimpleViewData; |
Angus Kong | 01054e9 | 2013-12-10 11:06:18 -0800 | [diff] [blame] | 88 | import com.android.camera.filmstrip.FilmstripContentPanel; |
Angus Kong | 6284815 | 2013-11-08 17:25:29 -0800 | [diff] [blame] | 89 | import com.android.camera.filmstrip.FilmstripController; |
Angus Kong | 612321f | 2013-11-18 16:17:43 -0800 | [diff] [blame] | 90 | import com.android.camera.module.ModulesInfo; |
Sascha Haeberling | a63dbb6 | 2013-11-22 11:55:32 -0800 | [diff] [blame] | 91 | import com.android.camera.session.CaptureSessionManager; |
| 92 | import com.android.camera.session.CaptureSessionManager.SessionListener; |
| 93 | import com.android.camera.session.PlaceholderManager; |
Erin Dahlgren | 357b767 | 2013-11-20 17:38:14 -0800 | [diff] [blame] | 94 | import com.android.camera.settings.SettingsManager; |
| 95 | import com.android.camera.settings.SettingsManager.SettingsCapabilities; |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 96 | import com.android.camera.tinyplanet.TinyPlanetFragment; |
Doris Liu | f55f3c4 | 2013-11-20 00:24:46 -0800 | [diff] [blame] | 97 | import com.android.camera.ui.MainActivityLayout; |
Doris Liu | 1c94b7d | 2013-11-09 19:13:44 -0800 | [diff] [blame] | 98 | import com.android.camera.ui.ModeListView; |
Doris Liu | 06db742 | 2013-12-09 19:36:25 -0800 | [diff] [blame] | 99 | import com.android.camera.ui.PreviewStatusListener; |
Erin Dahlgren | c120b0f | 2013-11-19 10:53:49 -0800 | [diff] [blame] | 100 | import com.android.camera.ui.SettingsView; |
Sascha Haeberling | 88ef766 | 2013-08-15 17:19:22 -0700 | [diff] [blame] | 101 | import com.android.camera.util.ApiHelper; |
Angus Kong | b50b5cb | 2013-08-09 14:55:20 -0700 | [diff] [blame] | 102 | import com.android.camera.util.CameraUtil; |
Christian Wyglendowski | 6fe8c82 | 2013-11-26 14:16:04 -0800 | [diff] [blame] | 103 | import com.android.camera.util.FeedbackHelper; |
Ruben Brunk | a9d66bd | 2013-09-06 11:56:32 -0700 | [diff] [blame] | 104 | import com.android.camera.util.GcamHelper; |
Alan Newberger | 761306f | 2013-10-30 12:51:21 -0700 | [diff] [blame] | 105 | import com.android.camera.util.IntentHelper; |
Sascha Haeberling | 88ef766 | 2013-08-15 17:19:22 -0700 | [diff] [blame] | 106 | import com.android.camera.util.PhotoSphereHelper.PanoramaViewHelper; |
Seth Raphael | cbd8267 | 2013-11-05 10:12:36 -0800 | [diff] [blame] | 107 | import com.android.camera.util.UsageStatistics; |
Sascha Haeberling | a63dbb6 | 2013-11-22 11:55:32 -0800 | [diff] [blame] | 108 | import com.android.camera.widget.FilmstripView; |
Sascha Haeberling | 8e963a5 | 2013-08-06 11:43:02 -0700 | [diff] [blame] | 109 | import com.android.camera2.R; |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 110 | |
Seth Raphael | cbd8267 | 2013-11-05 10:12:36 -0800 | [diff] [blame] | 111 | import java.io.File; |
Angus Kong | e2f4c03 | 2013-12-19 10:24:33 -0800 | [diff] [blame] | 112 | import java.util.List; |
Seth Raphael | cbd8267 | 2013-11-05 10:12:36 -0800 | [diff] [blame] | 113 | |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 114 | public class CameraActivity extends Activity |
Doris Liu | f55f3c4 | 2013-11-20 00:24:46 -0800 | [diff] [blame] | 115 | implements AppController, CameraManager.CameraOpenCallback, |
Angus Kong | 9f1db52 | 2013-11-09 16:25:59 -0800 | [diff] [blame] | 116 | ActionBar.OnMenuVisibilityListener, ShareActionProvider.OnShareTargetSelectedListener, |
| 117 | OrientationManager.OnOrientationChangeListener { |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 118 | |
Sascha Haeberling | 5850115 | 2014-01-06 11:02:35 -0800 | [diff] [blame] | 119 | private static final String TAG = "CameraActivity"; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 120 | |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 121 | private static final String INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE = |
| 122 | "android.media.action.STILL_IMAGE_CAMERA_SECURE"; |
| 123 | public static final String ACTION_IMAGE_CAPTURE_SECURE = |
| 124 | "android.media.action.IMAGE_CAPTURE_SECURE"; |
| 125 | |
| 126 | // The intent extra for camera from secure lock screen. True if the gallery |
| 127 | // should only show newly captured pictures. sSecureAlbumId does not |
| 128 | // increment. This is used when switching between camera, camcorder, and |
| 129 | // panorama. If the extra is not set, it is in the normal camera mode. |
| 130 | public static final String SECURE_CAMERA_EXTRA = "secure_camera"; |
| 131 | |
Sascha Haeberling | b7639c6 | 2013-09-09 14:42:43 -0700 | [diff] [blame] | 132 | /** |
Angus Kong | 20fad24 | 2013-11-11 18:23:46 -0800 | [diff] [blame] | 133 | * Request code from an activity we started that indicated that we do not want |
| 134 | * to reset the view to the preview in onResume. |
Sascha Haeberling | b7639c6 | 2013-09-09 14:42:43 -0700 | [diff] [blame] | 135 | */ |
| 136 | public static final int REQ_CODE_DONT_SWITCH_TO_PREVIEW = 142; |
| 137 | |
Ruben Brunk | d217ed0 | 2013-10-08 23:31:13 -0700 | [diff] [blame] | 138 | public static final int REQ_CODE_GCAM_DEBUG_POSTCAPTURE = 999; |
| 139 | |
Angus Kong | 13e87c4 | 2013-11-25 10:02:47 -0800 | [diff] [blame] | 140 | private static final int MSG_HIDE_ACTION_BAR = 1; |
| 141 | private static final int MSG_CLEAR_SCREEN_ON_FLAG = 2; |
Angus Kong | 13e87c4 | 2013-11-25 10:02:47 -0800 | [diff] [blame] | 142 | private static final long SCREEN_DELAY_MS = 2 * 60 * 1000; // 2 mins. |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 143 | |
Angus Kong | 20fad24 | 2013-11-11 18:23:46 -0800 | [diff] [blame] | 144 | /** |
| 145 | * Whether onResume should reset the view to the preview. |
| 146 | */ |
Sascha Haeberling | b7639c6 | 2013-09-09 14:42:43 -0700 | [diff] [blame] | 147 | private boolean mResetToPreviewOnResume = true; |
| 148 | |
Angus Kong | 20fad24 | 2013-11-11 18:23:46 -0800 | [diff] [blame] | 149 | /** |
| 150 | * This data adapter is used by FilmStripView. |
| 151 | */ |
Angus Kong | 8e5e4ee | 2013-07-30 11:36:00 -0700 | [diff] [blame] | 152 | private LocalDataAdapter mDataAdapter; |
Angus Kong | 8e5e4ee | 2013-07-30 11:36:00 -0700 | [diff] [blame] | 153 | |
Sascha Haeberling | a63dbb6 | 2013-11-22 11:55:32 -0800 | [diff] [blame] | 154 | /** |
| 155 | * TODO: This should be moved to the app level. |
| 156 | */ |
Erin Dahlgren | c120b0f | 2013-11-19 10:53:49 -0800 | [diff] [blame] | 157 | private SettingsManager mSettingsManager; |
Sascha Haeberling | a63dbb6 | 2013-11-22 11:55:32 -0800 | [diff] [blame] | 158 | |
| 159 | /** |
| 160 | * TODO: This should be moved to the app level. |
| 161 | */ |
Erin Dahlgren | 357b767 | 2013-11-20 17:38:14 -0800 | [diff] [blame] | 162 | private SettingsController mSettingsController; |
Doris Liu | 70576b6 | 2013-11-14 20:30:33 -0800 | [diff] [blame] | 163 | private ModeListView mModeListView; |
Erin Dahlgren | c120b0f | 2013-11-19 10:53:49 -0800 | [diff] [blame] | 164 | private int mCurrentModeIndex; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 165 | private CameraModule mCurrentModule; |
Angus Kong | 20fad24 | 2013-11-11 18:23:46 -0800 | [diff] [blame] | 166 | private ModuleManagerImpl mModuleManager; |
Angus Kong | 653c43b | 2013-08-21 18:28:43 -0700 | [diff] [blame] | 167 | private FrameLayout mAboveFilmstripControlLayout; |
Angus Kong | 6284815 | 2013-11-08 17:25:29 -0800 | [diff] [blame] | 168 | private FilmstripController mFilmstripController; |
Angus Kong | faaee01 | 2013-12-07 00:38:46 -0800 | [diff] [blame] | 169 | private boolean mFilmstripVisible; |
Sascha Haeberling | a63dbb6 | 2013-11-22 11:55:32 -0800 | [diff] [blame] | 170 | private TextView mBottomProgressText; |
| 171 | private ProgressBar mBottomProgressBar; |
| 172 | private View mSessionProgressPanel; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 173 | private int mResultCodeForTesting; |
| 174 | private Intent mResultDataForTesting; |
| 175 | private OnScreenHint mStorageHint; |
Angus Kong | 2dcc0a9 | 2013-09-25 13:00:08 -0700 | [diff] [blame] | 176 | private long mStorageSpaceBytes = Storage.LOW_STORAGE_THRESHOLD_BYTES; |
Doris Liu | 3cf565c | 2013-02-15 10:55:37 -0800 | [diff] [blame] | 177 | private boolean mAutoRotateScreen; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 178 | private boolean mSecureCamera; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 179 | private int mLastRawOrientation; |
Angus Kong | 9f1db52 | 2013-11-09 16:25:59 -0800 | [diff] [blame] | 180 | private OrientationManagerImpl mOrientationManager; |
Erin Dahlgren | 21c21a6 | 2013-11-19 16:37:38 -0800 | [diff] [blame] | 181 | private LocationManager mLocationManager; |
Erin Dahlgren | 8a2933b | 2013-12-06 12:07:33 -0800 | [diff] [blame] | 182 | private ButtonManager mButtonManager; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 183 | private Handler mMainHandler; |
Sascha Haeberling | f1f5186 | 2013-07-31 11:28:21 -0700 | [diff] [blame] | 184 | private PanoramaViewHelper mPanoramaViewHelper; |
ztenghui | fa9e2cc | 2013-08-09 17:37:15 -0700 | [diff] [blame] | 185 | private ActionBar mActionBar; |
Angus Kong | 653c43b | 2013-08-21 18:28:43 -0700 | [diff] [blame] | 186 | private ViewGroup mUndoDeletionBar; |
Doris Liu | 742cd5b | 2013-09-12 16:17:43 -0700 | [diff] [blame] | 187 | private boolean mIsUndoingDeletion = false; |
Doris Liu | 3cf565c | 2013-02-15 10:55:37 -0800 | [diff] [blame] | 188 | |
Sascha Haeberling | 280fd3e | 2013-11-21 13:52:15 -0800 | [diff] [blame] | 189 | private final Uri[] mNfcPushUris = new Uri[1]; |
Mangesh Ghiware | a5682ab | 2013-09-19 09:24:23 -0700 | [diff] [blame] | 190 | |
ztenghui | 064d600 | 2013-09-05 15:47:58 -0700 | [diff] [blame] | 191 | private LocalMediaObserver mLocalImagesObserver; |
| 192 | private LocalMediaObserver mLocalVideosObserver; |
Mangesh Ghiware | cd2eeb0 | 2013-08-23 13:28:21 -0700 | [diff] [blame] | 193 | |
Doris Liu | 742cd5b | 2013-09-12 16:17:43 -0700 | [diff] [blame] | 194 | private boolean mPendingDeletion = false; |
Sascha Haeberling | 5199c20 | 2013-09-05 17:10:19 -0700 | [diff] [blame] | 195 | |
Angus Kong | 20fad24 | 2013-11-11 18:23:46 -0800 | [diff] [blame] | 196 | private CameraController mCameraController; |
Erin Dahlgren | c120b0f | 2013-11-19 10:53:49 -0800 | [diff] [blame] | 197 | private boolean mPaused; |
Doris Liu | f55f3c4 | 2013-11-20 00:24:46 -0800 | [diff] [blame] | 198 | private CameraAppUI mCameraAppUI; |
Angus Kong | 20fad24 | 2013-11-11 18:23:46 -0800 | [diff] [blame] | 199 | |
Christian Wyglendowski | 6fe8c82 | 2013-11-26 14:16:04 -0800 | [diff] [blame] | 200 | private FeedbackHelper mFeedbackHelper; |
| 201 | |
Spike Sprague | 0f3c4b4 | 2013-12-10 19:50:17 -0800 | [diff] [blame] | 202 | @Override |
| 203 | public CameraAppUI getCameraAppUI() { |
| 204 | return mCameraAppUI; |
| 205 | } |
| 206 | |
Doris Liu | b84b973 | 2013-06-18 17:14:26 -0700 | [diff] [blame] | 207 | // close activity when screen turns off |
Sascha Haeberling | 280fd3e | 2013-11-21 13:52:15 -0800 | [diff] [blame] | 208 | private final BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() { |
Doris Liu | b84b973 | 2013-06-18 17:14:26 -0700 | [diff] [blame] | 209 | @Override |
| 210 | public void onReceive(Context context, Intent intent) { |
| 211 | finish(); |
| 212 | } |
| 213 | }; |
| 214 | |
Angus Kong | 13e87c4 | 2013-11-25 10:02:47 -0800 | [diff] [blame] | 215 | /** |
| 216 | * Whether the screen is kept turned on. |
| 217 | */ |
| 218 | private boolean mKeepScreenOn; |
Angus Kong | 53ae041 | 2013-12-01 23:21:49 -0800 | [diff] [blame] | 219 | private int mLastLayoutOrientation; |
Sascha Haeberling | a63dbb6 | 2013-11-22 11:55:32 -0800 | [diff] [blame] | 220 | private final CameraAppUI.BottomControls.Listener mMyFilmstripBottomControlListener = |
Angus Kong | b251025 | 2013-12-10 22:58:15 -0800 | [diff] [blame] | 221 | new CameraAppUI.BottomControls.Listener() { |
| 222 | |
| 223 | /** |
| 224 | * If the current photo is a photo sphere, this will launch the Photo Sphere |
| 225 | * panorama viewer. |
| 226 | */ |
| 227 | @Override |
Angus Kong | 8a2350a | 2013-12-16 15:02:34 -0800 | [diff] [blame] | 228 | public void onExternalViewer() { |
| 229 | if (mPanoramaViewHelper == null) { |
| 230 | return; |
| 231 | } |
| 232 | final LocalData data = getCurrentLocalData(); |
| 233 | if (data == null) { |
| 234 | return; |
| 235 | } |
| 236 | final Uri contentUri = data.getContentUri(); |
| 237 | if (contentUri == Uri.EMPTY) { |
| 238 | return; |
| 239 | } |
| 240 | |
| 241 | if (PanoramaMetadataLoader.isPanorama(data)) { |
| 242 | mPanoramaViewHelper.showPanorama(contentUri); |
| 243 | } else if (RgbzMetadataLoader.hasRGBZData(data)) { |
| 244 | mPanoramaViewHelper.showRgbz(contentUri); |
Angus Kong | b251025 | 2013-12-10 22:58:15 -0800 | [diff] [blame] | 245 | } |
| 246 | } |
| 247 | |
| 248 | @Override |
| 249 | public void onEdit() { |
| 250 | LocalData data = getCurrentLocalData(); |
| 251 | if (data == null) { |
| 252 | return; |
| 253 | } |
| 254 | launchEditor(data); |
| 255 | } |
| 256 | |
| 257 | @Override |
| 258 | public void onTinyPlanet() { |
| 259 | LocalData data = getCurrentLocalData(); |
| 260 | if (data == null) { |
| 261 | return; |
| 262 | } |
Angus Kong | e0aff89 | 2013-12-11 20:51:01 -0800 | [diff] [blame] | 263 | final int currentDataId = getCurrentDataId(); |
| 264 | UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA, |
| 265 | UsageStatistics.ACTION_EDIT, null, 0, |
| 266 | UsageStatistics.hashFileName(fileNameFromDataID(currentDataId))); |
Angus Kong | b251025 | 2013-12-10 22:58:15 -0800 | [diff] [blame] | 267 | launchTinyPlanetEditor(data); |
| 268 | } |
| 269 | |
Angus Kong | e0aff89 | 2013-12-11 20:51:01 -0800 | [diff] [blame] | 270 | @Override |
| 271 | public void onDelete() { |
| 272 | final int currentDataId = getCurrentDataId(); |
| 273 | UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA, |
| 274 | UsageStatistics.ACTION_DELETE, null, 0, |
| 275 | UsageStatistics.hashFileName(fileNameFromDataID(currentDataId))); |
| 276 | removeData(currentDataId); |
| 277 | } |
| 278 | |
| 279 | @Override |
| 280 | public void onShare() { |
Angus Kong | 662fbf4 | 2013-12-12 13:22:03 -0800 | [diff] [blame] | 281 | final LocalData data = getCurrentLocalData(); |
| 282 | Intent shareIntent = getShareIntentByData(data); |
| 283 | if (shareIntent != null) { |
Angus Kong | e4002f3 | 2013-12-13 22:24:11 -0800 | [diff] [blame] | 284 | try { |
Angus Kong | 0eaf016 | 2013-12-16 15:53:30 -0800 | [diff] [blame] | 285 | launchActivityByIntent(shareIntent); |
Angus Kong | e4002f3 | 2013-12-13 22:24:11 -0800 | [diff] [blame] | 286 | mCameraAppUI.getFilmstripBottomControls().setShareEnabled(false); |
| 287 | } catch (ActivityNotFoundException ex) { |
| 288 | // Nothing. |
| 289 | } |
Angus Kong | 662fbf4 | 2013-12-12 13:22:03 -0800 | [diff] [blame] | 290 | } |
Angus Kong | e0aff89 | 2013-12-11 20:51:01 -0800 | [diff] [blame] | 291 | } |
| 292 | |
| 293 | @Override |
| 294 | public void onGallery() { |
Angus Kong | d3de171 | 2013-12-12 22:01:12 -0800 | [diff] [blame] | 295 | startGallery(); |
Angus Kong | e0aff89 | 2013-12-11 20:51:01 -0800 | [diff] [blame] | 296 | } |
| 297 | |
| 298 | private int getCurrentDataId() { |
| 299 | return mFilmstripController.getCurrentId(); |
| 300 | } |
| 301 | |
Angus Kong | b251025 | 2013-12-10 22:58:15 -0800 | [diff] [blame] | 302 | private LocalData getCurrentLocalData() { |
Angus Kong | e0aff89 | 2013-12-11 20:51:01 -0800 | [diff] [blame] | 303 | return mDataAdapter.getLocalData(getCurrentDataId()); |
Angus Kong | b251025 | 2013-12-10 22:58:15 -0800 | [diff] [blame] | 304 | } |
Angus Kong | 662fbf4 | 2013-12-12 13:22:03 -0800 | [diff] [blame] | 305 | |
| 306 | /** |
| 307 | * Sets up the share intent and NFC properly according to the data. |
| 308 | * |
| 309 | * @param data The data to be shared. |
| 310 | */ |
| 311 | private Intent getShareIntentByData(final LocalData data) { |
| 312 | Intent intent = null; |
| 313 | final Uri contentUri = data.getContentUri(); |
Angus Kong | 8a2350a | 2013-12-16 15:02:34 -0800 | [diff] [blame] | 314 | if (PanoramaMetadataLoader.isPanorama360(data) && |
Angus Kong | 662fbf4 | 2013-12-12 13:22:03 -0800 | [diff] [blame] | 315 | data.getContentUri() != Uri.EMPTY) { |
| 316 | intent = new Intent(Intent.ACTION_SEND); |
| 317 | intent.setType("application/vnd.google.panorama360+jpg"); |
| 318 | intent.putExtra(Intent.EXTRA_STREAM, contentUri); |
| 319 | } else if (data.isDataActionSupported(LocalData.DATA_ACTION_SHARE)) { |
| 320 | final String mimeType = data.getMimeType(); |
| 321 | intent = getShareIntentFromType(mimeType); |
| 322 | if (intent != null) { |
| 323 | intent.putExtra(Intent.EXTRA_STREAM, contentUri); |
| 324 | intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); |
| 325 | } |
| 326 | } |
| 327 | return intent; |
| 328 | } |
| 329 | |
| 330 | /** |
| 331 | * Get the share intent according to the mimeType |
| 332 | * |
| 333 | * @param mimeType The mimeType of current data. |
| 334 | * @return the video/image's ShareIntent or null if mimeType is invalid. |
| 335 | */ |
| 336 | private Intent getShareIntentFromType(String mimeType) { |
| 337 | // Lazily create the intent object. |
| 338 | Intent intent = new Intent(Intent.ACTION_SEND); |
| 339 | if (mimeType.startsWith("video/")) { |
| 340 | intent.setType("video/*"); |
| 341 | } else { |
| 342 | if (mimeType.startsWith("image/")) { |
| 343 | intent.setType("image/*"); |
| 344 | } else { |
| 345 | Log.w(TAG, "unsupported mimeType " + mimeType); |
| 346 | } |
| 347 | } |
| 348 | return intent; |
| 349 | } |
Angus Kong | b251025 | 2013-12-10 22:58:15 -0800 | [diff] [blame] | 350 | }; |
Angus Kong | 13e87c4 | 2013-11-25 10:02:47 -0800 | [diff] [blame] | 351 | |
Kevin Gabayan | ffbc43c | 2013-12-09 11:41:50 -0800 | [diff] [blame] | 352 | private ComboPreferences mPreferences; |
| 353 | private ContentResolver mContentResolver; |
| 354 | |
Angus Kong | 20fad24 | 2013-11-11 18:23:46 -0800 | [diff] [blame] | 355 | @Override |
| 356 | public void onCameraOpened(CameraManager.CameraProxy camera) { |
Erin Dahlgren | c120b0f | 2013-11-19 10:53:49 -0800 | [diff] [blame] | 357 | if (!mModuleManager.getModuleAgent(mCurrentModeIndex).requestAppForCamera()) { |
Angus Kong | 20fad24 | 2013-11-11 18:23:46 -0800 | [diff] [blame] | 358 | // We shouldn't be here. Just close the camera and leave. |
| 359 | camera.release(false); |
| 360 | throw new IllegalStateException("Camera opened but the module shouldn't be " + |
| 361 | "requesting"); |
| 362 | } |
Angus Kong | 13e87c4 | 2013-11-25 10:02:47 -0800 | [diff] [blame] | 363 | if (mCurrentModule != null) { |
Erin Dahlgren | 357b767 | 2013-11-20 17:38:14 -0800 | [diff] [blame] | 364 | SettingsCapabilities capabilities = |
| 365 | SettingsController.getSettingsCapabilities(camera); |
| 366 | mSettingsManager.changeCamera(camera.getCameraId(), capabilities); |
Angus Kong | 13e87c4 | 2013-11-25 10:02:47 -0800 | [diff] [blame] | 367 | mCurrentModule.onCameraAvailable(camera); |
Angus Kong | 20fad24 | 2013-11-11 18:23:46 -0800 | [diff] [blame] | 368 | } |
Erin Dahlgren | 1648c36 | 2014-01-06 15:06:04 -0800 | [diff] [blame] | 369 | mCameraAppUI.onChangeCamera(); |
Angus Kong | 20fad24 | 2013-11-11 18:23:46 -0800 | [diff] [blame] | 370 | } |
| 371 | |
| 372 | @Override |
| 373 | public void onCameraDisabled(int cameraId) { |
| 374 | UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA, UsageStatistics.ACTION_OPEN_FAIL, |
| 375 | "security"); |
| 376 | |
| 377 | CameraUtil.showErrorAndFinish(this, R.string.camera_disabled); |
| 378 | } |
| 379 | |
| 380 | @Override |
| 381 | public void onDeviceOpenFailure(int cameraId) { |
| 382 | UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA, |
| 383 | UsageStatistics.ACTION_OPEN_FAIL, "open"); |
| 384 | |
| 385 | CameraUtil.showErrorAndFinish(this, R.string.cannot_connect_camera); |
| 386 | } |
| 387 | |
| 388 | @Override |
| 389 | public void onReconnectionFailure(CameraManager mgr) { |
| 390 | UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA, |
| 391 | UsageStatistics.ACTION_OPEN_FAIL, "reconnect"); |
| 392 | |
| 393 | CameraUtil.showErrorAndFinish(this, R.string.cannot_connect_camera); |
| 394 | } |
| 395 | |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 396 | private class MainHandler extends Handler { |
| 397 | public MainHandler(Looper looper) { |
| 398 | super(looper); |
| 399 | } |
| 400 | |
| 401 | @Override |
| 402 | public void handleMessage(Message msg) { |
Angus Kong | 13e87c4 | 2013-11-25 10:02:47 -0800 | [diff] [blame] | 403 | switch (msg.what) { |
| 404 | case MSG_HIDE_ACTION_BAR: { |
| 405 | removeMessages(MSG_HIDE_ACTION_BAR); |
Angus Kong | b251025 | 2013-12-10 22:58:15 -0800 | [diff] [blame] | 406 | CameraActivity.this.setFilmstripUiVisibility(false); |
Angus Kong | 13e87c4 | 2013-11-25 10:02:47 -0800 | [diff] [blame] | 407 | break; |
| 408 | } |
| 409 | |
| 410 | case MSG_CLEAR_SCREEN_ON_FLAG: { |
| 411 | if (!mPaused) { |
| 412 | getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); |
| 413 | } |
| 414 | break; |
| 415 | } |
| 416 | |
| 417 | default: |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 418 | } |
| 419 | } |
| 420 | } |
| 421 | |
Seth Raphael | cbd8267 | 2013-11-05 10:12:36 -0800 | [diff] [blame] | 422 | private String fileNameFromDataID(int dataID) { |
| 423 | final LocalData localData = mDataAdapter.getLocalData(dataID); |
| 424 | |
| 425 | File localFile = new File(localData.getPath()); |
| 426 | return localFile.getName(); |
| 427 | } |
| 428 | |
Angus Kong | 01054e9 | 2013-12-10 11:06:18 -0800 | [diff] [blame] | 429 | private final FilmstripContentPanel.Listener mFilmstripListener = |
| 430 | new FilmstripContentPanel.Listener() { |
Angus Kong | faaee01 | 2013-12-07 00:38:46 -0800 | [diff] [blame] | 431 | |
| 432 | @Override |
| 433 | public void onFilmstripHidden() { |
| 434 | mFilmstripVisible = false; |
Angus Kong | b251025 | 2013-12-10 22:58:15 -0800 | [diff] [blame] | 435 | CameraActivity.this.setFilmstripUiVisibility(false); |
Angus Kong | faaee01 | 2013-12-07 00:38:46 -0800 | [diff] [blame] | 436 | // When the user hide the filmstrip (either swipe out or |
| 437 | // tap on back key) we move to the first item so next time |
| 438 | // when the user swipe in the filmstrip, the most recent |
| 439 | // one is shown. |
| 440 | mFilmstripController.goToFirstItem(); |
| 441 | if (mCurrentModule != null) { |
| 442 | mCurrentModule.onPreviewVisibilityChanged(true); |
| 443 | } |
| 444 | } |
| 445 | |
| 446 | @Override |
| 447 | public void onFilmstripShown() { |
| 448 | mFilmstripVisible = true; |
| 449 | updateUiByData(mFilmstripController.getCurrentId()); |
| 450 | if (mCurrentModule != null) { |
| 451 | mCurrentModule.onPreviewVisibilityChanged(false); |
| 452 | } |
| 453 | } |
| 454 | |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 455 | @Override |
| 456 | public void onDataPromoted(int dataID) { |
Seth Raphael | cbd8267 | 2013-11-05 10:12:36 -0800 | [diff] [blame] | 457 | UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA, |
| 458 | UsageStatistics.ACTION_DELETE, "promoted", 0, |
| 459 | UsageStatistics.hashFileName(fileNameFromDataID(dataID))); |
| 460 | |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 461 | removeData(dataID); |
| 462 | } |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 463 | |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 464 | @Override |
| 465 | public void onDataDemoted(int dataID) { |
Seth Raphael | cbd8267 | 2013-11-05 10:12:36 -0800 | [diff] [blame] | 466 | UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA, |
| 467 | UsageStatistics.ACTION_DELETE, "demoted", 0, |
| 468 | UsageStatistics.hashFileName(fileNameFromDataID(dataID))); |
| 469 | |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 470 | removeData(dataID); |
| 471 | } |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 472 | |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 473 | @Override |
Angus Kong | faaee01 | 2013-12-07 00:38:46 -0800 | [diff] [blame] | 474 | public void onEnterFullScreen(int dataId) { |
| 475 | if (mFilmstripVisible) { |
Angus Kong | b251025 | 2013-12-10 22:58:15 -0800 | [diff] [blame] | 476 | CameraActivity.this.setFilmstripUiVisibility(false); |
Erin Dahlgren | 3044d8c | 2013-10-10 18:23:45 -0700 | [diff] [blame] | 477 | } |
| 478 | } |
| 479 | |
| 480 | @Override |
Angus Kong | faaee01 | 2013-12-07 00:38:46 -0800 | [diff] [blame] | 481 | public void onLeaveFullScreen(int dataId) { |
| 482 | // Do nothing. |
| 483 | } |
Erin Dahlgren | 3044d8c | 2013-10-10 18:23:45 -0700 | [diff] [blame] | 484 | |
Angus Kong | faaee01 | 2013-12-07 00:38:46 -0800 | [diff] [blame] | 485 | @Override |
| 486 | public void onEnterFilmstrip(int dataId) { |
| 487 | if (mFilmstripVisible) { |
Angus Kong | b251025 | 2013-12-10 22:58:15 -0800 | [diff] [blame] | 488 | CameraActivity.this.setFilmstripUiVisibility(true); |
Erin Dahlgren | 3044d8c | 2013-10-10 18:23:45 -0700 | [diff] [blame] | 489 | } |
| 490 | } |
| 491 | |
| 492 | @Override |
Angus Kong | faaee01 | 2013-12-07 00:38:46 -0800 | [diff] [blame] | 493 | public void onLeaveFilmstrip(int dataId) { |
| 494 | // Do nothing. |
| 495 | } |
| 496 | |
| 497 | @Override |
| 498 | public void onDataReloaded() { |
| 499 | if (!mFilmstripVisible) { |
| 500 | return; |
| 501 | } |
| 502 | updateUiByData(mFilmstripController.getCurrentId()); |
| 503 | } |
| 504 | |
| 505 | @Override |
Angus Kong | 8a2350a | 2013-12-16 15:02:34 -0800 | [diff] [blame] | 506 | public void onDataUpdated(int dataId) { |
| 507 | if (!mFilmstripVisible) { |
| 508 | return; |
| 509 | } |
| 510 | updateUiByData(mFilmstripController.getCurrentId()); |
| 511 | } |
| 512 | |
| 513 | @Override |
Angus Kong | faaee01 | 2013-12-07 00:38:46 -0800 | [diff] [blame] | 514 | public void onEnterZoomView(int dataID) { |
| 515 | if (mFilmstripVisible) { |
Angus Kong | b251025 | 2013-12-10 22:58:15 -0800 | [diff] [blame] | 516 | CameraActivity.this.setFilmstripUiVisibility(false); |
Angus Kong | faaee01 | 2013-12-07 00:38:46 -0800 | [diff] [blame] | 517 | } |
| 518 | } |
| 519 | |
| 520 | @Override |
| 521 | public void onDataFocusChanged(final int prevDataId, final int newDataId) { |
| 522 | if (!mFilmstripVisible) { |
| 523 | return; |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 524 | } |
Angus Kong | 02cafdf | 2013-10-13 19:26:02 -0700 | [diff] [blame] | 525 | // TODO: This callback is UI event callback, should always |
| 526 | // happen on UI thread. Find the reason for this |
| 527 | // runOnUiThread() and fix it. |
Mangesh Ghiware | 33035c1 | 2013-08-23 13:28:21 -0700 | [diff] [blame] | 528 | runOnUiThread(new Runnable() { |
| 529 | @Override |
| 530 | public void run() { |
Angus Kong | faaee01 | 2013-12-07 00:38:46 -0800 | [diff] [blame] | 531 | updateUiByData(newDataId); |
ztenghui | 2c3d9a5 | 2013-09-03 11:27:21 -0700 | [diff] [blame] | 532 | } |
Mangesh Ghiware | 33035c1 | 2013-08-23 13:28:21 -0700 | [diff] [blame] | 533 | }); |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 534 | } |
| 535 | }; |
| 536 | |
Sascha Haeberling | 44c1afb | 2013-12-20 11:59:35 -0800 | [diff] [blame] | 537 | private final LocalDataAdapter.LocalDataListener mLocalDataListener = |
Angus Kong | e2f4c03 | 2013-12-19 10:24:33 -0800 | [diff] [blame] | 538 | new LocalDataAdapter.LocalDataListener() { |
| 539 | @Override |
| 540 | public void onMetadataUpdated(List<Integer> updatedData) { |
| 541 | int currentDataId = mFilmstripController.getCurrentId(); |
| 542 | for (Integer dataId : updatedData) { |
| 543 | if (dataId == currentDataId) { |
| 544 | updateBottomControlsByData(mDataAdapter.getLocalData(dataId)); |
| 545 | } |
| 546 | } |
| 547 | } |
| 548 | }; |
| 549 | |
Sascha Haeberling | 4ed2059 | 2013-09-13 11:58:33 -0700 | [diff] [blame] | 550 | public void gotoGallery() { |
Seth Raphael | cbd8267 | 2013-11-05 10:12:36 -0800 | [diff] [blame] | 551 | UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA, UsageStatistics.ACTION_FILMSTRIP, |
| 552 | "thumbnailTap"); |
| 553 | |
Angus Kong | 6284815 | 2013-11-08 17:25:29 -0800 | [diff] [blame] | 554 | mFilmstripController.goToNextItem(); |
Sascha Haeberling | 4ed2059 | 2013-09-13 11:58:33 -0700 | [diff] [blame] | 555 | } |
| 556 | |
Sascha Haeberling | 5199c20 | 2013-09-05 17:10:19 -0700 | [diff] [blame] | 557 | /** |
Angus Kong | faaee01 | 2013-12-07 00:38:46 -0800 | [diff] [blame] | 558 | * If {@param visible} is false, this hides the action bar and switches the |
Angus Kong | b251025 | 2013-12-10 22:58:15 -0800 | [diff] [blame] | 559 | * filmstrip UI to lights-out mode. |
Sascha Haeberling | 5199c20 | 2013-09-05 17:10:19 -0700 | [diff] [blame] | 560 | */ |
Doris Liu | 97cb1ea | 2013-10-11 16:54:51 -0700 | [diff] [blame] | 561 | // TODO: This should not be called outside of the activity. |
Angus Kong | b251025 | 2013-12-10 22:58:15 -0800 | [diff] [blame] | 562 | public void setFilmstripUiVisibility(boolean visible) { |
Angus Kong | 13e87c4 | 2013-11-25 10:02:47 -0800 | [diff] [blame] | 563 | mMainHandler.removeMessages(MSG_HIDE_ACTION_BAR); |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 564 | |
ztenghui | 17f1e65 | 2013-11-06 14:20:31 -0800 | [diff] [blame] | 565 | int currentSystemUIVisibility = mAboveFilmstripControlLayout.getSystemUiVisibility(); |
Doris Liu | 773e1c9 | 2013-12-02 17:35:03 -0800 | [diff] [blame] | 566 | int newSystemUIVisibility = (visible ? View.SYSTEM_UI_FLAG_VISIBLE : |
ztenghui | 17f1e65 | 2013-11-06 14:20:31 -0800 | [diff] [blame] | 567 | View.SYSTEM_UI_FLAG_LOW_PROFILE | View.SYSTEM_UI_FLAG_FULLSCREEN); |
| 568 | if (newSystemUIVisibility != currentSystemUIVisibility) { |
| 569 | mAboveFilmstripControlLayout.setSystemUiVisibility(newSystemUIVisibility); |
| 570 | } |
Doris Liu | 97cb1ea | 2013-10-11 16:54:51 -0700 | [diff] [blame] | 571 | |
ztenghui | 17f1e65 | 2013-11-06 14:20:31 -0800 | [diff] [blame] | 572 | boolean currentActionBarVisibility = mActionBar.isShowing(); |
Angus Kong | b251025 | 2013-12-10 22:58:15 -0800 | [diff] [blame] | 573 | mCameraAppUI.getFilmstripBottomControls().setVisible(visible); |
ztenghui | 17f1e65 | 2013-11-06 14:20:31 -0800 | [diff] [blame] | 574 | if (visible != currentActionBarVisibility) { |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 575 | if (visible) { |
| 576 | mActionBar.show(); |
| 577 | } else { |
| 578 | mActionBar.hide(); |
| 579 | } |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 580 | } |
Sascha Haeberling | 5199c20 | 2013-09-05 17:10:19 -0700 | [diff] [blame] | 581 | } |
| 582 | |
Sascha Haeberling | a63dbb6 | 2013-11-22 11:55:32 -0800 | [diff] [blame] | 583 | private void hideSessionProgress() { |
| 584 | mSessionProgressPanel.setVisibility(View.GONE); |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 585 | } |
| 586 | |
Sascha Haeberling | a63dbb6 | 2013-11-22 11:55:32 -0800 | [diff] [blame] | 587 | private void showSessionProgress(CharSequence message) { |
| 588 | mBottomProgressText.setText(message); |
| 589 | mSessionProgressPanel.setVisibility(View.VISIBLE); |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 590 | } |
| 591 | |
Sascha Haeberling | a63dbb6 | 2013-11-22 11:55:32 -0800 | [diff] [blame] | 592 | private void updateSessionProgress(int progress) { |
| 593 | mBottomProgressBar.setProgress(progress); |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 594 | } |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 595 | |
Mangesh Ghiware | a5682ab | 2013-09-19 09:24:23 -0700 | [diff] [blame] | 596 | @TargetApi(Build.VERSION_CODES.JELLY_BEAN) |
| 597 | private void setupNfcBeamPush() { |
| 598 | NfcAdapter adapter = NfcAdapter.getDefaultAdapter(CameraActivity.this); |
| 599 | if (adapter == null) { |
| 600 | return; |
| 601 | } |
| 602 | |
| 603 | if (!ApiHelper.HAS_SET_BEAM_PUSH_URIS) { |
| 604 | // Disable beaming |
| 605 | adapter.setNdefPushMessage(null, CameraActivity.this); |
| 606 | return; |
| 607 | } |
| 608 | |
| 609 | adapter.setBeamPushUris(null, CameraActivity.this); |
| 610 | adapter.setBeamPushUrisCallback(new CreateBeamUrisCallback() { |
| 611 | @Override |
| 612 | public Uri[] createBeamUris(NfcEvent event) { |
| 613 | return mNfcPushUris; |
| 614 | } |
| 615 | }, CameraActivity.this); |
| 616 | } |
| 617 | |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 618 | @Override |
| 619 | public void onMenuVisibilityChanged(boolean isVisible) { |
Angus Kong | faaee01 | 2013-12-07 00:38:46 -0800 | [diff] [blame] | 620 | // TODO: Remove this or bring back the original implementation: cancel |
| 621 | // auto-hide actionbar. |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 622 | } |
| 623 | |
Seth Raphael | cbd8267 | 2013-11-05 10:12:36 -0800 | [diff] [blame] | 624 | @Override |
| 625 | public boolean onShareTargetSelected(ShareActionProvider shareActionProvider, Intent intent) { |
Angus Kong | 6284815 | 2013-11-08 17:25:29 -0800 | [diff] [blame] | 626 | int currentDataId = mFilmstripController.getCurrentId(); |
Seth Raphael | cbd8267 | 2013-11-05 10:12:36 -0800 | [diff] [blame] | 627 | if (currentDataId < 0) { |
| 628 | return false; |
| 629 | } |
| 630 | UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA, UsageStatistics.ACTION_SHARE, |
| 631 | intent.getComponent().getPackageName(), 0, |
| 632 | UsageStatistics.hashFileName(fileNameFromDataID(currentDataId))); |
| 633 | return true; |
| 634 | } |
| 635 | |
Sascha Haeberling | 14ff6c8 | 2013-12-13 13:29:58 -0800 | [diff] [blame] | 636 | // Note: All callbacks come back on the main thread. |
Sascha Haeberling | a63dbb6 | 2013-11-22 11:55:32 -0800 | [diff] [blame] | 637 | private final SessionListener mSessionListener = |
| 638 | new SessionListener() { |
Ruben Brunk | 7cfcafd | 2013-10-17 15:41:44 -0700 | [diff] [blame] | 639 | @Override |
Sascha Haeberling | a63dbb6 | 2013-11-22 11:55:32 -0800 | [diff] [blame] | 640 | public void onSessionQueued(final Uri uri) { |
Sascha Haeberling | 14ff6c8 | 2013-12-13 13:29:58 -0800 | [diff] [blame] | 641 | notifyNewMedia(uri); |
| 642 | int dataID = mDataAdapter.findDataByContentUri(uri); |
| 643 | if (dataID != -1) { |
| 644 | // Don't allow special UI actions (swipe to |
| 645 | // delete, for example) on in-progress data. |
| 646 | LocalData d = mDataAdapter.getLocalData(dataID); |
| 647 | InProgressDataWrapper newData = new InProgressDataWrapper(d); |
| 648 | mDataAdapter.updateData(dataID, newData); |
| 649 | } |
Angus Kong | 6798c34 | 2013-07-16 15:14:58 -0700 | [diff] [blame] | 650 | } |
| 651 | |
| 652 | @Override |
Sascha Haeberling | a63dbb6 | 2013-11-22 11:55:32 -0800 | [diff] [blame] | 653 | public void onSessionDone(final Uri uri) { |
| 654 | Log.v(TAG, "onSessionDone:" + uri); |
Sascha Haeberling | 14ff6c8 | 2013-12-13 13:29:58 -0800 | [diff] [blame] | 655 | int doneID = mDataAdapter.findDataByContentUri(uri); |
| 656 | int currentDataId = mFilmstripController.getCurrentId(); |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 657 | |
Sascha Haeberling | 14ff6c8 | 2013-12-13 13:29:58 -0800 | [diff] [blame] | 658 | if (currentDataId == doneID) { |
| 659 | hideSessionProgress(); |
| 660 | updateSessionProgress(0); |
| 661 | } |
Sascha Haeberling | 44c1afb | 2013-12-20 11:59:35 -0800 | [diff] [blame] | 662 | mDataAdapter.refresh(uri, /* isInProgress */ false); |
Angus Kong | 6798c34 | 2013-07-16 15:14:58 -0700 | [diff] [blame] | 663 | } |
| 664 | |
| 665 | @Override |
Sascha Haeberling | a63dbb6 | 2013-11-22 11:55:32 -0800 | [diff] [blame] | 666 | public void onSessionProgress(final Uri uri, final int progress) { |
| 667 | if (progress < 0) { |
| 668 | // Do nothing, there is no task for this URI. |
| 669 | return; |
| 670 | } |
Sascha Haeberling | 14ff6c8 | 2013-12-13 13:29:58 -0800 | [diff] [blame] | 671 | int currentDataId = mFilmstripController.getCurrentId(); |
| 672 | if (currentDataId == -1) { |
| 673 | return; |
| 674 | } |
| 675 | if (uri.equals( |
| 676 | mDataAdapter.getLocalData(currentDataId).getContentUri())) { |
| 677 | updateSessionProgress(progress); |
| 678 | } |
| 679 | } |
| 680 | |
| 681 | @Override |
| 682 | public void onSessionUpdated(Uri uri) { |
Sascha Haeberling | 44c1afb | 2013-12-20 11:59:35 -0800 | [diff] [blame] | 683 | mDataAdapter.refresh(uri, /* isInProgress */ true); |
Angus Kong | 6798c34 | 2013-07-16 15:14:58 -0700 | [diff] [blame] | 684 | } |
| 685 | }; |
| 686 | |
Angus Kong | 9f1db52 | 2013-11-09 16:25:59 -0800 | [diff] [blame] | 687 | @Override |
| 688 | public Context getAndroidContext() { |
| 689 | return this; |
| 690 | } |
| 691 | |
| 692 | @Override |
Angus Kong | 0eaf016 | 2013-12-16 15:53:30 -0800 | [diff] [blame] | 693 | public void launchActivityByIntent(Intent intent) { |
| 694 | startActivityForResult(intent, REQ_CODE_DONT_SWITCH_TO_PREVIEW); |
| 695 | } |
| 696 | |
| 697 | @Override |
Doris Liu | f55f3c4 | 2013-11-20 00:24:46 -0800 | [diff] [blame] | 698 | public int getCurrentModuleIndex() { |
| 699 | return mCurrentModeIndex; |
| 700 | } |
| 701 | |
| 702 | @Override |
Angus Kong | 9f1db52 | 2013-11-09 16:25:59 -0800 | [diff] [blame] | 703 | public SurfaceTexture getPreviewBuffer() { |
| 704 | // TODO: implement this |
| 705 | return null; |
| 706 | } |
| 707 | |
| 708 | @Override |
Doris Liu | 2b906b8 | 2013-12-10 16:34:08 -0800 | [diff] [blame] | 709 | public void onPreviewStarted() { |
| 710 | mCameraAppUI.onPreviewStarted(); |
| 711 | } |
| 712 | |
| 713 | @Override |
Doris Liu | 482de02 | 2013-12-18 19:18:16 -0800 | [diff] [blame] | 714 | public void addPreviewAreaSizeChangedListener( |
| 715 | PreviewStatusListener.PreviewAreaSizeChangedListener listener) { |
| 716 | mCameraAppUI.addPreviewAreaSizeChangedListener(listener); |
| 717 | } |
| 718 | |
| 719 | @Override |
| 720 | public void removePreviewAreaSizeChangedListener( |
| 721 | PreviewStatusListener.PreviewAreaSizeChangedListener listener) { |
| 722 | mCameraAppUI.removePreviewAreaSizeChangedListener(listener); |
| 723 | } |
| 724 | |
| 725 | @Override |
Doris Liu | 4d4a4bc | 2013-12-19 18:55:54 -0800 | [diff] [blame] | 726 | public void setupOneShotPreviewListener() { |
| 727 | mCameraController.setOneShotPreviewCallback(mMainHandler, |
| 728 | new CameraManager.CameraPreviewDataCallback() { |
Doris Liu | 482de02 | 2013-12-18 19:18:16 -0800 | [diff] [blame] | 729 | @Override |
| 730 | public void onPreviewFrame(byte[] data, CameraManager.CameraProxy camera) { |
| 731 | mCameraAppUI.onNewPreviewFrame(); |
| 732 | } |
| 733 | }); |
Doris Liu | 4d4a4bc | 2013-12-19 18:55:54 -0800 | [diff] [blame] | 734 | } |
| 735 | |
| 736 | @Override |
Doris Liu | 70da918 | 2013-12-17 18:41:15 -0800 | [diff] [blame] | 737 | public void updatePreviewAspectRatio(float aspectRatio) { |
| 738 | mCameraAppUI.updatePreviewAspectRatio(aspectRatio); |
| 739 | } |
| 740 | |
| 741 | @Override |
| 742 | public void updatePreviewTransform(Matrix matrix) { |
| 743 | mCameraAppUI.updatePreviewTransform(matrix); |
| 744 | } |
| 745 | |
| 746 | @Override |
Doris Liu | 06db742 | 2013-12-09 19:36:25 -0800 | [diff] [blame] | 747 | public void setPreviewStatusListener(PreviewStatusListener previewStatusListener) { |
| 748 | mCameraAppUI.setPreviewStatusListener(previewStatusListener); |
| 749 | } |
| 750 | |
| 751 | @Override |
Angus Kong | 9f1db52 | 2013-11-09 16:25:59 -0800 | [diff] [blame] | 752 | public FrameLayout getModuleLayoutRoot() { |
Doris Liu | c6c9740 | 2013-12-06 21:02:53 -0800 | [diff] [blame] | 753 | return mCameraAppUI.getModuleRootView(); |
Angus Kong | 9f1db52 | 2013-11-09 16:25:59 -0800 | [diff] [blame] | 754 | } |
| 755 | |
| 756 | @Override |
| 757 | public void setShutterEventsListener(ShutterEventsListener listener) { |
| 758 | // TODO: implement this |
| 759 | } |
| 760 | |
| 761 | @Override |
| 762 | public void setShutterEnabled(boolean enabled) { |
| 763 | // TODO: implement this |
| 764 | } |
| 765 | |
| 766 | @Override |
| 767 | public boolean isShutterEnabled() { |
| 768 | // TODO: implement this |
| 769 | return false; |
| 770 | } |
| 771 | |
| 772 | @Override |
| 773 | public void startPreCaptureAnimation() { |
Doris Liu | 1dfe782 | 2013-12-12 00:02:08 -0800 | [diff] [blame] | 774 | mCameraAppUI.startPreCaptureAnimation(); |
Angus Kong | 9f1db52 | 2013-11-09 16:25:59 -0800 | [diff] [blame] | 775 | } |
| 776 | |
| 777 | @Override |
| 778 | public void cancelPreCaptureAnimation() { |
| 779 | // TODO: implement this |
| 780 | } |
| 781 | |
| 782 | @Override |
| 783 | public void startPostCaptureAnimation() { |
| 784 | // TODO: implement this |
| 785 | } |
| 786 | |
| 787 | @Override |
| 788 | public void startPostCaptureAnimation(Bitmap thumbnail) { |
| 789 | // TODO: implement this |
| 790 | } |
| 791 | |
| 792 | @Override |
| 793 | public void cancelPostCaptureAnimation() { |
| 794 | // TODO: implement this |
| 795 | } |
| 796 | |
| 797 | @Override |
Angus Kong | 9f1db52 | 2013-11-09 16:25:59 -0800 | [diff] [blame] | 798 | public OrientationManager getOrientationManager() { |
| 799 | return mOrientationManager; |
| 800 | } |
| 801 | |
| 802 | @Override |
| 803 | public LocationManager getLocationManager() { |
Erin Dahlgren | 21c21a6 | 2013-11-19 16:37:38 -0800 | [diff] [blame] | 804 | return mLocationManager; |
Angus Kong | 9f1db52 | 2013-11-09 16:25:59 -0800 | [diff] [blame] | 805 | } |
| 806 | |
| 807 | @Override |
| 808 | public void lockOrientation() { |
| 809 | mOrientationManager.lockOrientation(); |
| 810 | } |
| 811 | |
| 812 | @Override |
| 813 | public void unlockOrientation() { |
| 814 | mOrientationManager.unlockOrientation(); |
| 815 | } |
| 816 | |
| 817 | @Override |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 818 | public void notifyNewMedia(Uri uri) { |
| 819 | ContentResolver cr = getContentResolver(); |
| 820 | String mimeType = cr.getType(uri); |
| 821 | if (mimeType.startsWith("video/")) { |
Angus Kong | b50b5cb | 2013-08-09 14:55:20 -0700 | [diff] [blame] | 822 | sendBroadcast(new Intent(CameraUtil.ACTION_NEW_VIDEO, uri)); |
Sascha Haeberling | 44c1afb | 2013-12-20 11:59:35 -0800 | [diff] [blame] | 823 | mDataAdapter.addNewVideo(uri); |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 824 | } else if (mimeType.startsWith("image/")) { |
Angus Kong | b50b5cb | 2013-08-09 14:55:20 -0700 | [diff] [blame] | 825 | CameraUtil.broadcastNewPicture(this, uri); |
Sascha Haeberling | 44c1afb | 2013-12-20 11:59:35 -0800 | [diff] [blame] | 826 | mDataAdapter.addNewPhoto(uri); |
Ruben Brunk | 7cfcafd | 2013-10-17 15:41:44 -0700 | [diff] [blame] | 827 | } else if (mimeType.startsWith(PlaceholderManager.PLACEHOLDER_MIME_TYPE)) { |
Sascha Haeberling | 44c1afb | 2013-12-20 11:59:35 -0800 | [diff] [blame] | 828 | mDataAdapter.addNewPhoto(uri); |
Doris Liu | 48239f4 | 2013-03-04 22:19:10 -0800 | [diff] [blame] | 829 | } else { |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 830 | android.util.Log.w(TAG, "Unknown new media with MIME type:" |
| 831 | + mimeType + ", uri:" + uri); |
Doris Liu | 48239f4 | 2013-03-04 22:19:10 -0800 | [diff] [blame] | 832 | } |
| 833 | } |
| 834 | |
Angus Kong | 20fad24 | 2013-11-11 18:23:46 -0800 | [diff] [blame] | 835 | @Override |
Angus Kong | 13e87c4 | 2013-11-25 10:02:47 -0800 | [diff] [blame] | 836 | public void enableKeepScreenOn(boolean enabled) { |
| 837 | if (mPaused) { |
| 838 | return; |
| 839 | } |
| 840 | |
| 841 | mKeepScreenOn = enabled; |
| 842 | if (mKeepScreenOn) { |
| 843 | mMainHandler.removeMessages(MSG_CLEAR_SCREEN_ON_FLAG); |
| 844 | getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); |
| 845 | } else { |
| 846 | keepScreenOnForAWhile(); |
| 847 | } |
| 848 | } |
| 849 | |
| 850 | @Override |
Angus Kong | 20fad24 | 2013-11-11 18:23:46 -0800 | [diff] [blame] | 851 | public CameraProvider getCameraProvider() { |
| 852 | return mCameraController; |
| 853 | } |
| 854 | |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 855 | private void removeData(int dataID) { |
Sascha Haeberling | 44c1afb | 2013-12-20 11:59:35 -0800 | [diff] [blame] | 856 | mDataAdapter.removeData(dataID); |
Doris Liu | 742cd5b | 2013-09-12 16:17:43 -0700 | [diff] [blame] | 857 | if (mDataAdapter.getTotalNumber() > 1) { |
| 858 | showUndoDeletionBar(); |
| 859 | } else { |
| 860 | // If camera preview is the only view left in filmstrip, |
| 861 | // no need to show undo bar. |
Doris Liu | f2c1433 | 2013-09-26 11:24:37 -0700 | [diff] [blame] | 862 | mPendingDeletion = true; |
Doris Liu | 742cd5b | 2013-09-12 16:17:43 -0700 | [diff] [blame] | 863 | performDeletion(); |
| 864 | } |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 865 | } |
| 866 | |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 867 | @Override |
| 868 | public boolean onOptionsItemSelected(MenuItem item) { |
| 869 | // Handle presses on the action bar items |
| 870 | switch (item.getItemId()) { |
Alan Newberger | 3f969c1 | 2013-08-23 10:10:30 -0700 | [diff] [blame] | 871 | case android.R.id.home: |
Angus Kong | 248f42b | 2013-12-06 15:49:17 -0800 | [diff] [blame] | 872 | onBackPressed(); |
| 873 | return true; |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 874 | default: |
| 875 | return super.onOptionsItemSelected(item); |
| 876 | } |
| 877 | } |
| 878 | |
ztenghui | fd43e3b | 2013-09-03 11:30:11 -0700 | [diff] [blame] | 879 | private boolean isCaptureIntent() { |
| 880 | if (MediaStore.ACTION_VIDEO_CAPTURE.equals(getIntent().getAction()) |
| 881 | || MediaStore.ACTION_IMAGE_CAPTURE.equals(getIntent().getAction()) |
| 882 | || MediaStore.ACTION_IMAGE_CAPTURE_SECURE.equals(getIntent().getAction())) { |
| 883 | return true; |
| 884 | } else { |
| 885 | return false; |
| 886 | } |
| 887 | } |
| 888 | |
ztenghui | 0353ca2 | 2013-08-13 13:53:16 -0700 | [diff] [blame] | 889 | @Override |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 890 | public void onCreate(Bundle state) { |
| 891 | super.onCreate(state); |
Sascha Haeberling | 048bf4d | 2013-10-06 17:49:51 -0700 | [diff] [blame] | 892 | GcamHelper.init(getContentResolver()); |
| 893 | |
ztenghui | 50df470 | 2013-08-13 15:53:57 -0700 | [diff] [blame] | 894 | getWindow().requestFeature(Window.FEATURE_ACTION_BAR); |
Doris Liu | 1c94b7d | 2013-11-09 19:13:44 -0800 | [diff] [blame] | 895 | setContentView(R.layout.activity_main); |
ztenghui | fa9e2cc | 2013-08-09 17:37:15 -0700 | [diff] [blame] | 896 | mActionBar = getActionBar(); |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 897 | mActionBar.addOnMenuVisibilityListener(this); |
Angus Kong | 20fad24 | 2013-11-11 18:23:46 -0800 | [diff] [blame] | 898 | mMainHandler = new MainHandler(getMainLooper()); |
| 899 | mCameraController = |
| 900 | new CameraController(this, this, mMainHandler, |
| 901 | CameraManagerFactory.getAndroidCameraManager()); |
Kevin Gabayan | ffbc43c | 2013-12-09 11:41:50 -0800 | [diff] [blame] | 902 | mPreferences = new ComboPreferences(getAndroidContext()); |
| 903 | mContentResolver = this.getContentResolver(); |
Angus Kong | 40d95e9 | 2013-11-27 15:13:34 -0800 | [diff] [blame] | 904 | |
Erin Dahlgren | 7f0151d | 2014-01-02 16:08:12 -0800 | [diff] [blame] | 905 | mSettingsManager = new SettingsManager(this, mCameraController.getNumberOfCameras()); |
| 906 | |
Angus Kong | 40d95e9 | 2013-11-27 15:13:34 -0800 | [diff] [blame] | 907 | // Remove this after we get rid of ComboPreferences. |
| 908 | int cameraId = Integer.parseInt(mSettingsManager.get(SettingsManager.SETTING_CAMERA_ID)); |
Kevin Gabayan | ffbc43c | 2013-12-09 11:41:50 -0800 | [diff] [blame] | 909 | mPreferences.setLocalId(this, cameraId); |
| 910 | CameraSettings.upgradeGlobalPreferences(mPreferences, |
| 911 | mCameraController.getNumberOfCameras()); |
Angus Kong | 20fad24 | 2013-11-11 18:23:46 -0800 | [diff] [blame] | 912 | // TODO: Try to move all the resources allocation to happen as soon as |
| 913 | // possible so we can call module.init() at the earliest time. |
| 914 | mModuleManager = new ModuleManagerImpl(); |
Angus Kong | 612321f | 2013-11-18 16:17:43 -0800 | [diff] [blame] | 915 | ModulesInfo.setupModules(this, mModuleManager); |
ztenghui | fa9e2cc | 2013-08-09 17:37:15 -0700 | [diff] [blame] | 916 | |
Doris Liu | 70576b6 | 2013-11-14 20:30:33 -0800 | [diff] [blame] | 917 | mModeListView = (ModeListView) findViewById(R.id.mode_list_layout); |
Doris Liu | a20074f | 2013-12-09 15:19:06 -0800 | [diff] [blame] | 918 | mModeListView.init(mModuleManager.getSupportedModeIndexList()); |
Michael Kolb | 0865018 | 2013-02-25 19:43:56 -0800 | [diff] [blame] | 919 | if (ApiHelper.HAS_ROTATION_ANIMATION) { |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 920 | setRotationAnimation(); |
Michael Kolb | 0865018 | 2013-02-25 19:43:56 -0800 | [diff] [blame] | 921 | } |
Doris Liu | aa87442 | 2013-09-18 19:43:12 -0700 | [diff] [blame] | 922 | |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 923 | // Check if this is in the secure camera mode. |
| 924 | Intent intent = getIntent(); |
| 925 | String action = intent.getAction(); |
Doris Liu | b84b973 | 2013-06-18 17:14:26 -0700 | [diff] [blame] | 926 | if (INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE.equals(action) |
| 927 | || ACTION_IMAGE_CAPTURE_SECURE.equals(action)) { |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 928 | mSecureCamera = true; |
| 929 | } else { |
| 930 | mSecureCamera = intent.getBooleanExtra(SECURE_CAMERA_EXTRA, false); |
| 931 | } |
Doris Liu | b84b973 | 2013-06-18 17:14:26 -0700 | [diff] [blame] | 932 | |
| 933 | if (mSecureCamera) { |
| 934 | // Change the window flags so that secure camera can show when locked |
| 935 | Window win = getWindow(); |
| 936 | WindowManager.LayoutParams params = win.getAttributes(); |
| 937 | params.flags |= WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; |
| 938 | win.setAttributes(params); |
| 939 | |
| 940 | // Filter for screen off so that we can finish secure camera activity |
| 941 | // when screen is off. |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 942 | IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF); |
| 943 | registerReceiver(mScreenOffReceiver, filter); |
Doris Liu | b84b973 | 2013-06-18 17:14:26 -0700 | [diff] [blame] | 944 | } |
Angus Kong | b251025 | 2013-12-10 22:58:15 -0800 | [diff] [blame] | 945 | mCameraAppUI = new CameraAppUI(this, |
| 946 | (MainActivityLayout) findViewById(R.id.activity_root_view), |
| 947 | isSecureCamera(), isCaptureIntent()); |
| 948 | |
| 949 | mCameraAppUI.setFilmstripBottomControlsListener(mMyFilmstripBottomControlListener); |
| 950 | |
Angus Kong | 653c43b | 2013-08-21 18:28:43 -0700 | [diff] [blame] | 951 | mAboveFilmstripControlLayout = |
Angus Kong | b95699e | 2013-12-07 13:52:51 -0800 | [diff] [blame] | 952 | (FrameLayout) findViewById(R.id.camera_filmstrip_content_layout); |
Sascha Haeberling | a63dbb6 | 2013-11-22 11:55:32 -0800 | [diff] [blame] | 953 | |
| 954 | // Add the session listener so we can track the session progress updates. |
| 955 | getServices().getCaptureSessionManager().addSessionListener(mSessionListener); |
| 956 | mSessionProgressPanel = findViewById(R.id.pano_session_progress_panel); |
| 957 | mBottomProgressBar = (ProgressBar) findViewById(R.id.pano_session_progress_bar); |
| 958 | mBottomProgressText = (TextView) findViewById(R.id.pano_session_progress_text); |
Angus Kong | 6284815 | 2013-11-08 17:25:29 -0800 | [diff] [blame] | 959 | mFilmstripController = ((FilmstripView) findViewById(R.id.filmstrip_view)).getController(); |
Angus Kong | faaee01 | 2013-12-07 00:38:46 -0800 | [diff] [blame] | 960 | mFilmstripController.setImageGap( |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 961 | getResources().getDimensionPixelSize(R.dimen.camera_film_strip_gap)); |
Sascha Haeberling | f1f5186 | 2013-07-31 11:28:21 -0700 | [diff] [blame] | 962 | mPanoramaViewHelper = new PanoramaViewHelper(this); |
| 963 | mPanoramaViewHelper.onCreate(); |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 964 | // Set up the camera preview first so the preview shows up ASAP. |
Sascha Haeberling | 44c1afb | 2013-12-20 11:59:35 -0800 | [diff] [blame] | 965 | mDataAdapter = new CameraDataAdapter(getApplicationContext(), |
Angus Kong | 166e36f | 2013-12-03 08:54:42 -0800 | [diff] [blame] | 966 | new ColorDrawable(getResources().getColor(R.color.photo_placeholder))); |
Angus Kong | e2f4c03 | 2013-12-19 10:24:33 -0800 | [diff] [blame] | 967 | mDataAdapter.setLocalDataListener(mLocalDataListener); |
Angus Kong | faaee01 | 2013-12-07 00:38:46 -0800 | [diff] [blame] | 968 | |
Spike Sprague | 0f3c4b4 | 2013-12-10 19:50:17 -0800 | [diff] [blame] | 969 | mCameraAppUI.getFilmstripContentPanel().setFilmstripListener(mFilmstripListener); |
Sascha Haeberling | 2654dd9 | 2013-08-28 15:28:57 -0700 | [diff] [blame] | 970 | |
Kevin Gabayan | ffbc43c | 2013-12-09 11:41:50 -0800 | [diff] [blame] | 971 | mLocationManager = new LocationManager(this); |
Erin Dahlgren | 21c21a6 | 2013-11-19 16:37:38 -0800 | [diff] [blame] | 972 | |
Erin Dahlgren | 357b767 | 2013-11-20 17:38:14 -0800 | [diff] [blame] | 973 | mSettingsController = new SettingsController(this, mSettingsManager, mLocationManager); |
| 974 | |
| 975 | int modeIndex = -1; |
| 976 | if (MediaStore.INTENT_ACTION_VIDEO_CAMERA.equals(getIntent().getAction()) |
| 977 | || MediaStore.ACTION_VIDEO_CAPTURE.equals(getIntent().getAction())) { |
| 978 | modeIndex = ModeListView.MODE_VIDEO; |
| 979 | } else if (MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA.equals(getIntent().getAction()) |
| 980 | || MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE.equals(getIntent() |
| 981 | .getAction())) { |
| 982 | modeIndex = ModeListView.MODE_PHOTO; |
Erin Dahlgren | 635a4b8 | 2013-11-25 15:21:18 -0800 | [diff] [blame] | 983 | if (mSettingsManager.getInt(SettingsManager.SETTING_STARTUP_MODULE_INDEX) |
Erin Dahlgren | 357b767 | 2013-11-20 17:38:14 -0800 | [diff] [blame] | 984 | == ModeListView.MODE_GCAM && GcamHelper.hasGcamCapture()) { |
| 985 | modeIndex = ModeListView.MODE_GCAM; |
| 986 | } |
| 987 | } else if (MediaStore.ACTION_IMAGE_CAPTURE.equals(getIntent().getAction()) |
| 988 | || MediaStore.ACTION_IMAGE_CAPTURE_SECURE.equals(getIntent().getAction())) { |
| 989 | modeIndex = ModeListView.MODE_PHOTO; |
| 990 | } else { |
| 991 | // If the activity has not been started using an explicit intent, |
| 992 | // read the module index from the last time the user changed modes |
Erin Dahlgren | 635a4b8 | 2013-11-25 15:21:18 -0800 | [diff] [blame] | 993 | modeIndex = mSettingsManager.getInt(SettingsManager.SETTING_STARTUP_MODULE_INDEX); |
Erin Dahlgren | 357b767 | 2013-11-20 17:38:14 -0800 | [diff] [blame] | 994 | if ((modeIndex == ModeListView.MODE_GCAM && |
| 995 | !GcamHelper.hasGcamCapture()) || modeIndex < 0) { |
| 996 | modeIndex = ModeListView.MODE_PHOTO; |
| 997 | } |
| 998 | } |
| 999 | |
| 1000 | mOrientationManager = new OrientationManagerImpl(this); |
| 1001 | mOrientationManager.addOnOrientationChangeListener(mMainHandler, this); |
Erin Dahlgren | c120b0f | 2013-11-19 10:53:49 -0800 | [diff] [blame] | 1002 | |
| 1003 | setModuleFromModeIndex(modeIndex); |
Doris Liu | f55f3c4 | 2013-11-20 00:24:46 -0800 | [diff] [blame] | 1004 | |
| 1005 | // TODO: Remove this when refactor is done. |
Erin Dahlgren | 5f500be | 2013-12-10 14:53:35 -0800 | [diff] [blame] | 1006 | if (modeIndex == ModulesInfo.MODULE_PHOTO |
| 1007 | || modeIndex == ModulesInfo.MODULE_VIDEO |
Erin Dahlgren | 79fcbe4 | 2013-12-13 15:52:30 -0800 | [diff] [blame] | 1008 | || modeIndex == ModulesInfo.MODULE_GCAM |
Erin Dahlgren | 4efa8b5 | 2013-12-17 18:31:35 -0800 | [diff] [blame] | 1009 | || modeIndex == ModulesInfo.MODULE_CRAFT |
| 1010 | || modeIndex == ModulesInfo.MODULE_REFOCUS) { |
Doris Liu | f55f3c4 | 2013-11-20 00:24:46 -0800 | [diff] [blame] | 1011 | mCameraAppUI.prepareModuleUI(); |
| 1012 | } |
Angus Kong | 13e87c4 | 2013-11-25 10:02:47 -0800 | [diff] [blame] | 1013 | mCurrentModule.init(this, isSecureCamera(), isCaptureIntent()); |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 1014 | |
| 1015 | if (!mSecureCamera) { |
Angus Kong | 6284815 | 2013-11-08 17:25:29 -0800 | [diff] [blame] | 1016 | mFilmstripController.setDataAdapter(mDataAdapter); |
Angus Kong | a719460 | 2013-09-06 17:20:15 -0700 | [diff] [blame] | 1017 | if (!isCaptureIntent()) { |
Sascha Haeberling | 44c1afb | 2013-12-20 11:59:35 -0800 | [diff] [blame] | 1018 | mDataAdapter.requestLoad(); |
Angus Kong | a719460 | 2013-09-06 17:20:15 -0700 | [diff] [blame] | 1019 | } |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 1020 | } else { |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 1021 | // Put a lock placeholder as the last image by setting its date to |
| 1022 | // 0. |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 1023 | ImageView v = (ImageView) getLayoutInflater().inflate( |
| 1024 | R.layout.secure_album_placeholder, null); |
Angus Kong | 690dc47 | 2013-09-21 14:48:51 -0700 | [diff] [blame] | 1025 | v.setOnClickListener(new View.OnClickListener() { |
| 1026 | @Override |
| 1027 | public void onClick(View view) { |
Angus Kong | d3de171 | 2013-12-12 22:01:12 -0800 | [diff] [blame] | 1028 | startGallery(); |
Angus Kong | 690dc47 | 2013-09-21 14:48:51 -0700 | [diff] [blame] | 1029 | finish(); |
| 1030 | } |
| 1031 | }); |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 1032 | mDataAdapter = new FixedLastDataAdapter( |
Sascha Haeberling | 44c1afb | 2013-12-20 11:59:35 -0800 | [diff] [blame] | 1033 | getApplicationContext(), |
Angus Kong | 166e36f | 2013-12-03 08:54:42 -0800 | [diff] [blame] | 1034 | mDataAdapter, |
Angus Kong | bd26069 | 2013-08-07 14:52:56 -0700 | [diff] [blame] | 1035 | new SimpleViewData( |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 1036 | v, |
| 1037 | v.getDrawable().getIntrinsicWidth(), |
| 1038 | v.getDrawable().getIntrinsicHeight(), |
| 1039 | 0, 0)); |
| 1040 | // Flush out all the original data. |
| 1041 | mDataAdapter.flush(); |
Angus Kong | 6284815 | 2013-11-08 17:25:29 -0800 | [diff] [blame] | 1042 | mFilmstripController.setDataAdapter(mDataAdapter); |
Sascha Haeberling | 37f3611 | 2013-08-06 14:31:52 -0700 | [diff] [blame] | 1043 | } |
Mangesh Ghiware | a5682ab | 2013-09-19 09:24:23 -0700 | [diff] [blame] | 1044 | |
| 1045 | setupNfcBeamPush(); |
ztenghui | 064d600 | 2013-09-05 15:47:58 -0700 | [diff] [blame] | 1046 | |
Doris Liu | 2b86d87 | 2013-09-26 15:23:41 -0700 | [diff] [blame] | 1047 | mLocalImagesObserver = new LocalMediaObserver(); |
| 1048 | mLocalVideosObserver = new LocalMediaObserver(); |
ztenghui | 064d600 | 2013-09-05 15:47:58 -0700 | [diff] [blame] | 1049 | |
| 1050 | getContentResolver().registerContentObserver( |
| 1051 | MediaStore.Images.Media.EXTERNAL_CONTENT_URI, true, |
| 1052 | mLocalImagesObserver); |
| 1053 | getContentResolver().registerContentObserver( |
| 1054 | MediaStore.Video.Media.EXTERNAL_CONTENT_URI, true, |
| 1055 | mLocalVideosObserver); |
Christian Wyglendowski | 6fe8c82 | 2013-11-26 14:16:04 -0800 | [diff] [blame] | 1056 | if (FeedbackHelper.feedbackAvailable()) { |
| 1057 | mFeedbackHelper = new FeedbackHelper(this); |
| 1058 | } |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 1059 | } |
| 1060 | |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1061 | private void setRotationAnimation() { |
Michael Kolb | 0865018 | 2013-02-25 19:43:56 -0800 | [diff] [blame] | 1062 | int rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1063 | rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE; |
Michael Kolb | 0865018 | 2013-02-25 19:43:56 -0800 | [diff] [blame] | 1064 | Window win = getWindow(); |
| 1065 | WindowManager.LayoutParams winParams = win.getAttributes(); |
| 1066 | winParams.rotationAnimation = rotationAnimation; |
| 1067 | win.setAttributes(winParams); |
| 1068 | } |
| 1069 | |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 1070 | @Override |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 1071 | public void onUserInteraction() { |
| 1072 | super.onUserInteraction(); |
Angus Kong | 13e87c4 | 2013-11-25 10:02:47 -0800 | [diff] [blame] | 1073 | if (!isFinishing()) { |
| 1074 | keepScreenOnForAWhile(); |
| 1075 | } |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 1076 | } |
| 1077 | |
| 1078 | @Override |
Doris Liu | 742cd5b | 2013-09-12 16:17:43 -0700 | [diff] [blame] | 1079 | public boolean dispatchTouchEvent(MotionEvent ev) { |
| 1080 | boolean result = super.dispatchTouchEvent(ev); |
| 1081 | if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) { |
| 1082 | // Real deletion is postponed until the next user interaction after |
| 1083 | // the gesture that triggers deletion. Until real deletion is performed, |
| 1084 | // users can click the undo button to bring back the image that they |
| 1085 | // chose to delete. |
| 1086 | if (mPendingDeletion && !mIsUndoingDeletion) { |
Angus Kong | 20fad24 | 2013-11-11 18:23:46 -0800 | [diff] [blame] | 1087 | performDeletion(); |
Doris Liu | 742cd5b | 2013-09-12 16:17:43 -0700 | [diff] [blame] | 1088 | } |
| 1089 | } |
| 1090 | return result; |
| 1091 | } |
| 1092 | |
| 1093 | @Override |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1094 | public void onPause() { |
Erin Dahlgren | c120b0f | 2013-11-19 10:53:49 -0800 | [diff] [blame] | 1095 | mPaused = true; |
| 1096 | |
Doris Liu | f2c1433 | 2013-09-26 11:24:37 -0700 | [diff] [blame] | 1097 | // Delete photos that are pending deletion |
| 1098 | performDeletion(); |
Angus Kong | c4e6656 | 2013-11-22 23:03:21 -0800 | [diff] [blame] | 1099 | mCurrentModule.pause(); |
Angus Kong | 9f1db52 | 2013-11-09 16:25:59 -0800 | [diff] [blame] | 1100 | mOrientationManager.pause(); |
Angus Kong | 20fad24 | 2013-11-11 18:23:46 -0800 | [diff] [blame] | 1101 | // Close the camera and wait for the operation done. |
| 1102 | mCameraController.closeCamera(); |
Doris Liu | 2b86d87 | 2013-09-26 15:23:41 -0700 | [diff] [blame] | 1103 | |
| 1104 | mLocalImagesObserver.setActivityPaused(true); |
| 1105 | mLocalVideosObserver.setActivityPaused(true); |
Angus Kong | 13e87c4 | 2013-11-25 10:02:47 -0800 | [diff] [blame] | 1106 | resetScreenOn(); |
Angus Kong | c4e6656 | 2013-11-22 23:03:21 -0800 | [diff] [blame] | 1107 | super.onPause(); |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1108 | } |
| 1109 | |
| 1110 | @Override |
Sascha Haeberling | b7639c6 | 2013-09-09 14:42:43 -0700 | [diff] [blame] | 1111 | protected void onActivityResult(int requestCode, int resultCode, Intent data) { |
ztenghui | 064d600 | 2013-09-05 15:47:58 -0700 | [diff] [blame] | 1112 | if (requestCode == REQ_CODE_DONT_SWITCH_TO_PREVIEW) { |
Sascha Haeberling | b7639c6 | 2013-09-09 14:42:43 -0700 | [diff] [blame] | 1113 | mResetToPreviewOnResume = false; |
| 1114 | } else { |
| 1115 | super.onActivityResult(requestCode, resultCode, data); |
| 1116 | } |
| 1117 | } |
| 1118 | |
| 1119 | @Override |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1120 | public void onResume() { |
Erin Dahlgren | c120b0f | 2013-11-19 10:53:49 -0800 | [diff] [blame] | 1121 | mPaused = false; |
| 1122 | |
Angus Kong | 53ae041 | 2013-12-01 23:21:49 -0800 | [diff] [blame] | 1123 | mLastLayoutOrientation = getResources().getConfiguration().orientation; |
| 1124 | |
Angus Kong | ce2b949 | 2013-09-05 17:49:06 -0700 | [diff] [blame] | 1125 | // TODO: Handle this in OrientationManager. |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 1126 | // Auto-rotate off |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1127 | if (Settings.System.getInt(getContentResolver(), |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 1128 | Settings.System.ACCELEROMETER_ROTATION, 0) == 0) { |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1129 | setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); |
| 1130 | mAutoRotateScreen = false; |
| 1131 | } else { |
| 1132 | setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR); |
| 1133 | mAutoRotateScreen = true; |
| 1134 | } |
Seth Raphael | cbd8267 | 2013-11-05 10:12:36 -0800 | [diff] [blame] | 1135 | |
| 1136 | UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA, |
| 1137 | UsageStatistics.ACTION_FOREGROUNDED, this.getClass().getSimpleName()); |
| 1138 | |
Angus Kong | 9f1db52 | 2013-11-09 16:25:59 -0800 | [diff] [blame] | 1139 | mOrientationManager.resume(); |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1140 | super.onResume(); |
Angus Kong | c4e6656 | 2013-11-22 23:03:21 -0800 | [diff] [blame] | 1141 | mCurrentModule.resume(); |
Angus Kong | 6798c34 | 2013-07-16 15:14:58 -0700 | [diff] [blame] | 1142 | setSwipingEnabled(true); |
Sascha Haeberling | b7639c6 | 2013-09-09 14:42:43 -0700 | [diff] [blame] | 1143 | |
| 1144 | if (mResetToPreviewOnResume) { |
Doris Liu | 2b906b8 | 2013-12-10 16:34:08 -0800 | [diff] [blame] | 1145 | mCameraAppUI.resume(); |
Sascha Haeberling | b7639c6 | 2013-09-09 14:42:43 -0700 | [diff] [blame] | 1146 | } |
Angus Kong | e4002f3 | 2013-12-13 22:24:11 -0800 | [diff] [blame] | 1147 | // The share button might be disabled to avoid double tapping. |
| 1148 | mCameraAppUI.getFilmstripBottomControls().setShareEnabled(true); |
Sascha Haeberling | b7639c6 | 2013-09-09 14:42:43 -0700 | [diff] [blame] | 1149 | // Default is showing the preview, unless disabled by explicitly |
| 1150 | // starting an activity we want to return from to the filmstrip rather |
| 1151 | // than the preview. |
| 1152 | mResetToPreviewOnResume = true; |
ztenghui | 064d600 | 2013-09-05 15:47:58 -0700 | [diff] [blame] | 1153 | |
Doris Liu | 2b86d87 | 2013-09-26 15:23:41 -0700 | [diff] [blame] | 1154 | if (mLocalVideosObserver.isMediaDataChangedDuringPause() |
| 1155 | || mLocalImagesObserver.isMediaDataChangedDuringPause()) { |
Angus Kong | 2d5c747 | 2013-10-12 23:48:46 -0700 | [diff] [blame] | 1156 | if (!mSecureCamera) { |
| 1157 | // If it's secure camera, requestLoad() should not be called |
| 1158 | // as it will load all the data. |
Angus Kong | b251025 | 2013-12-10 22:58:15 -0800 | [diff] [blame] | 1159 | if (!mFilmstripVisible) { |
Sascha Haeberling | 44c1afb | 2013-12-20 11:59:35 -0800 | [diff] [blame] | 1160 | mDataAdapter.requestLoad(); |
Angus Kong | b251025 | 2013-12-10 22:58:15 -0800 | [diff] [blame] | 1161 | } |
Angus Kong | 2d5c747 | 2013-10-12 23:48:46 -0700 | [diff] [blame] | 1162 | } |
ztenghui | 064d600 | 2013-09-05 15:47:58 -0700 | [diff] [blame] | 1163 | } |
Doris Liu | 2b86d87 | 2013-09-26 15:23:41 -0700 | [diff] [blame] | 1164 | mLocalImagesObserver.setActivityPaused(false); |
| 1165 | mLocalVideosObserver.setActivityPaused(false); |
Doris Liu | 70576b6 | 2013-11-14 20:30:33 -0800 | [diff] [blame] | 1166 | |
Angus Kong | 13e87c4 | 2013-11-25 10:02:47 -0800 | [diff] [blame] | 1167 | keepScreenOnForAWhile(); |
Angus Kong | 6798c34 | 2013-07-16 15:14:58 -0700 | [diff] [blame] | 1168 | } |
| 1169 | |
| 1170 | @Override |
| 1171 | public void onStart() { |
| 1172 | super.onStart(); |
Sascha Haeberling | f1f5186 | 2013-07-31 11:28:21 -0700 | [diff] [blame] | 1173 | mPanoramaViewHelper.onStart(); |
Kevin Gabayan | ffbc43c | 2013-12-09 11:41:50 -0800 | [diff] [blame] | 1174 | boolean recordLocation = RecordLocationPreference.get( |
| 1175 | mPreferences, mContentResolver); |
| 1176 | mLocationManager.recordLocation(recordLocation); |
Sascha Haeberling | f1f5186 | 2013-07-31 11:28:21 -0700 | [diff] [blame] | 1177 | } |
| 1178 | |
| 1179 | @Override |
| 1180 | protected void onStop() { |
Sascha Haeberling | f1f5186 | 2013-07-31 11:28:21 -0700 | [diff] [blame] | 1181 | mPanoramaViewHelper.onStop(); |
Christian Wyglendowski | 6fe8c82 | 2013-11-26 14:16:04 -0800 | [diff] [blame] | 1182 | if (mFeedbackHelper != null) { |
| 1183 | mFeedbackHelper.stopFeedback(); |
| 1184 | } |
Angus Kong | 0e57fc1 | 2013-11-18 13:21:07 -0800 | [diff] [blame] | 1185 | |
Kevin Gabayan | ffbc43c | 2013-12-09 11:41:50 -0800 | [diff] [blame] | 1186 | mLocationManager.disconnect(); |
Angus Kong | 0e57fc1 | 2013-11-18 13:21:07 -0800 | [diff] [blame] | 1187 | CameraManagerFactory.recycle(); |
| 1188 | super.onStop(); |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1189 | } |
| 1190 | |
| 1191 | @Override |
| 1192 | public void onDestroy() { |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 1193 | if (mSecureCamera) { |
| 1194 | unregisterReceiver(mScreenOffReceiver); |
| 1195 | } |
Erin Dahlgren | 1648c36 | 2014-01-06 15:06:04 -0800 | [diff] [blame] | 1196 | mSettingsManager.removeAllListeners(); |
ztenghui | 064d600 | 2013-09-05 15:47:58 -0700 | [diff] [blame] | 1197 | getContentResolver().unregisterContentObserver(mLocalImagesObserver); |
| 1198 | getContentResolver().unregisterContentObserver(mLocalVideosObserver); |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1199 | super.onDestroy(); |
| 1200 | } |
| 1201 | |
| 1202 | @Override |
| 1203 | public void onConfigurationChanged(Configuration config) { |
| 1204 | super.onConfigurationChanged(config); |
Angus Kong | 166e36f | 2013-12-03 08:54:42 -0800 | [diff] [blame] | 1205 | Log.v(TAG, "onConfigurationChanged"); |
Angus Kong | 2f0e4a3 | 2013-12-03 10:02:35 -0800 | [diff] [blame] | 1206 | if (config.orientation == Configuration.ORIENTATION_UNDEFINED) { |
| 1207 | return; |
| 1208 | } |
| 1209 | |
Angus Kong | 53ae041 | 2013-12-01 23:21:49 -0800 | [diff] [blame] | 1210 | if (mLastLayoutOrientation != config.orientation) { |
| 1211 | mLastLayoutOrientation = config.orientation; |
Angus Kong | 2f0e4a3 | 2013-12-03 10:02:35 -0800 | [diff] [blame] | 1212 | mCurrentModule.onLayoutOrientationChanged( |
| 1213 | mLastLayoutOrientation == Configuration.ORIENTATION_LANDSCAPE); |
Angus Kong | 53ae041 | 2013-12-01 23:21:49 -0800 | [diff] [blame] | 1214 | } |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1215 | } |
| 1216 | |
| 1217 | @Override |
| 1218 | public boolean onKeyDown(int keyCode, KeyEvent event) { |
Angus Kong | 8dcccb1 | 2014-01-02 16:00:49 -0800 | [diff] [blame] | 1219 | if (!mFilmstripVisible) { |
Doris Liu | dba16ae | 2013-10-03 15:31:40 -0700 | [diff] [blame] | 1220 | if (mCurrentModule.onKeyDown(keyCode, event)) { |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 1221 | return true; |
| 1222 | } |
Doris Liu | dba16ae | 2013-10-03 15:31:40 -0700 | [diff] [blame] | 1223 | // Prevent software keyboard or voice search from showing up. |
| 1224 | if (keyCode == KeyEvent.KEYCODE_SEARCH |
| 1225 | || keyCode == KeyEvent.KEYCODE_MENU) { |
| 1226 | if (event.isLongPress()) { |
| 1227 | return true; |
| 1228 | } |
| 1229 | } |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1230 | } |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1231 | |
| 1232 | return super.onKeyDown(keyCode, event); |
| 1233 | } |
| 1234 | |
| 1235 | @Override |
| 1236 | public boolean onKeyUp(int keyCode, KeyEvent event) { |
Angus Kong | 8dcccb1 | 2014-01-02 16:00:49 -0800 | [diff] [blame] | 1237 | if (!mFilmstripVisible && mCurrentModule.onKeyUp(keyCode, event)) { |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 1238 | return true; |
| 1239 | } |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1240 | return super.onKeyUp(keyCode, event); |
| 1241 | } |
| 1242 | |
Alan Newberger | 5f6b50d | 2013-08-30 15:19:48 -0700 | [diff] [blame] | 1243 | @Override |
| 1244 | public void onBackPressed() { |
Angus Kong | 166e36f | 2013-12-03 08:54:42 -0800 | [diff] [blame] | 1245 | if (!mCameraAppUI.onBackPressed()) { |
| 1246 | if (!mCurrentModule.onBackPressed()) { |
| 1247 | super.onBackPressed(); |
| 1248 | } |
Alan Newberger | 5f6b50d | 2013-08-30 15:19:48 -0700 | [diff] [blame] | 1249 | } |
| 1250 | } |
| 1251 | |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1252 | public boolean isAutoRotateScreen() { |
| 1253 | return mAutoRotateScreen; |
| 1254 | } |
| 1255 | |
| 1256 | protected void updateStorageSpace() { |
Angus Kong | 2dcc0a9 | 2013-09-25 13:00:08 -0700 | [diff] [blame] | 1257 | mStorageSpaceBytes = Storage.getAvailableSpace(); |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1258 | } |
| 1259 | |
Angus Kong | 2dcc0a9 | 2013-09-25 13:00:08 -0700 | [diff] [blame] | 1260 | protected long getStorageSpaceBytes() { |
| 1261 | return mStorageSpaceBytes; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1262 | } |
| 1263 | |
| 1264 | protected void updateStorageSpaceAndHint() { |
| 1265 | updateStorageSpace(); |
Angus Kong | 2dcc0a9 | 2013-09-25 13:00:08 -0700 | [diff] [blame] | 1266 | updateStorageHint(mStorageSpaceBytes); |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1267 | } |
| 1268 | |
| 1269 | protected void updateStorageHint(long storageSpace) { |
| 1270 | String message = null; |
| 1271 | if (storageSpace == Storage.UNAVAILABLE) { |
| 1272 | message = getString(R.string.no_storage); |
| 1273 | } else if (storageSpace == Storage.PREPARING) { |
| 1274 | message = getString(R.string.preparing_sd); |
| 1275 | } else if (storageSpace == Storage.UNKNOWN_SIZE) { |
| 1276 | message = getString(R.string.access_sd_fail); |
Angus Kong | 2dcc0a9 | 2013-09-25 13:00:08 -0700 | [diff] [blame] | 1277 | } else if (storageSpace <= Storage.LOW_STORAGE_THRESHOLD_BYTES) { |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1278 | message = getString(R.string.spaceIsLow_content); |
| 1279 | } |
| 1280 | |
| 1281 | if (message != null) { |
| 1282 | if (mStorageHint == null) { |
| 1283 | mStorageHint = OnScreenHint.makeText(this, message); |
| 1284 | } else { |
| 1285 | mStorageHint.setText(message); |
| 1286 | } |
| 1287 | mStorageHint.show(); |
| 1288 | } else if (mStorageHint != null) { |
| 1289 | mStorageHint.cancel(); |
| 1290 | mStorageHint = null; |
| 1291 | } |
| 1292 | } |
| 1293 | |
| 1294 | protected void setResultEx(int resultCode) { |
| 1295 | mResultCodeForTesting = resultCode; |
| 1296 | setResult(resultCode); |
| 1297 | } |
| 1298 | |
| 1299 | protected void setResultEx(int resultCode, Intent data) { |
| 1300 | mResultCodeForTesting = resultCode; |
| 1301 | mResultDataForTesting = data; |
| 1302 | setResult(resultCode, data); |
| 1303 | } |
| 1304 | |
| 1305 | public int getResultCode() { |
| 1306 | return mResultCodeForTesting; |
| 1307 | } |
| 1308 | |
| 1309 | public Intent getResultData() { |
| 1310 | return mResultDataForTesting; |
| 1311 | } |
| 1312 | |
| 1313 | public boolean isSecureCamera() { |
| 1314 | return mSecureCamera; |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 1315 | } |
| 1316 | |
| 1317 | @Override |
Erin Dahlgren | c120b0f | 2013-11-19 10:53:49 -0800 | [diff] [blame] | 1318 | public boolean isPaused() { |
| 1319 | return mPaused; |
| 1320 | } |
| 1321 | |
| 1322 | @Override |
| 1323 | public void onModeSelected(int modeIndex) { |
| 1324 | if (mCurrentModeIndex == modeIndex) { |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 1325 | return; |
| 1326 | } |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1327 | |
Doris Liu | f55f3c4 | 2013-11-20 00:24:46 -0800 | [diff] [blame] | 1328 | if (modeIndex == ModeListView.MODE_SETTING) { |
| 1329 | onSettingsSelected(); |
| 1330 | return; |
| 1331 | } |
| 1332 | |
Erin Dahlgren | c120b0f | 2013-11-19 10:53:49 -0800 | [diff] [blame] | 1333 | CameraHolder.instance().keep(); |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1334 | closeModule(mCurrentModule); |
Doris Liu | f55f3c4 | 2013-11-20 00:24:46 -0800 | [diff] [blame] | 1335 | int oldModuleIndex = mCurrentModeIndex; |
Erin Dahlgren | a340f07 | 2014-01-06 17:31:23 -0800 | [diff] [blame^] | 1336 | |
| 1337 | // Refocus and Gcam are modes that cannot be selected |
| 1338 | // from the mode list view, because they are not list items. |
| 1339 | // Check whether we should interpret MODULE_CRAFT as either. |
| 1340 | if (modeIndex == ModulesInfo.MODULE_CRAFT) { |
| 1341 | boolean refocusOn = mSettingsManager.isRefocusOn(); |
| 1342 | boolean hdrPlusOn = mSettingsManager.isHdrPlusOn(); |
| 1343 | if (refocusOn && hdrPlusOn) { |
| 1344 | throw new IllegalStateException("Refocus and hdr plus cannot be on together."); |
| 1345 | } |
| 1346 | if (refocusOn) { |
| 1347 | modeIndex = ModulesInfo.MODULE_REFOCUS; |
| 1348 | } else if (hdrPlusOn) { |
| 1349 | modeIndex = ModulesInfo.MODULE_GCAM; |
| 1350 | } else { |
| 1351 | // Do nothing, keep MODULE_CRAFT. |
| 1352 | } |
| 1353 | } |
| 1354 | |
Erin Dahlgren | c120b0f | 2013-11-19 10:53:49 -0800 | [diff] [blame] | 1355 | setModuleFromModeIndex(modeIndex); |
Doris Liu | f55f3c4 | 2013-11-20 00:24:46 -0800 | [diff] [blame] | 1356 | |
Erin Dahlgren | 5f500be | 2013-12-10 14:53:35 -0800 | [diff] [blame] | 1357 | // TODO: The following check is temporary for modules attached to the |
| 1358 | // generic_module layout. When the refactor is done, similar logic will |
| 1359 | // be applied to all modules. |
Doris Liu | f55f3c4 | 2013-11-20 00:24:46 -0800 | [diff] [blame] | 1360 | if (mCurrentModeIndex == ModulesInfo.MODULE_PHOTO |
Erin Dahlgren | 5f500be | 2013-12-10 14:53:35 -0800 | [diff] [blame] | 1361 | || mCurrentModeIndex == ModulesInfo.MODULE_VIDEO |
Erin Dahlgren | 79fcbe4 | 2013-12-13 15:52:30 -0800 | [diff] [blame] | 1362 | || mCurrentModeIndex == ModulesInfo.MODULE_GCAM |
Erin Dahlgren | 4efa8b5 | 2013-12-17 18:31:35 -0800 | [diff] [blame] | 1363 | || mCurrentModeIndex == ModulesInfo.MODULE_CRAFT |
| 1364 | || mCurrentModeIndex == ModulesInfo.MODULE_REFOCUS) { |
Doris Liu | f55f3c4 | 2013-11-20 00:24:46 -0800 | [diff] [blame] | 1365 | if (oldModuleIndex != ModulesInfo.MODULE_PHOTO |
Erin Dahlgren | 5f500be | 2013-12-10 14:53:35 -0800 | [diff] [blame] | 1366 | && oldModuleIndex != ModulesInfo.MODULE_VIDEO |
Erin Dahlgren | 79fcbe4 | 2013-12-13 15:52:30 -0800 | [diff] [blame] | 1367 | && oldModuleIndex != ModulesInfo.MODULE_GCAM |
Erin Dahlgren | 4efa8b5 | 2013-12-17 18:31:35 -0800 | [diff] [blame] | 1368 | && oldModuleIndex != ModulesInfo.MODULE_CRAFT |
| 1369 | && oldModuleIndex != ModulesInfo.MODULE_REFOCUS) { |
Doris Liu | f55f3c4 | 2013-11-20 00:24:46 -0800 | [diff] [blame] | 1370 | mCameraAppUI.prepareModuleUI(); |
| 1371 | } else { |
| 1372 | mCameraAppUI.clearModuleUI(); |
| 1373 | } |
| 1374 | } else { |
| 1375 | // This is the old way of removing all views in CameraRootView. Will |
| 1376 | // be deprecated soon. It is here to make sure modules that haven't |
| 1377 | // been refactored can still function. |
| 1378 | mCameraAppUI.clearCameraUI(); |
| 1379 | } |
| 1380 | |
Sascha Haeberling | 2654dd9 | 2013-08-28 15:28:57 -0700 | [diff] [blame] | 1381 | openModule(mCurrentModule); |
| 1382 | mCurrentModule.onOrientationChanged(mLastRawOrientation); |
Sascha Haeberling | 2654dd9 | 2013-08-28 15:28:57 -0700 | [diff] [blame] | 1383 | // Store the module index so we can use it the next time the Camera |
| 1384 | // starts up. |
| 1385 | SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); |
Erin Dahlgren | c120b0f | 2013-11-19 10:53:49 -0800 | [diff] [blame] | 1386 | prefs.edit().putInt(CameraSettings.KEY_STARTUP_MODULE_INDEX, modeIndex).apply(); |
| 1387 | } |
| 1388 | |
Doris Liu | f55f3c4 | 2013-11-20 00:24:46 -0800 | [diff] [blame] | 1389 | public void onSettingsSelected() { |
Erin Dahlgren | c120b0f | 2013-11-19 10:53:49 -0800 | [diff] [blame] | 1390 | // Temporary until we finalize the touch flow. |
| 1391 | LayoutInflater inflater = getLayoutInflater(); |
| 1392 | SettingsView settingsView = (SettingsView) inflater.inflate(R.layout.settings_list_layout, |
| 1393 | null, false); |
Erin Dahlgren | 357b767 | 2013-11-20 17:38:14 -0800 | [diff] [blame] | 1394 | settingsView.setSettingsListener(mSettingsController); |
Christian Wyglendowski | 6fe8c82 | 2013-11-26 14:16:04 -0800 | [diff] [blame] | 1395 | if (mFeedbackHelper != null) { |
| 1396 | settingsView.setFeedbackHelper(mFeedbackHelper); |
| 1397 | } |
Erin Dahlgren | 4bb8082 | 2013-11-27 10:42:10 -0800 | [diff] [blame] | 1398 | PopupWindow popup = new PopupWindow(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); |
Erin Dahlgren | c120b0f | 2013-11-19 10:53:49 -0800 | [diff] [blame] | 1399 | popup.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); |
| 1400 | popup.setOutsideTouchable(true); |
| 1401 | popup.setFocusable(true); |
| 1402 | popup.setContentView(settingsView); |
| 1403 | popup.showAtLocation(mModeListView.getRootView(), Gravity.CENTER, 0, 0); |
Sascha Haeberling | 2654dd9 | 2013-08-28 15:28:57 -0700 | [diff] [blame] | 1404 | } |
| 1405 | |
| 1406 | /** |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 1407 | * Sets the mCurrentModuleIndex, creates a new module instance for the given |
| 1408 | * index an sets it as mCurrentModule. |
Sascha Haeberling | 2654dd9 | 2013-08-28 15:28:57 -0700 | [diff] [blame] | 1409 | */ |
Erin Dahlgren | c120b0f | 2013-11-19 10:53:49 -0800 | [diff] [blame] | 1410 | private void setModuleFromModeIndex(int modeIndex) { |
| 1411 | ModuleManagerImpl.ModuleAgent agent = mModuleManager.getModuleAgent(modeIndex); |
Angus Kong | 20fad24 | 2013-11-11 18:23:46 -0800 | [diff] [blame] | 1412 | if (agent == null) { |
| 1413 | return; |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1414 | } |
Angus Kong | 20fad24 | 2013-11-11 18:23:46 -0800 | [diff] [blame] | 1415 | if (!agent.requestAppForCamera()) { |
| 1416 | mCameraController.closeCamera(); |
| 1417 | } |
Erin Dahlgren | c120b0f | 2013-11-19 10:53:49 -0800 | [diff] [blame] | 1418 | mCurrentModeIndex = agent.getModuleId(); |
Angus Kong | 13e87c4 | 2013-11-25 10:02:47 -0800 | [diff] [blame] | 1419 | mCurrentModule = (CameraModule) agent.createModule(this); |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 1420 | } |
| 1421 | |
Erin Dahlgren | c120b0f | 2013-11-19 10:53:49 -0800 | [diff] [blame] | 1422 | @Override |
| 1423 | public SettingsManager getSettingsManager() { |
| 1424 | return mSettingsManager; |
| 1425 | } |
| 1426 | |
Angus Kong | c4e6656 | 2013-11-22 23:03:21 -0800 | [diff] [blame] | 1427 | @Override |
| 1428 | public CameraServices getServices() { |
| 1429 | return (CameraServices) getApplication(); |
| 1430 | } |
| 1431 | |
Erin Dahlgren | 357b767 | 2013-11-20 17:38:14 -0800 | [diff] [blame] | 1432 | @Override |
| 1433 | public SettingsController getSettingsController() { |
| 1434 | return mSettingsController; |
| 1435 | } |
| 1436 | |
Erin Dahlgren | 18e2ef6 | 2013-12-05 14:53:38 -0800 | [diff] [blame] | 1437 | public ButtonManager getButtonManager() { |
Erin Dahlgren | 8a2933b | 2013-12-06 12:07:33 -0800 | [diff] [blame] | 1438 | if (mButtonManager == null) { |
| 1439 | mButtonManager = new ButtonManager(this); |
| 1440 | } |
| 1441 | return mButtonManager; |
Erin Dahlgren | 18e2ef6 | 2013-12-05 14:53:38 -0800 | [diff] [blame] | 1442 | } |
| 1443 | |
Sascha Haeberling | 88ef766 | 2013-08-15 17:19:22 -0700 | [diff] [blame] | 1444 | /** |
Erin Dahlgren | 491c628 | 2013-11-25 13:22:07 -0800 | [diff] [blame] | 1445 | * Creates an AlertDialog appropriate for choosing whether to enable location |
| 1446 | * on the first run of the app. |
| 1447 | */ |
| 1448 | public AlertDialog getFirstTimeLocationAlert() { |
| 1449 | AlertDialog.Builder builder = new AlertDialog.Builder(this); |
| 1450 | builder = SettingsView.getFirstTimeLocationAlertBuilder(builder, mSettingsController); |
| 1451 | if (builder != null) { |
| 1452 | return builder.create(); |
| 1453 | } else { |
| 1454 | return null; |
| 1455 | } |
| 1456 | } |
| 1457 | |
| 1458 | /** |
Sascha Haeberling | 88ef766 | 2013-08-15 17:19:22 -0700 | [diff] [blame] | 1459 | * Launches an ACTION_EDIT intent for the given local data item. |
| 1460 | */ |
| 1461 | public void launchEditor(LocalData data) { |
| 1462 | Intent intent = new Intent(Intent.ACTION_EDIT) |
| 1463 | .setDataAndType(data.getContentUri(), data.getMimeType()) |
| 1464 | .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); |
Erin Dahlgren | 05a0492 | 2013-11-07 11:35:10 -0800 | [diff] [blame] | 1465 | try { |
Angus Kong | 0eaf016 | 2013-12-16 15:53:30 -0800 | [diff] [blame] | 1466 | launchActivityByIntent(intent); |
Erin Dahlgren | 05a0492 | 2013-11-07 11:35:10 -0800 | [diff] [blame] | 1467 | } catch (ActivityNotFoundException e) { |
Angus Kong | 0eaf016 | 2013-12-16 15:53:30 -0800 | [diff] [blame] | 1468 | launchActivityByIntent(Intent.createChooser(intent, null)); |
Erin Dahlgren | 05a0492 | 2013-11-07 11:35:10 -0800 | [diff] [blame] | 1469 | } |
Sascha Haeberling | 88ef766 | 2013-08-15 17:19:22 -0700 | [diff] [blame] | 1470 | } |
| 1471 | |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 1472 | /** |
| 1473 | * Launch the tiny planet editor. |
| 1474 | * |
Angus Kong | 20fad24 | 2013-11-11 18:23:46 -0800 | [diff] [blame] | 1475 | * @param data The data must be a 360 degree stereographically mapped |
| 1476 | * panoramic image. It will not be modified, instead a new item |
| 1477 | * with the result will be added to the filmstrip. |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 1478 | */ |
| 1479 | public void launchTinyPlanetEditor(LocalData data) { |
| 1480 | TinyPlanetFragment fragment = new TinyPlanetFragment(); |
| 1481 | Bundle bundle = new Bundle(); |
| 1482 | bundle.putString(TinyPlanetFragment.ARGUMENT_URI, data.getContentUri().toString()); |
| 1483 | bundle.putString(TinyPlanetFragment.ARGUMENT_TITLE, data.getTitle()); |
| 1484 | fragment.setArguments(bundle); |
| 1485 | fragment.show(getFragmentManager(), "tiny_planet"); |
| 1486 | } |
| 1487 | |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1488 | private void openModule(CameraModule module) { |
Erin Dahlgren | 4efa8b5 | 2013-12-17 18:31:35 -0800 | [diff] [blame] | 1489 | // Currently not all modules use the generic_module UI. |
| 1490 | // TODO: once all modules have a bottom bar, move this |
| 1491 | // logic into the app. |
| 1492 | if (module.isUsingBottomBar()) { |
| 1493 | int color = mModeListView.getModeThemeColor(mCurrentModeIndex); |
| 1494 | mCameraAppUI.setBottomBarColor(color); |
| 1495 | } |
| 1496 | |
Angus Kong | 13e87c4 | 2013-11-25 10:02:47 -0800 | [diff] [blame] | 1497 | module.init(this, isSecureCamera(), isCaptureIntent()); |
Angus Kong | c4e6656 | 2013-11-22 23:03:21 -0800 | [diff] [blame] | 1498 | module.resume(); |
Angus Kong | faaee01 | 2013-12-07 00:38:46 -0800 | [diff] [blame] | 1499 | module.onPreviewVisibilityChanged(!mFilmstripVisible); |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1500 | } |
| 1501 | |
| 1502 | private void closeModule(CameraModule module) { |
Angus Kong | c4e6656 | 2013-11-22 23:03:21 -0800 | [diff] [blame] | 1503 | module.pause(); |
Angus Kong | 653c43b | 2013-08-21 18:28:43 -0700 | [diff] [blame] | 1504 | } |
| 1505 | |
Doris Liu | 742cd5b | 2013-09-12 16:17:43 -0700 | [diff] [blame] | 1506 | private void performDeletion() { |
| 1507 | if (!mPendingDeletion) { |
| 1508 | return; |
| 1509 | } |
| 1510 | hideUndoDeletionBar(false); |
Sascha Haeberling | 44c1afb | 2013-12-20 11:59:35 -0800 | [diff] [blame] | 1511 | mDataAdapter.executeDeletion(); |
Doris Liu | 742cd5b | 2013-09-12 16:17:43 -0700 | [diff] [blame] | 1512 | } |
| 1513 | |
| 1514 | public void showUndoDeletionBar() { |
| 1515 | if (mPendingDeletion) { |
| 1516 | performDeletion(); |
| 1517 | } |
| 1518 | Log.v(TAG, "showing undo bar"); |
| 1519 | mPendingDeletion = true; |
Angus Kong | 653c43b | 2013-08-21 18:28:43 -0700 | [diff] [blame] | 1520 | if (mUndoDeletionBar == null) { |
Angus Kong | 20fad24 | 2013-11-11 18:23:46 -0800 | [diff] [blame] | 1521 | ViewGroup v = (ViewGroup) getLayoutInflater().inflate(R.layout.undo_bar, |
| 1522 | mAboveFilmstripControlLayout, true); |
Angus Kong | 653c43b | 2013-08-21 18:28:43 -0700 | [diff] [blame] | 1523 | mUndoDeletionBar = (ViewGroup) v.findViewById(R.id.camera_undo_deletion_bar); |
| 1524 | View button = mUndoDeletionBar.findViewById(R.id.camera_undo_deletion_button); |
| 1525 | button.setOnClickListener(new View.OnClickListener() { |
| 1526 | @Override |
| 1527 | public void onClick(View view) { |
| 1528 | mDataAdapter.undoDataRemoval(); |
Doris Liu | 742cd5b | 2013-09-12 16:17:43 -0700 | [diff] [blame] | 1529 | hideUndoDeletionBar(true); |
| 1530 | } |
| 1531 | }); |
| 1532 | // Setting undo bar clickable to avoid touch events going through |
| 1533 | // the bar to the buttons (eg. edit button, etc) underneath the bar. |
| 1534 | mUndoDeletionBar.setClickable(true); |
| 1535 | // When there is user interaction going on with the undo button, we |
| 1536 | // do not want to hide the undo bar. |
| 1537 | button.setOnTouchListener(new View.OnTouchListener() { |
| 1538 | @Override |
| 1539 | public boolean onTouch(View v, MotionEvent event) { |
| 1540 | if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { |
| 1541 | mIsUndoingDeletion = true; |
| 1542 | } else if (event.getActionMasked() == MotionEvent.ACTION_UP) { |
Angus Kong | 20fad24 | 2013-11-11 18:23:46 -0800 | [diff] [blame] | 1543 | mIsUndoingDeletion = false; |
Doris Liu | 742cd5b | 2013-09-12 16:17:43 -0700 | [diff] [blame] | 1544 | } |
| 1545 | return false; |
Angus Kong | 653c43b | 2013-08-21 18:28:43 -0700 | [diff] [blame] | 1546 | } |
| 1547 | }); |
| 1548 | } |
| 1549 | mUndoDeletionBar.setAlpha(0f); |
| 1550 | mUndoDeletionBar.setVisibility(View.VISIBLE); |
Doris Liu | 742cd5b | 2013-09-12 16:17:43 -0700 | [diff] [blame] | 1551 | mUndoDeletionBar.animate().setDuration(200).alpha(1f).setListener(null).start(); |
Angus Kong | 653c43b | 2013-08-21 18:28:43 -0700 | [diff] [blame] | 1552 | } |
| 1553 | |
Doris Liu | 742cd5b | 2013-09-12 16:17:43 -0700 | [diff] [blame] | 1554 | private void hideUndoDeletionBar(boolean withAnimation) { |
Angus Kong | 653c43b | 2013-08-21 18:28:43 -0700 | [diff] [blame] | 1555 | Log.v(TAG, "Hiding undo deletion bar"); |
Doris Liu | 742cd5b | 2013-09-12 16:17:43 -0700 | [diff] [blame] | 1556 | mPendingDeletion = false; |
Angus Kong | 653c43b | 2013-08-21 18:28:43 -0700 | [diff] [blame] | 1557 | if (mUndoDeletionBar != null) { |
Doris Liu | 742cd5b | 2013-09-12 16:17:43 -0700 | [diff] [blame] | 1558 | if (withAnimation) { |
Angus Kong | 20fad24 | 2013-11-11 18:23:46 -0800 | [diff] [blame] | 1559 | mUndoDeletionBar.animate().setDuration(200).alpha(0f) |
Doris Liu | 742cd5b | 2013-09-12 16:17:43 -0700 | [diff] [blame] | 1560 | .setListener(new Animator.AnimatorListener() { |
| 1561 | @Override |
| 1562 | public void onAnimationStart(Animator animation) { |
| 1563 | // Do nothing. |
| 1564 | } |
| 1565 | |
| 1566 | @Override |
| 1567 | public void onAnimationEnd(Animator animation) { |
| 1568 | mUndoDeletionBar.setVisibility(View.GONE); |
| 1569 | } |
| 1570 | |
| 1571 | @Override |
| 1572 | public void onAnimationCancel(Animator animation) { |
| 1573 | // Do nothing. |
| 1574 | } |
| 1575 | |
| 1576 | @Override |
| 1577 | public void onAnimationRepeat(Animator animation) { |
| 1578 | // Do nothing. |
| 1579 | } |
Angus Kong | 20fad24 | 2013-11-11 18:23:46 -0800 | [diff] [blame] | 1580 | }).start(); |
Doris Liu | 742cd5b | 2013-09-12 16:17:43 -0700 | [diff] [blame] | 1581 | } else { |
| 1582 | mUndoDeletionBar.setVisibility(View.GONE); |
| 1583 | } |
Angus Kong | 653c43b | 2013-08-21 18:28:43 -0700 | [diff] [blame] | 1584 | } |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 1585 | } |
| 1586 | |
| 1587 | @Override |
Angus Kong | 9f1db52 | 2013-11-09 16:25:59 -0800 | [diff] [blame] | 1588 | public void onOrientationChanged(int orientation) { |
| 1589 | // We keep the last known orientation. So if the user first orient |
| 1590 | // the camera then point the camera to floor or sky, we still have |
| 1591 | // the correct orientation. |
| 1592 | if (orientation == OrientationManager.ORIENTATION_UNKNOWN) { |
| 1593 | return; |
| 1594 | } |
| 1595 | mLastRawOrientation = orientation; |
| 1596 | if (mCurrentModule != null) { |
| 1597 | mCurrentModule.onOrientationChanged(orientation); |
| 1598 | } |
| 1599 | } |
| 1600 | |
Angus Kong | a719460 | 2013-09-06 17:20:15 -0700 | [diff] [blame] | 1601 | /** |
Sascha Haeberling | a5a08d7 | 2013-09-11 20:30:52 -0700 | [diff] [blame] | 1602 | * Enable/disable swipe-to-filmstrip. Will always disable swipe if in |
| 1603 | * capture intent. |
Angus Kong | a719460 | 2013-09-06 17:20:15 -0700 | [diff] [blame] | 1604 | * |
| 1605 | * @param enable {@code true} to enable swipe. |
| 1606 | */ |
Doris Liu | 6432cd6 | 2013-06-13 17:20:31 -0700 | [diff] [blame] | 1607 | public void setSwipingEnabled(boolean enable) { |
Angus Kong | 166e36f | 2013-12-03 08:54:42 -0800 | [diff] [blame] | 1608 | // TODO: Bring back the functionality. |
Angus Kong | a719460 | 2013-09-06 17:20:15 -0700 | [diff] [blame] | 1609 | if (isCaptureIntent()) { |
Angus Kong | 166e36f | 2013-12-03 08:54:42 -0800 | [diff] [blame] | 1610 | //lockPreview(true); |
Angus Kong | a719460 | 2013-09-06 17:20:15 -0700 | [diff] [blame] | 1611 | } else { |
Angus Kong | 166e36f | 2013-12-03 08:54:42 -0800 | [diff] [blame] | 1612 | //lockPreview(!enable); |
Angus Kong | a719460 | 2013-09-06 17:20:15 -0700 | [diff] [blame] | 1613 | } |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 1614 | } |
| 1615 | |
| 1616 | // Accessor methods for getting latency times used in performance testing |
| 1617 | public long getAutoFocusTime() { |
| 1618 | return (mCurrentModule instanceof PhotoModule) ? |
| 1619 | ((PhotoModule) mCurrentModule).mAutoFocusTime : -1; |
| 1620 | } |
| 1621 | |
| 1622 | public long getShutterLag() { |
| 1623 | return (mCurrentModule instanceof PhotoModule) ? |
| 1624 | ((PhotoModule) mCurrentModule).mShutterLag : -1; |
| 1625 | } |
| 1626 | |
| 1627 | public long getShutterToPictureDisplayedTime() { |
| 1628 | return (mCurrentModule instanceof PhotoModule) ? |
| 1629 | ((PhotoModule) mCurrentModule).mShutterToPictureDisplayedTime : -1; |
| 1630 | } |
| 1631 | |
| 1632 | public long getPictureDisplayedToJpegCallbackTime() { |
| 1633 | return (mCurrentModule instanceof PhotoModule) ? |
| 1634 | ((PhotoModule) mCurrentModule).mPictureDisplayedToJpegCallbackTime : -1; |
| 1635 | } |
| 1636 | |
| 1637 | public long getJpegCallbackFinishTime() { |
| 1638 | return (mCurrentModule instanceof PhotoModule) ? |
| 1639 | ((PhotoModule) mCurrentModule).mJpegCallbackFinishTime : -1; |
| 1640 | } |
| 1641 | |
| 1642 | public long getCaptureStartTime() { |
| 1643 | return (mCurrentModule instanceof PhotoModule) ? |
| 1644 | ((PhotoModule) mCurrentModule).mCaptureStartTime : -1; |
| 1645 | } |
| 1646 | |
| 1647 | public boolean isRecording() { |
| 1648 | return (mCurrentModule instanceof VideoModule) ? |
| 1649 | ((VideoModule) mCurrentModule).isRecording() : false; |
| 1650 | } |
Angus Kong | 4f795b8 | 2013-09-16 14:25:35 -0700 | [diff] [blame] | 1651 | |
Angus Kong | 6284815 | 2013-11-08 17:25:29 -0800 | [diff] [blame] | 1652 | public CameraManager.CameraOpenCallback getCameraOpenErrorCallback() { |
Angus Kong | 20fad24 | 2013-11-11 18:23:46 -0800 | [diff] [blame] | 1653 | return mCameraController; |
Angus Kong | 4f795b8 | 2013-09-16 14:25:35 -0700 | [diff] [blame] | 1654 | } |
Ruben Brunk | d217ed0 | 2013-10-08 23:31:13 -0700 | [diff] [blame] | 1655 | |
| 1656 | // For debugging purposes only. |
| 1657 | public CameraModule getCurrentModule() { |
| 1658 | return mCurrentModule; |
| 1659 | } |
Angus Kong | 13e87c4 | 2013-11-25 10:02:47 -0800 | [diff] [blame] | 1660 | |
| 1661 | private void keepScreenOnForAWhile() { |
| 1662 | if (mKeepScreenOn) { |
| 1663 | return; |
| 1664 | } |
| 1665 | mMainHandler.removeMessages(MSG_CLEAR_SCREEN_ON_FLAG); |
| 1666 | getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); |
| 1667 | mMainHandler.sendEmptyMessageDelayed(MSG_CLEAR_SCREEN_ON_FLAG, SCREEN_DELAY_MS); |
| 1668 | } |
| 1669 | |
| 1670 | private void resetScreenOn() { |
| 1671 | mKeepScreenOn = false; |
| 1672 | mMainHandler.removeMessages(MSG_CLEAR_SCREEN_ON_FLAG); |
| 1673 | getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); |
| 1674 | } |
Angus Kong | b251025 | 2013-12-10 22:58:15 -0800 | [diff] [blame] | 1675 | |
Angus Kong | d3de171 | 2013-12-12 22:01:12 -0800 | [diff] [blame] | 1676 | private void startGallery() { |
| 1677 | try { |
| 1678 | UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA, |
| 1679 | UsageStatistics.ACTION_GALLERY, null); |
Angus Kong | 0eaf016 | 2013-12-16 15:53:30 -0800 | [diff] [blame] | 1680 | launchActivityByIntent(IntentHelper.getGalleryIntent(CameraActivity.this)); |
Angus Kong | d3de171 | 2013-12-12 22:01:12 -0800 | [diff] [blame] | 1681 | } catch (ActivityNotFoundException e) { |
| 1682 | Log.w(TAG, "Failed to launch gallery activity, closing"); |
| 1683 | } |
| 1684 | } |
| 1685 | |
Angus Kong | 662fbf4 | 2013-12-12 13:22:03 -0800 | [diff] [blame] | 1686 | private void setNfcBeamPushUriFromData(LocalData data) { |
| 1687 | final Uri uri = data.getContentUri(); |
| 1688 | if (uri != Uri.EMPTY) { |
| 1689 | mNfcPushUris[0] = uri; |
| 1690 | } else { |
| 1691 | mNfcPushUris[0] = null; |
| 1692 | } |
| 1693 | } |
| 1694 | |
Angus Kong | b251025 | 2013-12-10 22:58:15 -0800 | [diff] [blame] | 1695 | /** |
| 1696 | * Updates the visibility of the filmstrip bottom controls. |
| 1697 | */ |
| 1698 | private void updateUiByData(final int dataId) { |
| 1699 | if (isSecureCamera()) { |
| 1700 | // We cannot show buttons in secure camera since go to other |
| 1701 | // activities might create a security hole. |
| 1702 | return; |
| 1703 | } |
| 1704 | |
| 1705 | final LocalData currentData = mDataAdapter.getLocalData(dataId); |
| 1706 | if (currentData == null) { |
| 1707 | Log.w(TAG, "Current data ID not found."); |
Sascha Haeberling | a63dbb6 | 2013-11-22 11:55:32 -0800 | [diff] [blame] | 1708 | hideSessionProgress(); |
Angus Kong | b251025 | 2013-12-10 22:58:15 -0800 | [diff] [blame] | 1709 | return; |
| 1710 | } |
| 1711 | |
Angus Kong | 662fbf4 | 2013-12-12 13:22:03 -0800 | [diff] [blame] | 1712 | setNfcBeamPushUriFromData(currentData); |
| 1713 | |
Angus Kong | b251025 | 2013-12-10 22:58:15 -0800 | [diff] [blame] | 1714 | /* Bottom controls. */ |
| 1715 | |
Angus Kong | e2f4c03 | 2013-12-19 10:24:33 -0800 | [diff] [blame] | 1716 | updateBottomControlsByData(currentData); |
| 1717 | if (!mDataAdapter.isMetadataUpdated(dataId)) { |
Sascha Haeberling | 44c1afb | 2013-12-20 11:59:35 -0800 | [diff] [blame] | 1718 | mDataAdapter.updateMetadata(dataId); |
Angus Kong | e2f4c03 | 2013-12-19 10:24:33 -0800 | [diff] [blame] | 1719 | } |
| 1720 | } |
| 1721 | |
| 1722 | /** |
| 1723 | * Updates the bottom controls based on the data. |
| 1724 | */ |
| 1725 | private void updateBottomControlsByData(final LocalData currentData) { |
| 1726 | |
Angus Kong | b251025 | 2013-12-10 22:58:15 -0800 | [diff] [blame] | 1727 | final CameraAppUI.BottomControls filmstripBottomControls = |
| 1728 | mCameraAppUI.getFilmstripBottomControls(); |
Angus Kong | 740cbee | 2013-12-11 15:46:16 -0800 | [diff] [blame] | 1729 | filmstripBottomControls.setEditButtonVisibility( |
| 1730 | currentData.isDataActionSupported(LocalData.DATA_ACTION_EDIT)); |
Angus Kong | e0aff89 | 2013-12-11 20:51:01 -0800 | [diff] [blame] | 1731 | filmstripBottomControls.setShareButtonVisibility( |
| 1732 | currentData.isDataActionSupported(LocalData.DATA_ACTION_SHARE)); |
| 1733 | filmstripBottomControls.setDeleteButtonVisibility( |
| 1734 | currentData.isDataActionSupported(LocalData.DATA_ACTION_DELETE)); |
Angus Kong | b251025 | 2013-12-10 22:58:15 -0800 | [diff] [blame] | 1735 | |
| 1736 | /* Progress bar */ |
| 1737 | |
Sascha Haeberling | a63dbb6 | 2013-11-22 11:55:32 -0800 | [diff] [blame] | 1738 | Uri contentUri = currentData.getContentUri(); |
| 1739 | CaptureSessionManager sessionManager = getServices() |
| 1740 | .getCaptureSessionManager(); |
| 1741 | int sessionProgress = sessionManager.getSessionProgress(contentUri); |
| 1742 | |
| 1743 | if (sessionProgress < 0) { |
| 1744 | hideSessionProgress(); |
Angus Kong | b251025 | 2013-12-10 22:58:15 -0800 | [diff] [blame] | 1745 | } else { |
Sascha Haeberling | a63dbb6 | 2013-11-22 11:55:32 -0800 | [diff] [blame] | 1746 | CharSequence progressMessage = sessionManager |
| 1747 | .getSessionProgressMessage(contentUri); |
| 1748 | showSessionProgress(progressMessage); |
| 1749 | updateSessionProgress(sessionProgress); |
Angus Kong | b251025 | 2013-12-10 22:58:15 -0800 | [diff] [blame] | 1750 | } |
| 1751 | |
| 1752 | /* View button */ |
| 1753 | |
| 1754 | // We need to add this to a separate DB. |
Angus Kong | 8a2350a | 2013-12-16 15:02:34 -0800 | [diff] [blame] | 1755 | final int viewButtonVisibility; |
| 1756 | if (PanoramaMetadataLoader.isPanorama(currentData)) { |
| 1757 | viewButtonVisibility = CameraAppUI.BottomControls.VIEW_PHOTO_SPHERE; |
| 1758 | } else if (RgbzMetadataLoader.hasRGBZData(currentData)) { |
| 1759 | viewButtonVisibility = CameraAppUI.BottomControls.VIEW_RGBZ; |
| 1760 | } else { |
| 1761 | viewButtonVisibility = CameraAppUI.BottomControls.VIEW_NONE; |
| 1762 | } |
Angus Kong | b251025 | 2013-12-10 22:58:15 -0800 | [diff] [blame] | 1763 | |
Angus Kong | 8a2350a | 2013-12-16 15:02:34 -0800 | [diff] [blame] | 1764 | filmstripBottomControls.setTinyPlanetButtonVisibility( |
| 1765 | PanoramaMetadataLoader.isPanorama360(currentData)); |
| 1766 | filmstripBottomControls.setViewButtonVisibility(viewButtonVisibility); |
Angus Kong | b251025 | 2013-12-10 22:58:15 -0800 | [diff] [blame] | 1767 | } |
Michael Kolb | 8872c23 | 2013-01-29 10:33:22 -0800 | [diff] [blame] | 1768 | } |