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

Commit dd719e88 authored by Tomasz Mikolajewski's avatar Tomasz Mikolajewski Committed by android-build-merger
Browse files

Merge changes I5e500724,I40cfb12c into nyc-dev am: 0fb51357 am: 241e9fc0

am: 9aa18519

* commit '9aa18519':
  Restrict selection to 1000 items in DocumentsUI.
  Cancel band selection on directory change.

Change-Id: I88518e167cd06046888077ede90302c3b8fbdf1e
parents 6a5cb51b 9aa18519
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -247,4 +247,9 @@
        <item quantity="one">Delete <xliff:g id="count" example="1">%1$d</xliff:g> item?</item>
        <item quantity="other">Delete <xliff:g id="count" example="3">%1$d</xliff:g> items?</item>
    </plurals>
    <!-- Snackbar shown to users who wanted to select more than 1000 items (files or directories). -->
    <string name="too_many_selected">Sorry, you can only select up to 1000 items at a time</string>
    <!-- Snackbar shown to users who wanted to select all, but there were too many items (files or directories).
         Only the first 1000 items are selected in such case. -->
    <string name="too_many_in_select_all">Could only select 1000 items</string>
</resources>
+5 −5
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.documentsui;

import static com.android.documentsui.Shared.DEBUG;
import static com.android.documentsui.Shared.MAX_DOCS_IN_INTENT;
import static com.android.documentsui.model.DocumentInfo.getCursorString;

import android.content.ClipData;
@@ -46,7 +47,6 @@ import java.util.List;
final class QuickViewIntentBuilder {

    private static final String TAG = "QuickViewIntentBuilder";
    private static final int MAX_CLIP_ITEMS = 1000;

