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

Commit 0c375989 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Migrate to use RecyclerView-Selection library

Test: atest DocumentsUITests
Bug: 110482929
Change-Id: Icb99520ac48d120b8bed0ce461c5e4f2ff885c18
parent d0193072
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -10,7 +10,8 @@ LOCAL_STATIC_ANDROID_LIBRARIES := \
        androidx.legacy_legacy-support-v13 \
        androidx.design_design \
        androidx.transition_transition \
        androidx.recyclerview_recyclerview
        androidx.recyclerview_recyclerview \
        androidx.recyclerview_recyclerview-selection

LOCAL_USE_AAPT2 := true

+9 −9
Original line number Diff line number Diff line
@@ -34,11 +34,15 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.Parcelable;
import android.provider.DocumentsContract;
import androidx.annotation.VisibleForTesting;
import android.util.Log;
import android.util.Pair;
import android.view.DragEvent;

import androidx.annotation.VisibleForTesting;
import androidx.recyclerview.selection.ItemDetailsLookup.ItemDetails;
import androidx.recyclerview.selection.MutableSelection;
import androidx.recyclerview.selection.SelectionTracker;

import com.android.documentsui.AbstractActionHandler.CommonAddons;
import com.android.documentsui.LoadDocStackTask.LoadDocStackCallback;
import com.android.documentsui.base.BooleanConsumer;
@@ -57,10 +61,6 @@ import com.android.documentsui.queries.SearchViewManager;
import com.android.documentsui.roots.GetRootDocumentTask;
import com.android.documentsui.roots.LoadRootTask;
import com.android.documentsui.roots.ProvidersAccess;
import com.android.documentsui.selection.ContentLock;
import com.android.documentsui.selection.MutableSelection;
import com.android.documentsui.selection.SelectionHelper;
import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
import com.android.documentsui.sidebar.EjectRootTask;
import com.android.documentsui.ui.Snackbars;

@@ -93,7 +93,7 @@ public abstract class AbstractActionHandler<T extends Activity & CommonAddons>
    protected final ProvidersAccess mProviders;
    protected final DocumentsAccess mDocs;
    protected final FocusHandler mFocusHandler;
    protected final SelectionHelper mSelectionMgr;
    protected final SelectionTracker<String> mSelectionMgr;
    protected final SearchViewManager mSearchMgr;
    protected final Lookup<String, Executor> mExecutors;
    protected final Injector<?> mInjector;
