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

Commit 878b2717 authored by Steve McKay's avatar Steve McKay
Browse files

Extrac DocsUI selection manager.

DocsUI selection manager retains support for being reset.
This accommodation is in support of DocsUI's odd arrangement where
the SelectionManager is created at the activity level, but
shared with fragment instances each corresponding to the viewing of a single directory.
DefaultSelectionManager drops support for being reset. Instances are
now created in a fully valid state.

Bug: 64847011
Test: Passing.
Change-Id: Idaf61b2ec86cb699e90bcee25641f0e288c4e522
parent 53c8e803
Loading
Loading
Loading
Loading
+152 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 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.support.annotation.VisibleForTesting;
import android.support.v7.widget.RecyclerView;

import com.android.documentsui.selection.BandController;
import com.android.documentsui.selection.DefaultSelectionManager;
import com.android.documentsui.selection.Selection;
import com.android.documentsui.selection.SelectionManager;

import java.util.Set;

import javax.annotation.Nullable;

/**
 * DocumentsUI SelectManager implementation that creates delegate instances
 * each time reset is called.
 */
public final class DocsSelectionManager implements SelectionManager {

    private final @SelectionMode int mSelectionMode;
    private @Nullable DefaultSelectionManager mDelegate;

    public DocsSelectionManager(@SelectionMode int mode) {
        mSelectionMode = mode;
    }

    public SelectionManager reset(
            RecyclerView.Adapter<?> adapter,
            SelectionManager.Environment idLookup,
            SelectionManager.SelectionPredicate canSetState) {

        if (mDelegate != null) {
            mDelegate.clearSelection();
        }

        mDelegate = new DefaultSelectionManager(mSelectionMode, adapter, idLookup, canSetState);
        return this;
    }

    @Override
    public void bindContoller(BandController controller) {
        mDelegate.bindContoller(controller);
    }

    @Override
    public void addEventListener(EventListener listener) {
        mDelegate.addEventListener(listener);
    }

    @Override
    public boolean hasSelection() {
        return mDelegate.hasSelection();
    }

    @Override
    public Selection getSelection() {
        return mDelegate.getSelection();
    }

    @Override
    public Selection getSelection(Selection dest) {
        return mDelegate.getSelection(dest);
    }

    @Override
    @VisibleForTesting
    public void replaceSelection(Iterable<String> ids) {
        mDelegate.replaceSelection(ids);
    }

    @Override
    public void restoreSelection(Selection other) {
        mDelegate.restoreSelection(other);
    }

    @Override
    public boolean setItemsSelected(Iterable<String> ids, boolean selected) {
        return mDelegate.setItemsSelected(ids, selected);
    }

    @Override
    public void clearSelection() {
        mDelegate.clearSelection();
    }

    @Override
    public void toggleSelection(String modelId) {
        mDelegate.toggleSelection(modelId);
    }

    @Override
    public void startRangeSelection(int pos) {
        mDelegate.startRangeSelection(pos);
    }

    @Override
    public void snapRangeSelection(int pos) {
        mDelegate.snapRangeSelection(pos);
    }

    @Override
    public void snapProvisionalRangeSelection(int pos) {
        mDelegate.snapProvisionalRangeSelection(pos);
    }

    @Override
    public void formNewSelectionRange(int startPos, int endPos) {
        mDelegate.formNewSelectionRange(startPos, endPos);
    }

    @Override
    public void cancelProvisionalSelection() {
        mDelegate.cancelProvisionalSelection();
    }

    @Override
    public void setProvisionalSelection(Set<String> newSelection) {
        mDelegate.setProvisionalSelection(newSelection);
    }

    @Override
    public void endRangeSelection() {
        mDelegate.endRangeSelection();
    }

    @Override
    public boolean isRangeSelectionActive() {
        return mDelegate.isRangeSelectionActive();
    }

