From 76572d6f19f5635618a72e56014ca5a879b6a48d Mon Sep 17 00:00:00 2001 From: Tomasz Mikolajewski Date: Mon, 11 Apr 2016 11:06:16 +0900 Subject: [PATCH] Restrict selection to 1000 items in DocumentsUI. Bug: 27208679 Change-Id: I5e500724a3fb9af5b8f59e0c959523da5066b1fd --- packages/DocumentsUI/res/values/strings.xml | 5 +++ .../documentsui/QuickViewIntentBuilder.java | 10 ++--- .../src/com/android/documentsui/Shared.java | 5 +++ .../dirlist/DirectoryFragment.java | 39 ++++++++++++++++--- 4 files changed, 49 insertions(+), 10 deletions(-) diff --git a/packages/DocumentsUI/res/values/strings.xml b/packages/DocumentsUI/res/values/strings.xml index be21b55c4066e..e67cc8a06da27 100644 --- a/packages/DocumentsUI/res/values/strings.xml +++ b/packages/DocumentsUI/res/values/strings.xml @@ -247,4 +247,9 @@ Delete %1$d item? Delete %1$d items? + + Sorry, you can only select up to 1000 items at a time + + Could only select 1000 items diff --git a/packages/DocumentsUI/src/com/android/documentsui/QuickViewIntentBuilder.java b/packages/DocumentsUI/src/com/android/documentsui/QuickViewIntentBuilder.java index babde992a90bd..c78face9730a0 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/QuickViewIntentBuilder.java +++ b/packages/DocumentsUI/src/com/android/documentsui/QuickViewIntentBuilder.java @@ -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 diff --git a/packages/DocumentsUI/src/com/android/documentsui/Shared.java b/packages/DocumentsUI/src/com/android/documentsui/Shared.java index 1ba836a7fa4a6..07c3cdbcbec03 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/Shared.java +++ b/packages/DocumentsUI/src/com/android/documentsui/Shared.java @@ -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 { diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java index 8c073c9cc616c..297fbc784acd7 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java +++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java @@ -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 enabled = new ArrayList(); - for (String id : mAdapter.getModelIds()) { + // Exclude disabled files. + Set enabled = new HashSet(); + List 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); } }