blob: e87e53a643d66ec3389f904e991a57468e86c93e [file] [log] [blame]
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.documentsui;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.android.documentsui.AbstractActionHandler.CommonAddons;
import com.android.documentsui.base.DocumentInfo;
import com.android.documentsui.base.PairedTask;
import com.android.documentsui.base.RootInfo;
import com.android.documentsui.base.State;
import com.android.documentsui.dirlist.AnimationView;
import com.android.documentsui.queries.SearchViewManager;
import com.android.documentsui.roots.ProvidersAccess;
import java.util.Collection;
/**
* Monitors roots change and refresh the page when necessary.
*/
final class RootsMonitor<T extends Activity & CommonAddons> {
private final LocalBroadcastManager mManager;
private final BroadcastReceiver mReceiver;
RootsMonitor(
final T activity,
final ActionHandler actions,
final ProvidersAccess providers,
final DocumentsAccess docs,
final State state,
final SearchViewManager searchMgr,
final Runnable actionModeFinisher) {
mManager = LocalBroadcastManager.getInstance(activity);
mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
new HandleRootsChangedTask<>(
activity,
actions,
providers,
docs,
state,
searchMgr,
actionModeFinisher).execute(activity.getCurrentRoot());
}
};
}
void start() {
mManager.registerReceiver(mReceiver, new IntentFilter(ProvidersAccess.BROADCAST_ACTION));
}
void stop() {
mManager.unregisterReceiver(mReceiver);
}
private static class HandleRootsChangedTask<T extends Activity & CommonAddons>
extends PairedTask<T, RootInfo, RootInfo> {
private final ActionHandler mActions;
private final ProvidersAccess mProviders;
private final DocumentsAccess mDocs;
private final State mState;
private final SearchViewManager mSearchMgr;
private final Runnable mActionModeFinisher;
private RootInfo mCurrentRoot;
private DocumentInfo mDefaultRootDocument;
private HandleRootsChangedTask(
T activity,
ActionHandler actions,
ProvidersAccess providers,
DocumentsAccess docs,
State state,
SearchViewManager searchMgr,
Runnable actionModeFinisher) {
super(activity);
mActions = actions;
mProviders = providers;
mDocs = docs;
mState = state;
mSearchMgr = searchMgr;
mActionModeFinisher = actionModeFinisher;
}
@Override
protected RootInfo run(RootInfo... roots) {
assert (roots.length == 1);
mCurrentRoot = roots[0];
final Collection<RootInfo> cachedRoots = mProviders.getRootsBlocking();
for (final RootInfo root : cachedRoots) {
if (root.getUri().equals(mCurrentRoot.getUri())) {
// We don't need to change the current root as the current root was not removed.
return null;
}
}
// Choose the default root.
final RootInfo defaultRoot = mProviders.getDefaultRootBlocking(mState);
assert (defaultRoot != null);
if (!defaultRoot.isRecents()) {
mDefaultRootDocument = mDocs.getRootDocument(defaultRoot);
}
return defaultRoot;
}
@Override
protected void finish(RootInfo defaultRoot) {
if (defaultRoot == null) {
return;
}
// If the activity has been launched for the specific root and it is removed, finish the
// activity.
final Uri uri = mOwner.getIntent().getData();
if (uri != null && uri.equals(mCurrentRoot.getUri())) {
mOwner.finish();
return;
}
// Clean action mode before changing root.
mActionModeFinisher.run();
// Clear entire backstack and start in new root.
mState.stack.changeRoot(defaultRoot);
mSearchMgr.update(mState.stack);
if (defaultRoot.isRecents()) {
mOwner.refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE);
} else {
mActions.openContainerDocument(mDefaultRootDocument);
}
}
}
}