Garfield Tan | 63bf813 | 2016-10-11 11:00:49 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2016 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.documentsui; |
| 18 | |
| 19 | import android.app.Activity; |
Garfield Tan | be1e079 | 2017-02-24 17:14:53 -0800 | [diff] [blame] | 20 | import android.content.BroadcastReceiver; |
| 21 | import android.content.Context; |
| 22 | import android.content.Intent; |
| 23 | import android.content.IntentFilter; |
Garfield Tan | 63bf813 | 2016-10-11 11:00:49 -0700 | [diff] [blame] | 24 | import android.net.Uri; |
Zemiao Zhu | c85758f | 2020-03-03 17:02:21 -0800 | [diff] [blame] | 25 | |
KOUSHIK PANUGANTI | 6ca7acc | 2018-04-17 16:00:10 -0700 | [diff] [blame] | 26 | import androidx.localbroadcastmanager.content.LocalBroadcastManager; |
Garfield Tan | 63bf813 | 2016-10-11 11:00:49 -0700 | [diff] [blame] | 27 | |
| 28 | import com.android.documentsui.AbstractActionHandler.CommonAddons; |
| 29 | import com.android.documentsui.base.DocumentInfo; |
| 30 | import com.android.documentsui.base.PairedTask; |
| 31 | import com.android.documentsui.base.RootInfo; |
| 32 | import com.android.documentsui.base.State; |
| 33 | import com.android.documentsui.dirlist.AnimationView; |
Steve McKay | 3a26823 | 2016-10-19 11:15:47 -0700 | [diff] [blame] | 34 | import com.android.documentsui.queries.SearchViewManager; |
Jon Mann | 9bd4099 | 2017-03-24 12:34:34 -0700 | [diff] [blame] | 35 | import com.android.documentsui.roots.ProvidersAccess; |
Garfield Tan | 63bf813 | 2016-10-11 11:00:49 -0700 | [diff] [blame] | 36 | |
| 37 | import java.util.Collection; |
| 38 | |
| 39 | /** |
| 40 | * Monitors roots change and refresh the page when necessary. |
| 41 | */ |
| 42 | final class RootsMonitor<T extends Activity & CommonAddons> { |
| 43 | |
Garfield Tan | be1e079 | 2017-02-24 17:14:53 -0800 | [diff] [blame] | 44 | private final LocalBroadcastManager mManager; |
| 45 | private final BroadcastReceiver mReceiver; |
Garfield Tan | 63bf813 | 2016-10-11 11:00:49 -0700 | [diff] [blame] | 46 | |
| 47 | RootsMonitor( |
| 48 | final T activity, |
| 49 | final ActionHandler actions, |
Jon Mann | 9bd4099 | 2017-03-24 12:34:34 -0700 | [diff] [blame] | 50 | final ProvidersAccess providers, |
Garfield Tan | 63bf813 | 2016-10-11 11:00:49 -0700 | [diff] [blame] | 51 | final DocumentsAccess docs, |
| 52 | final State state, |
Garfield Tan | 80b52b3 | 2017-04-25 15:50:52 -0700 | [diff] [blame] | 53 | final SearchViewManager searchMgr, |
| 54 | final Runnable actionModeFinisher) { |
Garfield Tan | be1e079 | 2017-02-24 17:14:53 -0800 | [diff] [blame] | 55 | mManager = LocalBroadcastManager.getInstance(activity); |
Garfield Tan | 63bf813 | 2016-10-11 11:00:49 -0700 | [diff] [blame] | 56 | |
Garfield Tan | be1e079 | 2017-02-24 17:14:53 -0800 | [diff] [blame] | 57 | mReceiver = new BroadcastReceiver() { |
Garfield Tan | 63bf813 | 2016-10-11 11:00:49 -0700 | [diff] [blame] | 58 | @Override |
Garfield Tan | be1e079 | 2017-02-24 17:14:53 -0800 | [diff] [blame] | 59 | public void onReceive(Context context, Intent intent) { |
Steve McKay | 2d19a69 | 2017-08-22 09:05:08 -0700 | [diff] [blame] | 60 | new HandleRootsChangedTask<>( |
Garfield Tan | 63bf813 | 2016-10-11 11:00:49 -0700 | [diff] [blame] | 61 | activity, |
| 62 | actions, |
Jon Mann | 9bd4099 | 2017-03-24 12:34:34 -0700 | [diff] [blame] | 63 | providers, |
Garfield Tan | 63bf813 | 2016-10-11 11:00:49 -0700 | [diff] [blame] | 64 | docs, |
| 65 | state, |
Garfield Tan | 80b52b3 | 2017-04-25 15:50:52 -0700 | [diff] [blame] | 66 | searchMgr, |
| 67 | actionModeFinisher).execute(activity.getCurrentRoot()); |
Garfield Tan | 63bf813 | 2016-10-11 11:00:49 -0700 | [diff] [blame] | 68 | } |
| 69 | }; |
| 70 | } |
| 71 | |
| 72 | void start() { |
Jon Mann | 9bd4099 | 2017-03-24 12:34:34 -0700 | [diff] [blame] | 73 | mManager.registerReceiver(mReceiver, new IntentFilter(ProvidersAccess.BROADCAST_ACTION)); |
Garfield Tan | 63bf813 | 2016-10-11 11:00:49 -0700 | [diff] [blame] | 74 | } |
| 75 | |
| 76 | void stop() { |
Garfield Tan | be1e079 | 2017-02-24 17:14:53 -0800 | [diff] [blame] | 77 | mManager.unregisterReceiver(mReceiver); |
Garfield Tan | 63bf813 | 2016-10-11 11:00:49 -0700 | [diff] [blame] | 78 | } |
| 79 | |
| 80 | private static class HandleRootsChangedTask<T extends Activity & CommonAddons> |
| 81 | extends PairedTask<T, RootInfo, RootInfo> { |
| 82 | private final ActionHandler mActions; |
Jon Mann | 9bd4099 | 2017-03-24 12:34:34 -0700 | [diff] [blame] | 83 | private final ProvidersAccess mProviders; |
Garfield Tan | 63bf813 | 2016-10-11 11:00:49 -0700 | [diff] [blame] | 84 | private final DocumentsAccess mDocs; |
| 85 | private final State mState; |
| 86 | private final SearchViewManager mSearchMgr; |
Garfield Tan | 80b52b3 | 2017-04-25 15:50:52 -0700 | [diff] [blame] | 87 | private final Runnable mActionModeFinisher; |
Garfield Tan | 63bf813 | 2016-10-11 11:00:49 -0700 | [diff] [blame] | 88 | |
| 89 | private RootInfo mCurrentRoot; |
| 90 | private DocumentInfo mDefaultRootDocument; |
| 91 | |
| 92 | private HandleRootsChangedTask( |
| 93 | T activity, |
| 94 | ActionHandler actions, |
Jon Mann | 9bd4099 | 2017-03-24 12:34:34 -0700 | [diff] [blame] | 95 | ProvidersAccess providers, |
Garfield Tan | 63bf813 | 2016-10-11 11:00:49 -0700 | [diff] [blame] | 96 | DocumentsAccess docs, |
| 97 | State state, |
Garfield Tan | 80b52b3 | 2017-04-25 15:50:52 -0700 | [diff] [blame] | 98 | SearchViewManager searchMgr, |
| 99 | Runnable actionModeFinisher) { |
Garfield Tan | 63bf813 | 2016-10-11 11:00:49 -0700 | [diff] [blame] | 100 | super(activity); |
| 101 | mActions = actions; |
Jon Mann | 9bd4099 | 2017-03-24 12:34:34 -0700 | [diff] [blame] | 102 | mProviders = providers; |
Garfield Tan | 63bf813 | 2016-10-11 11:00:49 -0700 | [diff] [blame] | 103 | mDocs = docs; |
| 104 | mState = state; |
| 105 | mSearchMgr = searchMgr; |
Garfield Tan | 80b52b3 | 2017-04-25 15:50:52 -0700 | [diff] [blame] | 106 | mActionModeFinisher = actionModeFinisher; |
Garfield Tan | 63bf813 | 2016-10-11 11:00:49 -0700 | [diff] [blame] | 107 | } |
| 108 | |
| 109 | @Override |
| 110 | protected RootInfo run(RootInfo... roots) { |
| 111 | assert (roots.length == 1); |
| 112 | mCurrentRoot = roots[0]; |
Jon Mann | 9bd4099 | 2017-03-24 12:34:34 -0700 | [diff] [blame] | 113 | final Collection<RootInfo> cachedRoots = mProviders.getRootsBlocking(); |
Garfield Tan | 63bf813 | 2016-10-11 11:00:49 -0700 | [diff] [blame] | 114 | for (final RootInfo root : cachedRoots) { |
| 115 | if (root.getUri().equals(mCurrentRoot.getUri())) { |
| 116 | // We don't need to change the current root as the current root was not removed. |
| 117 | return null; |
| 118 | } |
| 119 | } |
| 120 | |
| 121 | // Choose the default root. |
Jon Mann | 9bd4099 | 2017-03-24 12:34:34 -0700 | [diff] [blame] | 122 | final RootInfo defaultRoot = mProviders.getDefaultRootBlocking(mState); |
Garfield Tan | 63bf813 | 2016-10-11 11:00:49 -0700 | [diff] [blame] | 123 | assert (defaultRoot != null); |
| 124 | if (!defaultRoot.isRecents()) { |
| 125 | mDefaultRootDocument = mDocs.getRootDocument(defaultRoot); |
| 126 | } |
| 127 | return defaultRoot; |
| 128 | } |
| 129 | |
| 130 | @Override |
| 131 | protected void finish(RootInfo defaultRoot) { |
| 132 | if (defaultRoot == null) { |
| 133 | return; |
| 134 | } |
| 135 | |
| 136 | // If the activity has been launched for the specific root and it is removed, finish the |
| 137 | // activity. |
| 138 | final Uri uri = mOwner.getIntent().getData(); |
| 139 | if (uri != null && uri.equals(mCurrentRoot.getUri())) { |
Zemiao Zhu | c85758f | 2020-03-03 17:02:21 -0800 | [diff] [blame] | 140 | mOwner.finishAndRemoveTask(); |
Garfield Tan | 63bf813 | 2016-10-11 11:00:49 -0700 | [diff] [blame] | 141 | return; |
| 142 | } |
| 143 | |
Garfield Tan | 80b52b3 | 2017-04-25 15:50:52 -0700 | [diff] [blame] | 144 | // Clean action mode before changing root. |
| 145 | mActionModeFinisher.run(); |
| 146 | |
Garfield Tan | 63bf813 | 2016-10-11 11:00:49 -0700 | [diff] [blame] | 147 | // Clear entire backstack and start in new root. |
Garfield Tan | 2a83742 | 2016-10-19 11:50:45 -0700 | [diff] [blame] | 148 | mState.stack.changeRoot(defaultRoot); |
Tomasz Mikolajewski | 9e04785 | 2017-02-13 14:05:17 +0900 | [diff] [blame] | 149 | mSearchMgr.update(mState.stack); |
Garfield Tan | 63bf813 | 2016-10-11 11:00:49 -0700 | [diff] [blame] | 150 | |
| 151 | if (defaultRoot.isRecents()) { |
| 152 | mOwner.refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE); |
| 153 | } else { |
| 154 | mActions.openContainerDocument(mDefaultRootDocument); |
| 155 | } |
| 156 | } |
| 157 | } |
| 158 | } |