Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 681f8931 authored by Garfield Tan's avatar Garfield Tan Committed by Android (Google) Code Review
Browse files

Merge "Lift loader to activity level." into arc-apps

parents 914b3757 e9670333
Loading
Loading
Loading
Loading
+101 −1
Original line number Diff line number Diff line
@@ -18,12 +18,17 @@ package com.android.documentsui;

import static com.android.documentsui.base.DocumentInfo.getCursorInt;
import static com.android.documentsui.base.DocumentInfo.getCursorString;
import static com.android.documentsui.base.Shared.DEBUG;

import android.app.Activity;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.Context;
import android.content.Intent;
import android.content.Loader;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcelable;
import android.provider.DocumentsContract;
import android.support.annotation.VisibleForTesting;
@@ -44,7 +49,6 @@ import com.android.documentsui.dirlist.AnimationView;
import com.android.documentsui.dirlist.AnimationView.AnimationType;
import com.android.documentsui.dirlist.DocumentDetails;
import com.android.documentsui.dirlist.FocusHandler;
import com.android.documentsui.dirlist.Model;
import com.android.documentsui.files.LauncherActivity;
import com.android.documentsui.queries.SearchViewManager;
import com.android.documentsui.roots.LoadRootTask;
@@ -66,6 +70,9 @@ import javax.annotation.Nullable;
public abstract class AbstractActionHandler<T extends Activity & CommonAddons>
        implements ActionHandler {

    @VisibleForTesting
    static final int LOADER_ID = 42;

    private static final String TAG = "AbstractActionHandler";
    private static final int REFRESH_SPINNER_TIMEOUT = 500;

@@ -79,8 +86,12 @@ public abstract class AbstractActionHandler<T extends Activity & CommonAddons>
    protected final Lookup<String, Executor> mExecutors;
    protected final Injector mInjector;

    private final LoaderBindings mBindings;

    private Runnable mDisplayStateChangedListener;

    private DirectoryReloadLock mDirectoryReloadLock;

    @Override
    public void registerDisplayStateChangedListener(Runnable l) {
        mDisplayStateChangedListener = l;
@@ -117,6 +128,8 @@ public abstract class AbstractActionHandler<T extends Activity & CommonAddons>
        mSearchMgr = searchMgr;
        mExecutors = executors;
        mInjector = injector;

        mBindings = new LoaderBindings();
    }

    @Override
@@ -242,6 +255,18 @@ public abstract class AbstractActionHandler<T extends Activity & CommonAddons>
        throw new UnsupportedOperationException("Show chooser for doc not supported!");
    }

    @Override
    public void openRootDocument(@Nullable DocumentInfo rootDoc) {
        if (rootDoc == null) {
            // There are 2 cases where rootDoc is null -- 1) loading recents; 2) failed to load root
            // document. Either case we should call refreshCurrentRootAndDirectory() to let
            // DirectoryFragment update UI.
            mActivity.refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE);
        } else {
            openContainerDocument(rootDoc);
        }
    }

    @Override
    public void openContainerDocument(DocumentInfo doc) {
        assert(doc.isContainer());
@@ -346,6 +371,22 @@ public abstract class AbstractActionHandler<T extends Activity & CommonAddons>
                .executeOnExecutor(mExecutors.lookup(uri.getAuthority()));
    }

    @Override
    public void loadDocumentsForCurrentStack() {
        DocumentStack stack = mState.stack;
        if (!stack.isRecents() && stack.isEmpty()) {
            DirectoryResult result = new DirectoryResult();

            // TODO (b/35996595): Consider plumbing through the actual exception, though it might
            // not be very useful (always pointing to DatabaseUtils#readExceptionFromParcel()).
            result.exception = new IllegalStateException("Failed to load root document.");
            mInjector.getModel().update(result);
            return;
        }

        mActivity.getLoaderManager().restartLoader(LOADER_ID, null, mBindings);
    }

    protected final boolean launchToDocument(Uri uri) {
        // We don't support launching to a document in an archive.
        if (!Providers.isArchiveUri(uri)) {
@@ -385,6 +426,65 @@ public abstract class AbstractActionHandler<T extends Activity & CommonAddons>
        return mSelectionMgr.getSelection(new Selection());
    }

    public ActionHandler reset(DirectoryReloadLock reloadLock) {
        mDirectoryReloadLock = reloadLock;
        mActivity.getLoaderManager().destroyLoader(LOADER_ID);
        return this;
    }

    private final class LoaderBindings implements LoaderCallbacks<DirectoryResult> {

        @Override
        public Loader<DirectoryResult> onCreateLoader(int id, Bundle args) {
            Context context = mActivity;

            if (mState.stack.isRecents()) {

                if (DEBUG) Log.d(TAG, "Creating new loader recents.");
                return new RecentsLoader(context, mRoots, mState, mInjector.features);

            } else {

                Uri contentsUri = mSearchMgr.isSearching()
                        ? DocumentsContract.buildSearchDocumentsUri(
                            mState.stack.getRoot().authority,
                            mState.stack.getRoot().rootId,
                            mSearchMgr.getCurrentSearch())
                        : DocumentsContract.buildChildDocumentsUri(
                                mState.stack.peek().authority,
                                mState.stack.peek().documentId);

                if (mInjector.config.managedModeEnabled(mState.stack)) {
                    contentsUri = DocumentsContract.setManageMode(contentsUri);
                }

                if (DEBUG) Log.d(TAG,
                        "Creating new directory loader for: "
                                + DocumentInfo.debugString(mState.stack.peek()));

                return new DirectoryLoader(
                        context,
                        mState.stack.getRoot(),
                        mState.stack.peek(),
                        contentsUri,
                        mState.sortModel,
                        mDirectoryReloadLock,
                        mSearchMgr.isSearching());
            }
        }

        @Override
        public void onLoadFinished(Loader<DirectoryResult> loader, DirectoryResult result) {
            if (DEBUG) Log.d(TAG, "Loader has finished for: "
                    + DocumentInfo.debugString(mState.stack.peek()));
            assert(result != null);

            mInjector.getModel().update(result);
        }

        @Override
        public void onLoaderReset(Loader<DirectoryResult> loader) {}
    }
    /**
     * A class primarily for the support of isolating our tests
     * from our concrete activity implementations.
+6 −3
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@ import com.android.documentsui.base.DocumentInfo;
import com.android.documentsui.base.DocumentStack;
import com.android.documentsui.base.RootInfo;
import com.android.documentsui.dirlist.DocumentDetails;
import com.android.documentsui.dirlist.Model;

import javax.annotation.Nullable;

@@ -84,6 +83,8 @@ public interface ActionHandler {

    void showChooserForDoc(DocumentInfo doc);

    void openRootDocument(@Nullable DocumentInfo rootDoc);

    void openContainerDocument(DocumentInfo doc);

    void cutToClipboard();
@@ -107,9 +108,11 @@ public interface ActionHandler {
    void registerDisplayStateChangedListener(Runnable l);
    void unregisterDisplayStateChangedListener(Runnable l);

    void loadDocumentsForCurrentStack();

    /**
     * Allow action handler to be initialized in a new scope.
     * @return
     * @return this
     */
    <T extends ActionHandler> T reset(Model model);
    <T extends ActionHandler> T reset(DirectoryReloadLock reloadLock);
}
+6 −13
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@ import static com.android.documentsui.base.State.MODE_GRID;

