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