Steve McKay | d0a2a2c | 2015-03-25 14:35:33 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2015 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 | |
Steve McKay | b6006b2 | 2016-09-29 09:23:45 -0700 | [diff] [blame] | 17 | package com.android.documentsui.files; |
Steve McKay | d0a2a2c | 2015-03-25 14:35:33 -0700 | [diff] [blame] | 18 | |
Steve McKay | df5add4 | 2016-01-28 12:02:57 -0800 | [diff] [blame] | 19 | import static com.android.documentsui.OperationDialogFragment.DIALOG_TYPE_UNKNOWN; |
Steve McKay | 7ef09a2 | 2015-05-06 12:16:40 -0700 | [diff] [blame] | 20 | |
Steve McKay | 7295c48 | 2017-03-15 17:51:32 -0700 | [diff] [blame] | 21 | import android.app.ActivityManager.TaskDescription; |
Steve McKay | d0a2a2c | 2015-03-25 14:35:33 -0700 | [diff] [blame] | 22 | import android.content.Intent; |
Tony Huang | f7b05c4 | 2019-05-02 16:51:01 +0800 | [diff] [blame] | 23 | import android.graphics.Color; |
Steve McKay | d0a2a2c | 2015-03-25 14:35:33 -0700 | [diff] [blame] | 24 | import android.net.Uri; |
Steve McKay | d0a2a2c | 2015-03-25 14:35:33 -0700 | [diff] [blame] | 25 | import android.os.Bundle; |
Steve McKay | 0599a44 | 2015-05-05 14:50:00 -0700 | [diff] [blame] | 26 | import android.view.KeyEvent; |
Ben Lin | a867323 | 2016-09-28 15:40:04 -0700 | [diff] [blame] | 27 | import android.view.KeyboardShortcutGroup; |
Steve McKay | d0a2a2c | 2015-03-25 14:35:33 -0700 | [diff] [blame] | 28 | import android.view.Menu; |
| 29 | import android.view.MenuItem; |
Tony Huang | f7b05c4 | 2019-05-02 16:51:01 +0800 | [diff] [blame] | 30 | import android.view.View; |
Steve McKay | d0a2a2c | 2015-03-25 14:35:33 -0700 | [diff] [blame] | 31 | |
Sunny Goyal | 5b22553 | 2018-07-03 12:44:03 -0700 | [diff] [blame] | 32 | import androidx.annotation.CallSuper; |
Tony Huang | 8d8d92f | 2018-09-13 14:41:16 +0800 | [diff] [blame] | 33 | import androidx.fragment.app.FragmentManager; |
Sunny Goyal | 5b22553 | 2018-07-03 12:44:03 -0700 | [diff] [blame] | 34 | |
Tony Huang | cf74715 | 2019-11-18 13:43:41 +0800 | [diff] [blame] | 35 | import com.android.documentsui.AbstractActionHandler; |
Steve McKay | bd9f05a | 2016-10-10 10:18:36 -0700 | [diff] [blame] | 36 | import com.android.documentsui.ActionModeController; |
Steve McKay | 16e0c1f | 2016-09-15 12:41:13 -0700 | [diff] [blame] | 37 | import com.android.documentsui.BaseActivity; |
Steve McKay | 365e3cb | 2017-08-31 10:27:08 -0700 | [diff] [blame] | 38 | import com.android.documentsui.DocsSelectionHelper; |
Steve McKay | 16e0c1f | 2016-09-15 12:41:13 -0700 | [diff] [blame] | 39 | import com.android.documentsui.DocumentsApplication; |
Ben Lin | 75b7b90 | 2016-11-02 15:59:29 -0700 | [diff] [blame] | 40 | import com.android.documentsui.FocusManager; |
Steve McKay | 92ae43d | 2016-11-08 12:06:58 -0800 | [diff] [blame] | 41 | import com.android.documentsui.Injector; |
Ben Lin | 7c35b03 | 2016-05-31 13:24:01 -0700 | [diff] [blame] | 42 | import com.android.documentsui.MenuManager.DirectoryDetails; |
Steve McKay | 16e0c1f | 2016-09-15 12:41:13 -0700 | [diff] [blame] | 43 | import com.android.documentsui.OperationDialogFragment; |
Steve McKay | df5add4 | 2016-01-28 12:02:57 -0800 | [diff] [blame] | 44 | import com.android.documentsui.OperationDialogFragment.DialogType; |
Garfield Tan | 239ab97 | 2016-09-16 13:33:48 -0700 | [diff] [blame] | 45 | import com.android.documentsui.ProviderExecutor; |
| 46 | import com.android.documentsui.R; |
Steve McKay | 0471826 | 2016-11-08 11:01:35 -0800 | [diff] [blame] | 47 | import com.android.documentsui.SharedInputHandler; |
Steve McKay | 052985f | 2017-06-07 11:30:46 -0700 | [diff] [blame] | 48 | import com.android.documentsui.ShortcutsUpdater; |
Steve McKay | d080506 | 2016-09-15 14:30:38 -0700 | [diff] [blame] | 49 | import com.android.documentsui.base.DocumentInfo; |
Steve McKay | 98f8c5f | 2017-03-03 13:52:14 -0800 | [diff] [blame] | 50 | import com.android.documentsui.base.Features; |
Steve McKay | d080506 | 2016-09-15 14:30:38 -0700 | [diff] [blame] | 51 | import com.android.documentsui.base.RootInfo; |
Steve McKay | d9caa6a | 2016-09-15 16:36:45 -0700 | [diff] [blame] | 52 | import com.android.documentsui.base.State; |
Garfield, Tan | 9666ce6 | 2016-07-12 11:02:09 -0700 | [diff] [blame] | 53 | import com.android.documentsui.clipping.DocumentClipper; |
Steve McKay | 988d8a3 | 2016-09-27 09:41:17 -0700 | [diff] [blame] | 54 | import com.android.documentsui.dirlist.AnimationView.AnimationType; |
Tony Huang | e092d2d | 2018-12-26 19:02:51 +0800 | [diff] [blame] | 55 | import com.android.documentsui.dirlist.AppsRowManager; |
Steve McKay | f68210e | 2015-11-03 15:23:16 -0800 | [diff] [blame] | 56 | import com.android.documentsui.dirlist.DirectoryFragment; |
Ben Lin | 30b0dc1 | 2017-03-07 15:37:16 -0800 | [diff] [blame] | 57 | import com.android.documentsui.prefs.ScopedPreferences; |
Steve McKay | c83baa0 | 2016-01-06 18:32:13 -0800 | [diff] [blame] | 58 | import com.android.documentsui.services.FileOperationService; |
Steve McKay | d080506 | 2016-09-15 14:30:38 -0700 | [diff] [blame] | 59 | import com.android.documentsui.sidebar.RootsFragment; |
Steve McKay | c8889af | 2016-09-23 11:22:41 -0700 | [diff] [blame] | 60 | import com.android.documentsui.ui.DialogController; |
Steve McKay | 92ae43d | 2016-11-08 12:06:58 -0800 | [diff] [blame] | 61 | import com.android.documentsui.ui.MessageBuilder; |
Steve McKay | d0a2a2c | 2015-03-25 14:35:33 -0700 | [diff] [blame] | 62 | |
Tomasz Mikolajewski | 332d819 | 2015-04-13 19:38:43 +0900 | [diff] [blame] | 63 | import java.util.ArrayList; |
Steve McKay | d0a2a2c | 2015-03-25 14:35:33 -0700 | [diff] [blame] | 64 | import java.util.List; |
Steve McKay | d0a2a2c | 2015-03-25 14:35:33 -0700 | [diff] [blame] | 65 | |
Steve McKay | b68dd22 | 2015-04-20 17:18:15 -0700 | [diff] [blame] | 66 | /** |
Steve McKay | 64ac251 | 2015-05-12 12:49:58 -0700 | [diff] [blame] | 67 | * Standalone file management activity. |
Steve McKay | b68dd22 | 2015-04-20 17:18:15 -0700 | [diff] [blame] | 68 | */ |
Tony Huang | cf74715 | 2019-11-18 13:43:41 +0800 | [diff] [blame] | 69 | public class FilesActivity extends BaseActivity implements AbstractActionHandler.CommonAddons { |
Steve McKay | edc65bb | 2015-07-31 14:35:22 -0700 | [diff] [blame] | 70 | |
Steve McKay | 6525a19 | 2016-10-18 14:28:00 -0700 | [diff] [blame] | 71 | private static final String TAG = "FilesActivity"; |
Steve McKay | 92ae43d | 2016-11-08 12:06:58 -0800 | [diff] [blame] | 72 | static final String PREFERENCES_SCOPE = "files"; |
Steve McKay | d0a2a2c | 2015-03-25 14:35:33 -0700 | [diff] [blame] | 73 | |
Steve McKay | 92ae43d | 2016-11-08 12:06:58 -0800 | [diff] [blame] | 74 | private Injector<ActionHandler<FilesActivity>> mInjector; |
Ben Lin | 79ae3a7 | 2016-10-13 10:57:45 -0700 | [diff] [blame] | 75 | private ActivityInputHandler mActivityInputHandler; |
Steve McKay | 0471826 | 2016-11-08 11:01:35 -0800 | [diff] [blame] | 76 | private SharedInputHandler mSharedInputHandler; |
Steve McKay | b68dd22 | 2015-04-20 17:18:15 -0700 | [diff] [blame] | 77 | |
Steve McKay | b6006b2 | 2016-09-29 09:23:45 -0700 | [diff] [blame] | 78 | public FilesActivity() { |
Steve McKay | 0fbfc65 | 2015-08-20 16:48:49 -0700 | [diff] [blame] | 79 | super(R.layout.files_activity, TAG); |
Steve McKay | b68dd22 | 2015-04-20 17:18:15 -0700 | [diff] [blame] | 80 | } |
Steve McKay | d0a2a2c | 2015-03-25 14:35:33 -0700 | [diff] [blame] | 81 | |
Tobias Thierer | e3830da | 2017-07-14 12:51:34 +0100 | [diff] [blame] | 82 | // make these methods visible in this package to work around compiler bug http://b/62218600 |
| 83 | @Override protected boolean focusSidebar() { return super.focusSidebar(); } |
| 84 | @Override protected boolean popDir() { return super.popDir(); } |
| 85 | |
Steve McKay | d0a2a2c | 2015-03-25 14:35:33 -0700 | [diff] [blame] | 86 | @Override |
| 87 | public void onCreate(Bundle icicle) { |
Steve McKay | 6525a19 | 2016-10-18 14:28:00 -0700 | [diff] [blame] | 88 | |
Steve McKay | 92ae43d | 2016-11-08 12:06:58 -0800 | [diff] [blame] | 89 | MessageBuilder messages = new MessageBuilder(this); |
Steve McKay | 5bd5cb4 | 2017-04-02 08:36:50 -0700 | [diff] [blame] | 90 | Features features = Features.create(this); |
Steve McKay | 0ce04b7 | 2017-06-05 13:23:54 -0700 | [diff] [blame] | 91 | ScopedPreferences prefs = ScopedPreferences.create(this, PREFERENCES_SCOPE); |
| 92 | |
Steve McKay | 92ae43d | 2016-11-08 12:06:58 -0800 | [diff] [blame] | 93 | mInjector = new Injector<>( |
Tomasz Mikolajewski | 0d83d32 | 2017-02-07 12:29:39 +0900 | [diff] [blame] | 94 | features, |
Steve McKay | 92ae43d | 2016-11-08 12:06:58 -0800 | [diff] [blame] | 95 | new Config(), |
| 96 | ScopedPreferences.create(this, PREFERENCES_SCOPE), |
| 97 | messages, |
shawnlin | 8dafe61 | 2019-08-14 20:10:18 +0800 | [diff] [blame] | 98 | DialogController.create(features, this), |
Steve McKay | 0ce04b7 | 2017-06-05 13:23:54 -0700 | [diff] [blame] | 99 | DocumentsApplication.getFileTypeLookup(this), |
| 100 | new ShortcutsUpdater(this, prefs)::update); |
Steve McKay | 6525a19 | 2016-10-18 14:28:00 -0700 | [diff] [blame] | 101 | |
Steve McKay | d0a2a2c | 2015-03-25 14:35:33 -0700 | [diff] [blame] | 102 | super.onCreate(icicle); |
| 103 | |
Steve McKay | 92ae43d | 2016-11-08 12:06:58 -0800 | [diff] [blame] | 104 | DocumentClipper clipper = DocumentsApplication.getDocumentClipper(this); |
Riddle Hsu | 0c37598 | 2018-06-21 22:06:43 +0800 | [diff] [blame] | 105 | mInjector.selectionMgr = DocsSelectionHelper.create(); |
Steve McKay | 0471826 | 2016-11-08 11:01:35 -0800 | [diff] [blame] | 106 | |
Steve McKay | 92ae43d | 2016-11-08 12:06:58 -0800 | [diff] [blame] | 107 | mInjector.focusManager = new FocusManager( |
Steve McKay | 98f8c5f | 2017-03-03 13:52:14 -0800 | [diff] [blame] | 108 | mInjector.features, |
Ben Lin | 340ab17 | 2017-01-27 11:41:26 -0800 | [diff] [blame] | 109 | mInjector.selectionMgr, |
| 110 | mDrawer, |
| 111 | this::focusSidebar, |
Tony Huang | 09571b2 | 2019-03-14 14:47:53 +0800 | [diff] [blame] | 112 | getColor(R.color.primary)); |
Steve McKay | 0471826 | 2016-11-08 11:01:35 -0800 | [diff] [blame] | 113 | |
Steve McKay | 92ae43d | 2016-11-08 12:06:58 -0800 | [diff] [blame] | 114 | mInjector.menuManager = new MenuManager( |
Steve McKay | 710248d | 2017-03-14 10:09:30 -0700 | [diff] [blame] | 115 | mInjector.features, |
Steve McKay | e5d6ca2 | 2016-09-19 20:27:24 -0700 | [diff] [blame] | 116 | mSearchManager, |
| 117 | mState, |
| 118 | new DirectoryDetails(this) { |
| 119 | @Override |
| 120 | public boolean hasItemsToPaste() { |
Steve McKay | 92ae43d | 2016-11-08 12:06:58 -0800 | [diff] [blame] | 121 | return clipper.hasItemsToPaste(); |
Steve McKay | e5d6ca2 | 2016-09-19 20:27:24 -0700 | [diff] [blame] | 122 | } |
Jon Mann | 253a992 | 2017-03-21 18:53:27 -0700 | [diff] [blame] | 123 | }, |
| 124 | getApplicationContext(), |
| 125 | mInjector.selectionMgr, |
Jon Mann | 9bd4099 | 2017-03-24 12:34:34 -0700 | [diff] [blame] | 126 | mProviders::getApplicationName, |
Tony Huang | 76c6c9d | 2019-08-12 18:04:06 +0800 | [diff] [blame] | 127 | mInjector.getModel()::getItemUri, |
| 128 | mInjector.getModel()::getItemCount); |
Steve McKay | bd9f05a | 2016-10-10 10:18:36 -0700 | [diff] [blame] | 129 | |
Steve McKay | 92ae43d | 2016-11-08 12:06:58 -0800 | [diff] [blame] | 130 | mInjector.actionModeController = new ActionModeController( |
Steve McKay | bd9f05a | 2016-10-10 10:18:36 -0700 | [diff] [blame] | 131 | this, |
Steve McKay | 92ae43d | 2016-11-08 12:06:58 -0800 | [diff] [blame] | 132 | mInjector.selectionMgr, |
| 133 | mInjector.menuManager, |
| 134 | mInjector.messages); |
Steve McKay | bd9f05a | 2016-10-10 10:18:36 -0700 | [diff] [blame] | 135 | |
Steve McKay | 92ae43d | 2016-11-08 12:06:58 -0800 | [diff] [blame] | 136 | mInjector.actions = new ActionHandler<>( |
Steve McKay | c8889af | 2016-09-23 11:22:41 -0700 | [diff] [blame] | 137 | this, |
Steve McKay | c8889af | 2016-09-23 11:22:41 -0700 | [diff] [blame] | 138 | mState, |
Jon Mann | 9bd4099 | 2017-03-24 12:34:34 -0700 | [diff] [blame] | 139 | mProviders, |
Garfield Tan | 63bf813 | 2016-10-11 11:00:49 -0700 | [diff] [blame] | 140 | mDocs, |
Garfield Tan | 63bf813 | 2016-10-11 11:00:49 -0700 | [diff] [blame] | 141 | mSearchManager, |
Steve McKay | 988d8a3 | 2016-09-27 09:41:17 -0700 | [diff] [blame] | 142 | ProviderExecutor::forAuthority, |
Steve McKay | 92ae43d | 2016-11-08 12:06:58 -0800 | [diff] [blame] | 143 | mInjector.actionModeController, |
Steve McKay | 92ae43d | 2016-11-08 12:06:58 -0800 | [diff] [blame] | 144 | clipper, |
Jon Mann | 30d8c79 | 2017-02-21 17:44:49 -0800 | [diff] [blame] | 145 | DocumentsApplication.getClipStore(this), |
Garfield Tan | da2c0f0 | 2017-04-11 13:47:58 -0700 | [diff] [blame] | 146 | DocumentsApplication.getDragAndDropManager(this), |
Jon Mann | 30d8c79 | 2017-02-21 17:44:49 -0800 | [diff] [blame] | 147 | mInjector); |
Steve McKay | 1f19948 | 2015-05-20 15:58:42 -0700 | [diff] [blame] | 148 | |
Garfield Tan | e967033 | 2017-03-06 18:33:23 -0800 | [diff] [blame] | 149 | mInjector.searchManager = mSearchManager; |
| 150 | |
Tony Huang | e092d2d | 2018-12-26 19:02:51 +0800 | [diff] [blame] | 151 | mAppsRowManager = new AppsRowManager(mInjector.actions); |
| 152 | mInjector.appsRowManager = mAppsRowManager; |
| 153 | |
Steve McKay | 92ae43d | 2016-11-08 12:06:58 -0800 | [diff] [blame] | 154 | mActivityInputHandler = |
shawnlin | 8dafe61 | 2019-08-14 20:10:18 +0800 | [diff] [blame] | 155 | new ActivityInputHandler(mInjector.actions::showDeleteDialog); |
Steve McKay | 98f8c5f | 2017-03-03 13:52:14 -0800 | [diff] [blame] | 156 | mSharedInputHandler = |
Ben Lin | 0902f07 | 2017-03-13 18:25:29 -0700 | [diff] [blame] | 157 | new SharedInputHandler( |
| 158 | mInjector.focusManager, |
| 159 | mInjector.selectionMgr, |
| 160 | mInjector.searchManager::cancelSearch, |
| 161 | this::popDir, |
Rhed Jao | 23c4bc0 | 2018-05-18 16:24:04 +0800 | [diff] [blame] | 162 | mInjector.features, |
Bill Lin | 35bfbef | 2019-08-05 16:09:53 +0800 | [diff] [blame] | 163 | mDrawer, |
| 164 | mInjector.searchManager::onSearchBarClicked); |
Ben Lin | 79ae3a7 | 2016-10-13 10:57:45 -0700 | [diff] [blame] | 165 | |
Tony Huang | 8d8d92f | 2018-09-13 14:41:16 +0800 | [diff] [blame] | 166 | RootsFragment.show(getSupportFragmentManager(), null); |
Steve McKay | 459bc2b | 2015-09-16 15:07:31 -0700 | [diff] [blame] | 167 | |
Tomasz Mikolajewski | cdbbbe0 | 2015-12-25 17:06:52 +0900 | [diff] [blame] | 168 | final Intent intent = getIntent(); |
Steve McKay | 4d0255f | 2015-09-25 16:02:56 -0700 | [diff] [blame] | 169 | |
Steve McKay | 92ae43d | 2016-11-08 12:06:58 -0800 | [diff] [blame] | 170 | mInjector.actions.initLocation(intent); |
Steve McKay | 7295c48 | 2017-03-15 17:51:32 -0700 | [diff] [blame] | 171 | |
| 172 | // Allow the activity to masquerade as another, so we can look both like |
| 173 | // Downloads and Files, but with only a single underlying activity. |
| 174 | if (intent.hasExtra(LauncherActivity.TASK_LABEL_RES) |
| 175 | && intent.hasExtra(LauncherActivity.TASK_ICON_RES)) { |
| 176 | updateTaskDescription(intent); |
| 177 | } |
| 178 | |
Tony Huang | f7b05c4 | 2019-05-02 16:51:01 +0800 | [diff] [blame] | 179 | // Set save container background to transparent for edge to edge nav bar. |
| 180 | View saveContainer = findViewById(R.id.container_save); |
| 181 | saveContainer.setBackgroundColor(Color.TRANSPARENT); |
| 182 | |
Steve McKay | 988d8a3 | 2016-09-27 09:41:17 -0700 | [diff] [blame] | 183 | presentFileErrors(icicle, intent); |
| 184 | } |
Steve McKay | 739f94b | 2016-09-22 14:54:23 -0700 | [diff] [blame] | 185 | |
Steve McKay | 7295c48 | 2017-03-15 17:51:32 -0700 | [diff] [blame] | 186 | // This is called in the intent contains label and icon resources. |
| 187 | // When that is true, the launcher activity has supplied them so we |
| 188 | // can adapt our presentation to how we were launched. |
| 189 | // Without this code, overlaying launcher_icon and launcher_label |
| 190 | // resources won't create a complete illusion of the activity being renamed. |
| 191 | // E.g. if we re-brand Files to Downloads by overlaying label and icon |
| 192 | // when the user tapped recents they'd see not "Downloads", but the |
| 193 | // underlying Activity description...Files. |
| 194 | // Alternate if we rename this activity, when launching other ways |
| 195 | // like when browsing files on a removable disk, the app would be |
| 196 | // called Downloads, which is also not the desired behavior. |
| 197 | private void updateTaskDescription(final Intent intent) { |
| 198 | int labelRes = intent.getIntExtra(LauncherActivity.TASK_LABEL_RES, -1); |
| 199 | assert(labelRes > -1); |
| 200 | String label = getResources().getString(labelRes); |
| 201 | |
| 202 | int iconRes = intent.getIntExtra(LauncherActivity.TASK_ICON_RES, -1); |
| 203 | assert(iconRes > -1); |
| 204 | |
Sunny Goyal | 5b22553 | 2018-07-03 12:44:03 -0700 | [diff] [blame] | 205 | setTaskDescription(new TaskDescription(label, iconRes)); |
Steve McKay | 7295c48 | 2017-03-15 17:51:32 -0700 | [diff] [blame] | 206 | } |
| 207 | |
Steve McKay | 988d8a3 | 2016-09-27 09:41:17 -0700 | [diff] [blame] | 208 | private void presentFileErrors(Bundle icicle, final Intent intent) { |
Tomasz Mikolajewski | dd2b31c | 2016-01-22 16:22:51 +0900 | [diff] [blame] | 209 | final @DialogType int dialogType = intent.getIntExtra( |
| 210 | FileOperationService.EXTRA_DIALOG_TYPE, DIALOG_TYPE_UNKNOWN); |
Tomasz Mikolajewski | cdbbbe0 | 2015-12-25 17:06:52 +0900 | [diff] [blame] | 211 | // DialogFragment takes care of restoring the dialog on configuration change. |
| 212 | // Only show it manually for the first time (icicle is null). |
Tomasz Mikolajewski | dd2b31c | 2016-01-22 16:22:51 +0900 | [diff] [blame] | 213 | if (icicle == null && dialogType != DIALOG_TYPE_UNKNOWN) { |
| 214 | final int opType = intent.getIntExtra( |
Garfield, Tan | 4833477 | 2016-06-28 17:17:38 -0700 | [diff] [blame] | 215 | FileOperationService.EXTRA_OPERATION_TYPE, |
Tomasz Mikolajewski | dd2b31c | 2016-01-22 16:22:51 +0900 | [diff] [blame] | 216 | FileOperationService.OPERATION_COPY); |
Steve McKay | 99f1dc3 | 2016-12-29 16:02:01 -0800 | [diff] [blame] | 217 | final ArrayList<DocumentInfo> docList = |
| 218 | intent.getParcelableArrayListExtra(FileOperationService.EXTRA_FAILED_DOCS); |
Tomasz Mikolajewski | 664025e | 2017-02-01 11:54:48 +0900 | [diff] [blame] | 219 | final ArrayList<Uri> uriList = |
Steve McKay | 99f1dc3 | 2016-12-29 16:02:01 -0800 | [diff] [blame] | 220 | intent.getParcelableArrayListExtra(FileOperationService.EXTRA_FAILED_URIS); |
Tomasz Mikolajewski | dd2b31c | 2016-01-22 16:22:51 +0900 | [diff] [blame] | 221 | OperationDialogFragment.show( |
Tony Huang | 8d8d92f | 2018-09-13 14:41:16 +0800 | [diff] [blame] | 222 | getSupportFragmentManager(), |
Tomasz Mikolajewski | dd2b31c | 2016-01-22 16:22:51 +0900 | [diff] [blame] | 223 | dialogType, |
Steve McKay | 99f1dc3 | 2016-12-29 16:02:01 -0800 | [diff] [blame] | 224 | docList, |
| 225 | uriList, |
Tomasz Mikolajewski | cdbbbe0 | 2015-12-25 17:06:52 +0900 | [diff] [blame] | 226 | mState.stack, |
Steve McKay | c83baa0 | 2016-01-06 18:32:13 -0800 | [diff] [blame] | 227 | opType); |
Steve McKay | d0a2a2c | 2015-03-25 14:35:33 -0700 | [diff] [blame] | 228 | } |
| 229 | } |
| 230 | |
Steve McKay | 0fbfc65 | 2015-08-20 16:48:49 -0700 | [diff] [blame] | 231 | @Override |
Steve McKay | 16e0c1f | 2016-09-15 12:41:13 -0700 | [diff] [blame] | 232 | public void includeState(State state) { |
Steve McKay | d0a2a2c | 2015-03-25 14:35:33 -0700 | [diff] [blame] | 233 | final Intent intent = getIntent(); |
Ben Kwa | 0574b18 | 2015-09-08 07:31:19 -0700 | [diff] [blame] | 234 | |
Garfield Tan | 78ade2b | 2017-02-28 13:19:53 -0800 | [diff] [blame] | 235 | // This is a remnant of old logic where we used to initialize accept MIME types in |
Jon Mann | 9bd4099 | 2017-03-24 12:34:34 -0700 | [diff] [blame] | 236 | // BaseActivity. ProvidersAccess still rely on this being correctly initialized so we still have |
Garfield Tan | 78ade2b | 2017-02-28 13:19:53 -0800 | [diff] [blame] | 237 | // to initialize it in FilesActivity. |
| 238 | state.initAcceptMimes(intent, "*/*"); |
Steve McKay | 459bc2b | 2015-09-16 15:07:31 -0700 | [diff] [blame] | 239 | state.action = State.ACTION_BROWSE; |
Ben Kwa | 0574b18 | 2015-09-08 07:31:19 -0700 | [diff] [blame] | 240 | state.allowMultiple = true; |
Steve McKay | 64ac251 | 2015-05-12 12:49:58 -0700 | [diff] [blame] | 241 | |
Steve McKay | 459bc2b | 2015-09-16 15:07:31 -0700 | [diff] [blame] | 242 | // Options specific to the DocumentsActivity. |
Steve McKay | 0af8afd | 2016-02-25 13:34:03 -0800 | [diff] [blame] | 243 | assert(!intent.hasExtra(Intent.EXTRA_LOCAL_ONLY)); |
Steve McKay | d0a2a2c | 2015-03-25 14:35:33 -0700 | [diff] [blame] | 244 | } |
| 245 | |
| 246 | @Override |
| 247 | protected void onPostCreate(Bundle savedInstanceState) { |
| 248 | super.onPostCreate(savedInstanceState); |
Steve McKay | a8fa58d | 2015-12-08 17:02:03 -0800 | [diff] [blame] | 249 | // This check avoids a flicker from "Recents" to "Home". |
| 250 | // Only update action bar at this point if there is an active |
Dooper | 0930d4c | 2017-06-02 10:32:00 -0700 | [diff] [blame] | 251 | // search. Why? Because this avoid an early (undesired) load of |
Steve McKay | a8fa58d | 2015-12-08 17:02:03 -0800 | [diff] [blame] | 252 | // the recents root...which is the default root in other activities. |
| 253 | // In Files app "Home" is the default, but it is loaded async. |
Steve McKay | 18d01e8 | 2016-02-03 11:15:57 -0800 | [diff] [blame] | 254 | // update will be called once Home root is loaded. |
Steve McKay | a8fa58d | 2015-12-08 17:02:03 -0800 | [diff] [blame] | 255 | // Except while searching we need this call to ensure the |
Dooper | 0930d4c | 2017-06-02 10:32:00 -0700 | [diff] [blame] | 256 | // search bits get laid out correctly. |
Steve McKay | a8fa58d | 2015-12-08 17:02:03 -0800 | [diff] [blame] | 257 | if (mSearchManager.isSearching()) { |
Steve McKay | 18d01e8 | 2016-02-03 11:15:57 -0800 | [diff] [blame] | 258 | mNavigator.update(); |
Steve McKay | a8fa58d | 2015-12-08 17:02:03 -0800 | [diff] [blame] | 259 | } |
Steve McKay | d0a2a2c | 2015-03-25 14:35:33 -0700 | [diff] [blame] | 260 | } |
| 261 | |
| 262 | @Override |
Steve McKay | 459bc2b | 2015-09-16 15:07:31 -0700 | [diff] [blame] | 263 | public void onResume() { |
| 264 | super.onResume(); |
| 265 | |
| 266 | final RootInfo root = getCurrentRoot(); |
| 267 | |
| 268 | // If we're browsing a specific root, and that root went away, then we |
| 269 | // have no reason to hang around. |
| 270 | // TODO: Rather than just disappearing, maybe we should inform |
| 271 | // the user what has happened, let them close us. Less surprising. |
Jon Mann | 9bd4099 | 2017-03-24 12:34:34 -0700 | [diff] [blame] | 272 | if (mProviders.getRootBlocking(root.authority, root.rootId) == null) { |
Steve McKay | 459bc2b | 2015-09-16 15:07:31 -0700 | [diff] [blame] | 273 | finish(); |
| 274 | } |
| 275 | } |
| 276 | |
| 277 | @Override |
Steve McKay | 18d01e8 | 2016-02-03 11:15:57 -0800 | [diff] [blame] | 278 | public String getDrawerTitle() { |
Steve McKay | 17f7e58 | 2016-04-04 15:26:48 -0700 | [diff] [blame] | 279 | Intent intent = getIntent(); |
| 280 | return (intent != null && intent.hasExtra(Intent.EXTRA_TITLE)) |
| 281 | ? intent.getStringExtra(Intent.EXTRA_TITLE) |
Steve McKay | a0b5265 | 2016-10-27 12:56:55 -0700 | [diff] [blame] | 282 | : getString(R.string.app_label); |
Steve McKay | d0a2a2c | 2015-03-25 14:35:33 -0700 | [diff] [blame] | 283 | } |
| 284 | |
| 285 | @Override |
Steve McKay | d0a2a2c | 2015-03-25 14:35:33 -0700 | [diff] [blame] | 286 | public boolean onPrepareOptionsMenu(Menu menu) { |
Steve McKay | e980927 | 2015-10-01 11:39:24 -0700 | [diff] [blame] | 287 | super.onPrepareOptionsMenu(menu); |
Steve McKay | 92ae43d | 2016-11-08 12:06:58 -0800 | [diff] [blame] | 288 | mInjector.menuManager.updateOptionMenu(menu); |
Steve McKay | e980927 | 2015-10-01 11:39:24 -0700 | [diff] [blame] | 289 | return true; |
Steve McKay | d0a2a2c | 2015-03-25 14:35:33 -0700 | [diff] [blame] | 290 | } |
| 291 | |
| 292 | @Override |
Steve McKay | 1f19948 | 2015-05-20 15:58:42 -0700 | [diff] [blame] | 293 | public boolean onOptionsItemSelected(MenuItem item) { |
Jon Mann | 49be24c | 2017-02-13 17:29:20 -0800 | [diff] [blame] | 294 | DirectoryFragment dir; |
Steve McKay | f2c8b0d | 2015-09-23 15:44:24 -0700 | [diff] [blame] | 295 | switch (item.getItemId()) { |
Ben Lin | ff7f3ae | 2017-04-25 16:08:52 -0700 | [diff] [blame] | 296 | case R.id.option_menu_create_dir: |
Steve McKay | 0af8afd | 2016-02-25 13:34:03 -0800 | [diff] [blame] | 297 | assert(canCreateDirectory()); |
Ben Lin | ff7f3ae | 2017-04-25 16:08:52 -0700 | [diff] [blame] | 298 | mInjector.actions.showCreateDirectoryDialog(); |
Aga Wronska | 4972d71 | 2016-03-30 13:55:19 -0700 | [diff] [blame] | 299 | break; |
Ben Lin | ff7f3ae | 2017-04-25 16:08:52 -0700 | [diff] [blame] | 300 | case R.id.option_menu_new_window: |
Steve McKay | 92ae43d | 2016-11-08 12:06:58 -0800 | [diff] [blame] | 301 | mInjector.actions.openInNewWindow(mState.stack); |
Aga Wronska | 4972d71 | 2016-03-30 13:55:19 -0700 | [diff] [blame] | 302 | break; |
Ben Lin | ff7f3ae | 2017-04-25 16:08:52 -0700 | [diff] [blame] | 303 | case R.id.option_menu_settings: |
Steve McKay | 92ae43d | 2016-11-08 12:06:58 -0800 | [diff] [blame] | 304 | mInjector.actions.openSettings(getCurrentRoot()); |
Ben Lin | 5668b86 | 2016-06-28 17:12:52 -0700 | [diff] [blame] | 305 | break; |
Ben Lin | ff7f3ae | 2017-04-25 16:08:52 -0700 | [diff] [blame] | 306 | case R.id.option_menu_select_all: |
Jon Mann | 30d8c79 | 2017-02-21 17:44:49 -0800 | [diff] [blame] | 307 | mInjector.actions.selectAllFiles(); |
Jon Mann | 49be24c | 2017-02-13 17:29:20 -0800 | [diff] [blame] | 308 | break; |
Steve McKay | 0c7ad03 | 2017-08-09 11:50:10 -0700 | [diff] [blame] | 309 | case R.id.option_menu_inspect: |
Steve McKay | efd10ac | 2017-07-25 13:33:57 -0700 | [diff] [blame] | 310 | mInjector.actions.showInspector(getCurrentDirectory()); |
| 311 | break; |
Aga Wronska | 4972d71 | 2016-03-30 13:55:19 -0700 | [diff] [blame] | 312 | default: |
| 313 | return super.onOptionsItemSelected(item); |
Steve McKay | 1f19948 | 2015-05-20 15:58:42 -0700 | [diff] [blame] | 314 | } |
Aga Wronska | 4972d71 | 2016-03-30 13:55:19 -0700 | [diff] [blame] | 315 | return true; |
Steve McKay | 1f19948 | 2015-05-20 15:58:42 -0700 | [diff] [blame] | 316 | } |
| 317 | |
| 318 | @Override |
Ben Lin | a867323 | 2016-09-28 15:40:04 -0700 | [diff] [blame] | 319 | public void onProvideKeyboardShortcuts( |
| 320 | List<KeyboardShortcutGroup> data, Menu menu, int deviceId) { |
Steve McKay | 92ae43d | 2016-11-08 12:06:58 -0800 | [diff] [blame] | 321 | mInjector.menuManager.updateKeyboardShortcutsMenu(data, this::getString); |
Ben Lin | a867323 | 2016-09-28 15:40:04 -0700 | [diff] [blame] | 322 | } |
| 323 | |
| 324 | @Override |
Steve McKay | 988d8a3 | 2016-09-27 09:41:17 -0700 | [diff] [blame] | 325 | public void refreshDirectory(@AnimationType int anim) { |
Tony Huang | 8d8d92f | 2018-09-13 14:41:16 +0800 | [diff] [blame] | 326 | final FragmentManager fm = getSupportFragmentManager(); |
Steve McKay | d0a2a2c | 2015-03-25 14:35:33 -0700 | [diff] [blame] | 327 | final RootInfo root = getCurrentRoot(); |
| 328 | final DocumentInfo cwd = getCurrentDirectory(); |
| 329 | |
Steve McKay | 0af8afd | 2016-02-25 13:34:03 -0800 | [diff] [blame] | 330 | assert(!mSearchManager.isSearching()); |
Aga Wronska | af5ace5 | 2016-02-17 13:50:42 -0800 | [diff] [blame] | 331 | |
Garfield Tan | e967033 | 2017-03-06 18:33:23 -0800 | [diff] [blame] | 332 | if (mState.stack.isRecents()) { |
Steve McKay | d0a2a2c | 2015-03-25 14:35:33 -0700 | [diff] [blame] | 333 | DirectoryFragment.showRecentsOpen(fm, anim); |
Steve McKay | d0a2a2c | 2015-03-25 14:35:33 -0700 | [diff] [blame] | 334 | } else { |
Aga Wronska | af5ace5 | 2016-02-17 13:50:42 -0800 | [diff] [blame] | 335 | // Normal boring directory |
| 336 | DirectoryFragment.showDirectory(fm, root, cwd, anim); |
Steve McKay | d0a2a2c | 2015-03-25 14:35:33 -0700 | [diff] [blame] | 337 | } |
Steve McKay | d0a2a2c | 2015-03-25 14:35:33 -0700 | [diff] [blame] | 338 | } |
| 339 | |
| 340 | @Override |
Steve McKay | 351a749 | 2015-08-04 10:11:01 -0700 | [diff] [blame] | 341 | public void onDocumentsPicked(List<DocumentInfo> docs) { |
| 342 | throw new UnsupportedOperationException(); |
Steve McKay | d0a2a2c | 2015-03-25 14:35:33 -0700 | [diff] [blame] | 343 | } |
| 344 | |
Steve McKay | 351a749 | 2015-08-04 10:11:01 -0700 | [diff] [blame] | 345 | @Override |
Steve McKay | eed2f4e | 2016-10-03 20:30:52 -0700 | [diff] [blame] | 346 | public void onDocumentPicked(DocumentInfo doc) { |
Tomasz Mikolajewski | d22cc18 | 2017-03-15 16:13:46 +0900 | [diff] [blame] | 347 | throw new UnsupportedOperationException(); |
Tomasz Mikolajewski | be4e38b | 2016-04-07 18:00:08 +0900 | [diff] [blame] | 348 | } |
| 349 | |
Garfield, Tan | 804133e | 2016-04-20 15:13:56 -0700 | [diff] [blame] | 350 | @Override |
Steve McKay | 16e0c1f | 2016-09-15 12:41:13 -0700 | [diff] [blame] | 351 | public void onDirectoryCreated(DocumentInfo doc) { |
Ben Lin | 81afd7f | 2016-08-22 18:24:03 -0700 | [diff] [blame] | 352 | assert(doc.isDirectory()); |
Steve McKay | 92ae43d | 2016-11-08 12:06:58 -0800 | [diff] [blame] | 353 | mInjector.focusManager.focusDocument(doc.documentId); |
Ben Lin | 81afd7f | 2016-08-22 18:24:03 -0700 | [diff] [blame] | 354 | } |
| 355 | |
Takamasa Kuramitsu | 5971052 | 2018-06-29 18:42:21 +0900 | [diff] [blame] | 356 | @Override |
| 357 | protected boolean canInspectDirectory() { |
| 358 | return getCurrentDirectory() != null && mInjector.getModel().doc != null; |
| 359 | } |
| 360 | |
Ben Lin | aa66c43 | 2016-10-12 12:11:24 -0700 | [diff] [blame] | 361 | @CallSuper |
| 362 | @Override |
| 363 | public boolean onKeyDown(int keyCode, KeyEvent event) { |
Steve McKay | 0471826 | 2016-11-08 11:01:35 -0800 | [diff] [blame] | 364 | return mActivityInputHandler.onKeyDown(keyCode, event) |
Bill Lin | 35bfbef | 2019-08-05 16:09:53 +0800 | [diff] [blame] | 365 | || mSharedInputHandler.onKeyDown(keyCode, event) |
Steve McKay | 0471826 | 2016-11-08 11:01:35 -0800 | [diff] [blame] | 366 | || super.onKeyDown(keyCode, event); |
Ben Lin | aa66c43 | 2016-10-12 12:11:24 -0700 | [diff] [blame] | 367 | } |
| 368 | |
Steve McKay | d0a2a2c | 2015-03-25 14:35:33 -0700 | [diff] [blame] | 369 | @Override |
Steve McKay | 0599a44 | 2015-05-05 14:50:00 -0700 | [diff] [blame] | 370 | public boolean onKeyShortcut(int keyCode, KeyEvent event) { |
| 371 | DirectoryFragment dir; |
Steve McKay | d480081 | 2016-02-02 11:41:03 -0800 | [diff] [blame] | 372 | // TODO: All key events should be statically bound using alphabeticShortcut. |
| 373 | // But not working. |
Steve McKay | 0599a44 | 2015-05-05 14:50:00 -0700 | [diff] [blame] | 374 | switch (keyCode) { |
| 375 | case KeyEvent.KEYCODE_A: |
Jon Mann | 30d8c79 | 2017-02-21 17:44:49 -0800 | [diff] [blame] | 376 | mInjector.actions.selectAllFiles(); |
Steve McKay | 0599a44 | 2015-05-05 14:50:00 -0700 | [diff] [blame] | 377 | return true; |
Ben Lin | ff4d584 | 2016-04-18 14:35:28 -0700 | [diff] [blame] | 378 | case KeyEvent.KEYCODE_X: |
Steve McKay | 92ae43d | 2016-11-08 12:06:58 -0800 | [diff] [blame] | 379 | mInjector.actions.cutToClipboard(); |
Ben Lin | ff4d584 | 2016-04-18 14:35:28 -0700 | [diff] [blame] | 380 | return true; |
Steve McKay | 1f19948 | 2015-05-20 15:58:42 -0700 | [diff] [blame] | 381 | case KeyEvent.KEYCODE_C: |
Steve McKay | 92ae43d | 2016-11-08 12:06:58 -0800 | [diff] [blame] | 382 | mInjector.actions.copyToClipboard(); |
Steve McKay | 6035b3c | 2015-12-04 11:19:09 -0800 | [diff] [blame] | 383 | return true; |
| 384 | case KeyEvent.KEYCODE_V: |
Steve McKay | d480081 | 2016-02-02 11:41:03 -0800 | [diff] [blame] | 385 | dir = getDirectoryFragment(); |
| 386 | if (dir != null) { |
| 387 | dir.pasteFromClipboard(); |
| 388 | } |
Steve McKay | 6035b3c | 2015-12-04 11:19:09 -0800 | [diff] [blame] | 389 | return true; |
| 390 | default: |
| 391 | return super.onKeyShortcut(keyCode, event); |
Steve McKay | 0599a44 | 2015-05-05 14:50:00 -0700 | [diff] [blame] | 392 | } |
| 393 | } |
| 394 | |
Steve McKay | b68dd22 | 2015-04-20 17:18:15 -0700 | [diff] [blame] | 395 | @Override |
Steve McKay | 92ae43d | 2016-11-08 12:06:58 -0800 | [diff] [blame] | 396 | public Injector<ActionHandler<FilesActivity>> getInjector() { |
| 397 | return mInjector; |
Steve McKay | c8889af | 2016-09-23 11:22:41 -0700 | [diff] [blame] | 398 | } |
Steve McKay | d0a2a2c | 2015-03-25 14:35:33 -0700 | [diff] [blame] | 399 | } |