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