    private final DocumentInfo mDocument;
    private final Model mModel;
@@ -165,11 +165,11 @@ final class QuickViewIntentBuilder {
        int firstSibling;
        int lastSibling;
        if (documentLocation < uris.size() / 2) {
            firstSibling = Math.max(0, documentLocation - MAX_CLIP_ITEMS / 2);
            lastSibling = Math.min(uris.size() - 1, firstSibling + MAX_CLIP_ITEMS - 1);
            firstSibling = Math.max(0, documentLocation - MAX_DOCS_IN_INTENT / 2);
            lastSibling = Math.min(uris.size() - 1, firstSibling + MAX_DOCS_IN_INTENT - 1);
        } else {
            lastSibling = Math.min(uris.size() - 1, documentLocation + MAX_CLIP_ITEMS / 2);
            firstSibling = Math.max(0, lastSibling - MAX_CLIP_ITEMS + 1);
            lastSibling = Math.min(uris.size() - 1, documentLocation + MAX_DOCS_IN_INTENT / 2);
            firstSibling = Math.max(0, lastSibling - MAX_DOCS_IN_INTENT + 1);
        }

        if (DEBUG) Log.d(TAG, "Copmuted siblings from index: " + firstSibling
+5 −0
Original line number Diff line number Diff line
@@ -104,6 +104,11 @@ public final class Shared {
     */
    public static final String EXTRA_BENCHMARK = "com.android.documentsui.benchmark";

    /**
     * Maximum number of items in a Binder transaction packet.
     */
    public static final int MAX_DOCS_IN_INTENT = 1000;

    private static final Collator sCollator;

    static {
+34 −5
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.documentsui.dirlist;

import static com.android.documentsui.Shared.DEBUG;
import static com.android.documentsui.Shared.MAX_DOCS_IN_INTENT;
import static com.android.documentsui.State.MODE_GRID;
import static com.android.documentsui.State.MODE_LIST;
import static com.android.documentsui.State.SORT_ORDER_UNKNOWN;
@@ -108,9 +109,11 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * Display the documents inside a single directory.
@@ -475,8 +478,18 @@ public class DirectoryFragment extends Fragment

                final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
                final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
                if (!mTuner.canSelectType(docMimeType, docFlags)) {
                    return false;
                }

                return mTuner.canSelectType(docMimeType, docFlags);
                if (mSelected.size() >= MAX_DOCS_IN_INTENT) {
                    Snackbars.makeSnackbar(
                            getActivity(),
                            R.string.too_many_selected,
                            Snackbar.LENGTH_SHORT)
                            .show();
                    return false;
                }
            }
            return true;
        }
@@ -1108,9 +1121,17 @@ public class DirectoryFragment extends Fragment
    public void selectAllFiles() {
        Metrics.logUserAction(getContext(), Metrics.USER_ACTION_SELECT_ALL);

        // Exclude disabled files
        List<String> enabled = new ArrayList<String>();
        for (String id : mAdapter.getModelIds()) {
        // Exclude disabled files.
        Set<String> enabled = new HashSet<String>();
        List<String> modelIds = mAdapter.getModelIds();

        // Get the current selection.
        String[] alreadySelected = mSelectionManager.getSelection().getAll();
        for (String id : alreadySelected) {
           enabled.add(id);
        }

        for (String id : modelIds) {
            Cursor cursor = getModel().getItem(id);
            if (cursor == null) {
                Log.w(TAG, "Skipping selection. Can't obtain cursor for modeId: " + id);
@@ -1118,7 +1139,15 @@ public class DirectoryFragment extends Fragment
            }
            String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
            int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
            if (isDocumentEnabled(docMimeType, docFlags)) {
            if (mTuner.canSelectType(docMimeType, docFlags)) {
                if (enabled.size() >= MAX_DOCS_IN_INTENT) {
                    Snackbars.makeSnackbar(
                        getActivity(),
                        R.string.too_many_in_select_all,
                        Snackbar.LENGTH_SHORT)
                        .show();
                    break;
                }
                enabled.add(id);
            }
        }
+31 −3
Original line number Diff line number Diff line
@@ -154,6 +154,10 @@ public final class MultiSelectManager {
                        // Update the selection to remove any disappeared IDs.
                        mSelection.cancelProvisionalSelection();
                        mSelection.intersect(mModelIds);

                        if (mBandManager != null && mBandManager.isActive()) {
                            mBandManager.endBandSelect();
                        }
                    }

                    @Override
@@ -940,6 +944,10 @@ public final class MultiSelectManager {
         * Layout items are excluded from the GridModel.
         */
        boolean isLayoutItem(int adapterPosition);
        /**
         * Items may be in the adapter, but without an attached view.
         */
        boolean hasView(int adapterPosition);
    }

    /** Recycler view facade implementation backed by good ol' RecyclerView. */
@@ -1061,6 +1069,11 @@ public final class MultiSelectManager {
                    return true;
            }
        }

        @Override
        public boolean hasView(int pos) {
            return mView.findViewHolderForAdapterPosition(pos) != null;
        }
    }

    public interface Callback {
@@ -1473,10 +1486,14 @@ public final class MultiSelectManager {
         *     y-value.
         */
        void startSelection(Point relativeOrigin) {
            recordVisibleChildren();
            if (isEmpty()) {
                // The selection band logic works only if there is at least one visible child.
                return;
            }

            mIsActive = true;
            mPointer = mHelper.createAbsolutePoint(relativeOrigin);

            recordVisibleChildren();
            mRelativeOrigin = new RelativePoint(mPointer);
            mRelativePointer = new RelativePoint(mPointer);
            computeCurrentSelection();
@@ -1530,7 +1547,11 @@ public final class MultiSelectManager {
        private void recordVisibleChildren() {
            for (int i = 0; i < mHelper.getVisibleChildCount(); i++) {
                int adapterPosition = mHelper.getAdapterPositionAt(i);
                if (!mHelper.isLayoutItem(adapterPosition) &&
                // Sometimes the view is not attached, as we notify the multi selection manager
                // synchronously, while views are attached asynchronously. As a result items which
                // are in the adapter may not actually have a corresponding view (yet).
                if (mHelper.hasView(adapterPosition) &&
                        !mHelper.isLayoutItem(adapterPosition) &&
                        !mKnownPositions.get(adapterPosition)) {
                    mKnownPositions.put(adapterPosition, true);
                    recordItemData(mHelper.getAbsoluteRectForChildViewAt(i), adapterPosition);
@@ -1538,6 +1559,13 @@ public final class MultiSelectManager {
            }
        }

        /**
         * Checks if there are any recorded children.
         */
        private boolean isEmpty() {
            return mColumnBounds.size() == 0 || mRowBounds.size() == 0;
        }

        /**
         * Updates the limits lists and column map with the given item metadata.
         * @param absoluteChildRect The absolute rectangle for the child view being processed.
Loading