RootsMonitor.java revision 3a2682362481d1af4ec437775610a1f11e9faa24
163bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan/*
263bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan * Copyright (C) 2016 The Android Open Source Project
363bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan *
463bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan * Licensed under the Apache License, Version 2.0 (the "License");
563bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan * you may not use this file except in compliance with the License.
663bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan * You may obtain a copy of the License at
763bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan *
863bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan *      http://www.apache.org/licenses/LICENSE-2.0
963bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan *
1063bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan * Unless required by applicable law or agreed to in writing, software
1163bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan * distributed under the License is distributed on an "AS IS" BASIS,
1263bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1363bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan * See the License for the specific language governing permissions and
1463bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan * limitations under the License.
1563bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan */
1663bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan
1763bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tanpackage com.android.documentsui;
1863bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan
1963bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tanimport android.app.Activity;
2063bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tanimport android.content.ContentResolver;
2163bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tanimport android.database.ContentObserver;
2263bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tanimport android.net.Uri;
2363bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tanimport android.os.Handler;
2463bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tanimport android.os.Looper;
2563bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan
2663bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tanimport com.android.documentsui.AbstractActionHandler.CommonAddons;
2763bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tanimport com.android.documentsui.base.DocumentInfo;
2863bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tanimport com.android.documentsui.base.PairedTask;
2963bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tanimport com.android.documentsui.base.RootInfo;
3063bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tanimport com.android.documentsui.base.State;
3163bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tanimport com.android.documentsui.dirlist.AnimationView;
323a2682362481d1af4ec437775610a1f11e9faa24Steve McKayimport com.android.documentsui.queries.SearchViewManager;
3363bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tanimport com.android.documentsui.roots.RootsAccess;
3463bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan
3563bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tanimport java.util.Collection;
3663bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan
3763bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan/**
3863bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan * Monitors roots change and refresh the page when necessary.
3963bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan */
4063bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tanfinal class RootsMonitor<T extends Activity & CommonAddons> {
4163bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan
4263bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan    private final ContentResolver mResolver;
4363bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan    private final ContentObserver mObserver;
4463bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan
4563bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan    RootsMonitor(
4663bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            final T activity,
4763bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            final ActionHandler actions,
4863bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            final RootsAccess roots,
4963bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            final DocumentsAccess docs,
5063bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            final State state,
5163bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            final SearchViewManager searchMgr) {
5263bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan        mResolver = activity.getContentResolver();
5363bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan
5463bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan        mObserver = new ContentObserver(new Handler(Looper.getMainLooper())) {
5563bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            @Override
5663bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            public void onChange(boolean selfChange) {
5763bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan                new HandleRootsChangedTask<T>(
5863bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan                        activity,
5963bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan                        actions,
6063bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan                        roots,
6163bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan                        docs,
6263bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan                        state,
6363bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan                        searchMgr).execute(activity.getCurrentRoot());
6463bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            }
6563bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan        };
6663bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan    }
6763bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan
6863bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan    void start() {
6963bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan        mResolver.registerContentObserver(RootsAccess.NOTIFICATION_URI, false, mObserver);
7063bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan    }
7163bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan
7263bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan    void stop() {
7363bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan        mResolver.unregisterContentObserver(mObserver);
7463bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan    }
7563bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan
7663bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan    private static class HandleRootsChangedTask<T extends Activity & CommonAddons>
7763bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            extends PairedTask<T, RootInfo, RootInfo> {
7863bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan        private final ActionHandler mActions;
7963bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan        private final RootsAccess mRoots;
8063bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan        private final DocumentsAccess mDocs;
8163bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan        private final State mState;
8263bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan        private final SearchViewManager mSearchMgr;
8363bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan
8463bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan        private RootInfo mCurrentRoot;
8563bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan        private DocumentInfo mDefaultRootDocument;
8663bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan
8763bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan        private HandleRootsChangedTask(
8863bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan                T activity,
8963bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan                ActionHandler actions,
9063bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan                RootsAccess roots,
9163bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan                DocumentsAccess docs,
9263bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan                State state,
9363bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan                SearchViewManager searchMgr) {
9463bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            super(activity);
9563bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            mActions = actions;
9663bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            mRoots = roots;
9763bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            mDocs = docs;
9863bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            mState = state;
9963bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            mSearchMgr = searchMgr;
10063bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan        }
10163bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan
10263bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan        @Override
10363bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan        protected RootInfo run(RootInfo... roots) {
10463bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            assert (roots.length == 1);
10563bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            mCurrentRoot = roots[0];
10663bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            final Collection<RootInfo> cachedRoots = mRoots.getRootsBlocking();
10763bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            for (final RootInfo root : cachedRoots) {
10863bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan                if (root.getUri().equals(mCurrentRoot.getUri())) {
10963bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan                    // We don't need to change the current root as the current root was not removed.
11063bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan                    return null;
11163bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan                }
11263bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            }
11363bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan
11463bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            // Choose the default root.
11563bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            final RootInfo defaultRoot = mRoots.getDefaultRootBlocking(mState);
11663bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            assert (defaultRoot != null);
11763bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            if (!defaultRoot.isRecents()) {
11863bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan                mDefaultRootDocument = mDocs.getRootDocument(defaultRoot);
11963bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            }
12063bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            return defaultRoot;
12163bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan        }
12263bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan
12363bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan        @Override
12463bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan        protected void finish(RootInfo defaultRoot) {
12563bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            if (defaultRoot == null) {
12663bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan                return;
12763bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            }
12863bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan
12963bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            // If the activity has been launched for the specific root and it is removed, finish the
13063bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            // activity.
13163bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            final Uri uri = mOwner.getIntent().getData();
13263bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            if (uri != null && uri.equals(mCurrentRoot.getUri())) {
13363bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan                mOwner.finish();
13463bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan                return;
13563bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            }
13663bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan
13763bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            // Clear entire backstack and start in new root.
13863bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            mState.onRootChanged(defaultRoot);
13963bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            mSearchMgr.update(defaultRoot);
14063bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan
14163bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            if (defaultRoot.isRecents()) {
14263bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan                mOwner.refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE);
14363bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            } else {
14463bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan                mActions.openContainerDocument(mDefaultRootDocument);
14563bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan            }
14663bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan        }
14763bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan    }
14863bf8135243605949a3bb140167ef91f5c6ae2aeGarfield Tan}
149