    @Override
    public void setSelectionRangeBegin(int position) {
        mDelegate.setSelectionRangeBegin(position);
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -69,7 +69,7 @@ public class Injector<T extends ActionHandler> {
    public FocusManager focusManager;

    @ContentScoped
    public SelectionManager selectionMgr;
    public DocsSelectionManager selectionMgr;

    private final Model mModel;

+5 −6
Original line number Diff line number Diff line
@@ -21,14 +21,13 @@ import static com.android.documentsui.OperationDialogFragment.DIALOG_TYPE_UNKNOW
import android.app.ActivityManager.TaskDescription;
import android.app.FragmentManager;
import android.content.Intent;
import android.content.Context;
import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.CallSuper;
@@ -39,6 +38,7 @@ import android.view.MenuItem;

import com.android.documentsui.ActionModeController;
import com.android.documentsui.BaseActivity;
import com.android.documentsui.DocsSelectionManager;
import com.android.documentsui.DocumentsApplication;
import com.android.documentsui.FocusManager;
import com.android.documentsui.Injector;
@@ -57,7 +57,6 @@ import com.android.documentsui.clipping.DocumentClipper;
import com.android.documentsui.dirlist.AnimationView.AnimationType;
import com.android.documentsui.dirlist.DirectoryFragment;
import com.android.documentsui.prefs.ScopedPreferences;
import com.android.documentsui.selection.DefaultSelectionManager;
import com.android.documentsui.selection.SelectionManager;
import com.android.documentsui.services.FileOperationService;
import com.android.documentsui.sidebar.RootsFragment;
@@ -106,7 +105,7 @@ public class FilesActivity extends BaseActivity implements ActionHandler.Addons
        super.onCreate(icicle);

        DocumentClipper clipper = DocumentsApplication.getDocumentClipper(this);
        mInjector.selectionMgr = new DefaultSelectionManager(SelectionManager.MODE_MULTIPLE);
        mInjector.selectionMgr = new DocsSelectionManager(SelectionManager.MODE_MULTIPLE);

        mInjector.focusManager = new FocusManager(
                mInjector.features,
+2 −2
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import android.view.Menu;

import com.android.documentsui.ActionModeController;
import com.android.documentsui.BaseActivity;
import com.android.documentsui.DocsSelectionManager;
import com.android.documentsui.DocumentsApplication;
import com.android.documentsui.FocusManager;
import com.android.documentsui.Injector;
@@ -49,7 +50,6 @@ import com.android.documentsui.base.Shared;
import com.android.documentsui.base.State;
import com.android.documentsui.dirlist.DirectoryFragment;
import com.android.documentsui.prefs.ScopedPreferences;
import com.android.documentsui.selection.DefaultSelectionManager;
import com.android.documentsui.selection.SelectionManager;
import com.android.documentsui.services.FileOperationService;
import com.android.documentsui.sidebar.RootsFragment;
@@ -95,7 +95,7 @@ public class PickActivity extends BaseActivity implements ActionHandler.Addons {

        super.onCreate(icicle);

        mInjector.selectionMgr = new DefaultSelectionManager(
        mInjector.selectionMgr = new DocsSelectionManager(
                mState.allowMultiple
                        ? SelectionManager.MODE_MULTIPLE
                        : SelectionManager.MODE_SINGLE);
+14 −26
Original line number Diff line number Diff line
@@ -38,33 +38,20 @@ import javax.annotation.Nullable;
public final class DefaultSelectionManager implements SelectionManager {

    private final Selection mSelection = new Selection();

    private final List<SelectionManager.EventListener> mEventListeners = new ArrayList<>(1);
    private final RecyclerView.Adapter<?> mAdapter;
    private final SelectionManager.Environment mIdLookup;
    private final boolean mSingleSelect;
    private final SelectionPredicate mCanSetState;
    private final RecyclerView.AdapterDataObserver mAdapterObserver;

    private @Nullable RecyclerView.Adapter<?> mAdapter;
    private @Nullable SelectionManager.Environment mIdLookup;
    private @Nullable Range mRanger;
    private boolean mSingleSelect;

    private RecyclerView.AdapterDataObserver mAdapterObserver;
    private SelectionManager.SelectionPredicate mCanSetState;

    public DefaultSelectionManager(@SelectionMode int mode) {
        mSingleSelect = mode == MODE_SINGLE;
    }

    @Override
    public SelectionManager reset(
    public DefaultSelectionManager(
            @SelectionMode int mode,
            RecyclerView.Adapter<?> adapter,
            SelectionManager.Environment idLookup,
            SelectionManager.SelectionPredicate canSetState) {

        mEventListeners.clear();
        if (mAdapter != null && mAdapterObserver != null) {
            mAdapter.unregisterAdapterDataObserver(mAdapterObserver);
        }

        clearSelectionQuietly();
            SelectionPredicate canSetState) {

        assert adapter != null;
        assert idLookup != null;
@@ -74,6 +61,8 @@ public final class DefaultSelectionManager implements SelectionManager {
        mIdLookup = idLookup;
        mCanSetState = canSetState;

        mSingleSelect = mode == MODE_SINGLE;

        mAdapterObserver = new RecyclerView.AdapterDataObserver() {

            private List<String> mModelIds;
@@ -115,7 +104,6 @@ public final class DefaultSelectionManager implements SelectionManager {
        };

        mAdapter.registerAdapterDataObserver(mAdapterObserver);
        return this;
    }

    @Override
@@ -372,7 +360,7 @@ public final class DefaultSelectionManager implements SelectionManager {
        return true;
    }

    boolean canSetState(String id, boolean nextState) {
    private boolean canSetState(String id, boolean nextState) {
        return mCanSetState.test(id, nextState);
    }

@@ -397,7 +385,7 @@ public final class DefaultSelectionManager implements SelectionManager {
     * Notifies registered listeners when the selection status of a single item
     * (identified by {@code position}) changes.
     */
    void notifyItemStateChanged(String id, boolean selected) {
    private void notifyItemStateChanged(String id, boolean selected) {
        assert id != null;
        int lastListener = mEventListeners.size() - 1;
        for (int i = lastListener; i >= 0; i--) {
@@ -412,7 +400,7 @@ public final class DefaultSelectionManager implements SelectionManager {
     * is complete, e.g. clearingSelection, or updating the single
     * selection from one item to another.
     */
    void notifySelectionChanged() {
    private void notifySelectionChanged() {
        int lastListener = mEventListeners.size() - 1;
        for (int i = lastListener; i > -1; i--) {
            mEventListeners.get(i).onSelectionChanged();
@@ -433,7 +421,7 @@ public final class DefaultSelectionManager implements SelectionManager {
        }
    }

    void updateForRange(int begin, int end, boolean selected, @RangeType int type) {
    private void updateForRange(int begin, int end, boolean selected, @RangeType int type) {
        switch (type) {
            case RANGE_REGULAR:
                updateForRegularRange(begin, end, selected);
Loading