@@ -227,7 +227,7 @@ public abstract class AbstractActionHandler<T extends Activity & CommonAddons>
    }

    @Override
    public boolean openItem(ItemDetails doc, @ViewType int type, @ViewType int fallback) {
    public boolean openItem(ItemDetails<String> doc, @ViewType int type, @ViewType int fallback) {
        throw new UnsupportedOperationException("Can't open document.");
    }

@@ -533,8 +533,8 @@ public abstract class AbstractActionHandler<T extends Activity & CommonAddons>
        loadRoot(Shared.getDefaultRootUri(mActivity));
    }

    protected MutableSelection getStableSelection() {
        MutableSelection selection = new MutableSelection();
    protected MutableSelection<String> getStableSelection() {
        MutableSelection<String> selection = new MutableSelection<>();
        mSelectionMgr.copySelection(selection);
        return selection;
    }
+6 −3
Original line number Diff line number Diff line
@@ -24,12 +24,12 @@ import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.view.DragEvent;

import androidx.recyclerview.selection.ItemDetailsLookup.ItemDetails;

import com.android.documentsui.base.BooleanConsumer;
import com.android.documentsui.base.DocumentInfo;
import com.android.documentsui.base.DocumentStack;
import com.android.documentsui.base.RootInfo;
import com.android.documentsui.selection.ContentLock;
import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -37,6 +37,9 @@ import java.util.function.Consumer;

import javax.annotation.Nullable;

/**
 * Interface to handle action for document.
 */
public interface ActionHandler {

    @IntDef({
@@ -110,7 +113,7 @@ public interface ActionHandler {
     * If container, then opens the container, otherwise views using the specified type of view.
     * If the primary view type is unavailable, then fallback to the alternative type of view.
     */
    boolean openItem(ItemDetails doc, @ViewType int type, @ViewType int fallback);
    boolean openItem(ItemDetails<String> doc, @ViewType int type, @ViewType int fallback);

    /**
     * This is called when user hovers over a doc for enough time during a drag n' drop, to open a
+8 −7
Original line number Diff line number Diff line
@@ -31,33 +31,34 @@ import android.view.View;
import com.android.documentsui.MenuManager.SelectionDetails;
import com.android.documentsui.base.EventHandler;
import com.android.documentsui.base.Menus;
import com.android.documentsui.selection.Selection;
import com.android.documentsui.selection.SelectionHelper;
import com.android.documentsui.selection.SelectionHelper.SelectionObserver;
import com.android.documentsui.ui.MessageBuilder;

import androidx.recyclerview.selection.MutableSelection;
import androidx.recyclerview.selection.SelectionTracker;
import androidx.recyclerview.selection.SelectionTracker.SelectionObserver;

/**
 * A controller that listens to selection changes and manages life cycles of action modes.
 */
public class ActionModeController extends SelectionObserver
public class ActionModeController extends SelectionObserver<String>
        implements ActionMode.Callback, ActionModeAddons {

    private static final String TAG = "ActionModeController";

    private final Activity mActivity;
    private final SelectionHelper mSelectionMgr;
    private final SelectionTracker<String> mSelectionMgr;
    private final MenuManager mMenuManager;
    private final MessageBuilder mMessages;

    private final ContentScope mScope = new ContentScope();
    private final Selection mSelected = new Selection();
    private final MutableSelection<String> mSelected = new MutableSelection<>();

    private @Nullable ActionMode mActionMode;
    private @Nullable Menu mMenu;

    public ActionModeController(
            Activity activity,
            SelectionHelper selectionMgr,
            SelectionTracker<String> selectionMgr,
            MenuManager menuManager,
            MessageBuilder messages) {

+5 −41
Original line number Diff line number Diff line
@@ -16,8 +16,8 @@

package com.android.documentsui;

import static com.android.documentsui.base.SharedMinimal.DEBUG;
import static com.android.documentsui.base.Shared.EXTRA_BENCHMARK;
import static com.android.documentsui.base.SharedMinimal.DEBUG;
import static com.android.documentsui.base.State.MODE_GRID;

import android.app.Activity;
@@ -31,9 +31,6 @@ import android.os.Bundle;
import android.os.MessageQueue.IdleHandler;
import android.preference.PreferenceManager;
import android.provider.DocumentsContract;
import androidx.annotation.CallSuper;
import androidx.annotation.LayoutRes;
import androidx.annotation.VisibleForTesting;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
@@ -41,6 +38,10 @@ import android.view.MenuItem;
import android.view.View;
import android.widget.Toolbar;

import androidx.annotation.CallSuper;
import androidx.annotation.LayoutRes;
import androidx.annotation.VisibleForTesting;

import com.android.documentsui.AbstractActionHandler.CommonAddons;
import com.android.documentsui.Injector.Injected;
import com.android.documentsui.NavigationViewManager.Breadcrumb;
@@ -60,7 +61,6 @@ import com.android.documentsui.queries.CommandInterceptor;
import com.android.documentsui.queries.SearchViewManager;
import com.android.documentsui.queries.SearchViewManager.SearchManagerListener;
import com.android.documentsui.roots.ProvidersCache;
import com.android.documentsui.selection.Selection;
import com.android.documentsui.sidebar.RootsFragment;
import com.android.documentsui.sorting.SortController;
import com.android.documentsui.sorting.SortModel;
@@ -82,7 +82,6 @@ public abstract class BaseActivity
    @Injected
    protected Injector<?> mInjector;

    protected @Nullable RetainedState mRetainedState;
    protected ProvidersCache mProviders;
    protected DocumentsAccess mDocs;
    protected DrawerController mDrawer;
@@ -133,10 +132,6 @@ public abstract class BaseActivity
        mDrawer = DrawerController.create(this, mInjector.config);
        Metrics.logActivityLaunch(this, mState, intent);

        // we're really interested in retainining state in our very complex
        // DirectoryFragment. So we do a little code yoga to extend
        // support to that fragment.
        mRetainedState = (RetainedState) getLastNonConfigurationInstance();
        mProviders = DocumentsApplication.getProvidersCache(this);
        mDocs = DocumentsAccess.create(this);

@@ -523,29 +518,6 @@ public abstract class BaseActivity
        mSearchManager.onSaveInstanceState(state);
    }

    @Override
    protected void onRestoreInstanceState(Bundle state) {
        super.onRestoreInstanceState(state);
    }

    /**
     * Delegate ths call to the current fragment so it can save selection.
     * Feel free to expand on this with other useful state.
     */
    @Override
    public RetainedState onRetainNonConfigurationInstance() {
        RetainedState retained = new RetainedState();
        DirectoryFragment fragment = DirectoryFragment.get(getFragmentManager());
        if (fragment != null) {
            fragment.retainState(retained);
        }
        return retained;
    }

    public @Nullable RetainedState getRetainedState() {
        return mRetainedState;
    }

    @Override
    public boolean isSearchExpanded() {
        return mSearchManager.isExpanded();
@@ -662,14 +634,6 @@ public abstract class BaseActivity
        });
    }

    public static final class RetainedState {
        public @Nullable Selection selection;

        public boolean hasSelection() {
            return selection != null;
        }
    }

    @VisibleForTesting
    protected interface EventListener {
        /**
Loading