import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@@ -32,7 +31,6 @@ import android.os.AsyncTask;
import android.os.Bundle;
import android.os.MessageQueue.IdleHandler;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Root;
import android.support.annotation.CallSuper;
import android.support.annotation.LayoutRes;
import android.support.annotation.Nullable;
@@ -52,7 +50,6 @@ import com.android.documentsui.base.State;
import com.android.documentsui.base.State.ViewMode;
import com.android.documentsui.dirlist.AnimationView;
import com.android.documentsui.dirlist.DirectoryFragment;
import com.android.documentsui.dirlist.DocumentsAdapter;
import com.android.documentsui.prefs.LocalPreferences;
import com.android.documentsui.prefs.PreferencesMonitor;
import com.android.documentsui.queries.DebugCommandProcessor;
@@ -155,7 +152,11 @@ public abstract class BaseActivity
             */
            @Override
            public void onSearchChanged(@Nullable String query) {
                reloadSearch(query);
                if (query != null) {
                    Metrics.logUserAction(BaseActivity.this, Metrics.USER_ACTION_SEARCH);
                }

                mInjector.actions.loadDocumentsForCurrentStack();
            }

            @Override
@@ -302,7 +303,7 @@ public abstract class BaseActivity
            new GetRootDocumentTask(
                    root,
                    this,
                    mInjector.actions::openContainerDocument)
                    mInjector.actions::openRootDocument)
                    .executeOnExecutor(getExecutorForCurrentDirectory());
        }
    }
@@ -405,14 +406,6 @@ public abstract class BaseActivity
        invalidateOptionsMenu();
    }

    private void reloadSearch(String query) {
        FragmentManager fm = getFragmentManager();
        RootInfo root = getCurrentRoot();
        DocumentInfo cwd = getCurrentDirectory();

        DirectoryFragment.reloadSearch(fm, root, cwd, query);
    }

    private final List<String> getExcludedAuthorities() {
        List<String> authorities = new ArrayList<>();
        if (getIntent().getBooleanExtra(DocumentsContract.EXTRA_EXCLUDE_SELF, false)) {
+2 −1
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.Handler;
import android.os.Looper;
import android.os.OperationCanceledException;
import android.os.RemoteException;
import android.provider.DocumentsContract.Document;
@@ -220,7 +221,7 @@ public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> {
        private final Runnable mContentChangedCallback;

        public LockingContentObserver(DirectoryReloadLock lock, Runnable contentChangedCallback) {
            super(new Handler());
            super(new Handler(Looper.getMainLooper()));
            mLock = lock;
            mContentChangedCallback = contentChangedCallback;
        }
+0 −1
Original line number Diff line number Diff line
@@ -30,7 +30,6 @@ import android.widget.TextView;
import com.android.documentsui.base.DocumentInfo;
import com.android.documentsui.base.Shared;
import com.android.documentsui.dirlist.IconHelper;
import com.android.documentsui.dirlist.Model;
import com.android.documentsui.selection.Selection;

import java.util.List;
Loading