diff options
author | 2019-03-11 16:31:57 +0800 | |
---|---|---|
committer | 2019-03-13 11:46:18 +0800 | |
commit | 166cd7c1636e12db42e1ab1b3a336f95843b694d (patch) | |
tree | c1e639ca9bec1cd8f3b5399b3f2e3a2d1f95140a | |
parent | a55472f607a88189ac21d6cd2cd7f766ff993895 (diff) |
Fix select behavior in picking mode
- Select all is no function when only folders in picking mode,
disable the menu to avoid coufuse users.
- Multi select region on folder is no function in picking mode,
it should not be hotspot at this situation.
Fix: 120817231
Fix: 124884267
Test: manual
Test: atest DocumentsUITests
Change-Id: I870e03fe58d7f935e925603fc5697beeb419d73c
9 files changed, 98 insertions, 6 deletions
diff --git a/src/com/android/documentsui/MenuManager.java b/src/com/android/documentsui/MenuManager.java index 755863bda..14691d357 100644 --- a/src/com/android/documentsui/MenuManager.java +++ b/src/com/android/documentsui/MenuManager.java @@ -100,6 +100,8 @@ public abstract class MenuManager { updateModePicker(menu.findItem(R.id.sub_menu_grid), menu.findItem(R.id.sub_menu_list)); } + public void updateModel(Model model) {} + /** * Called when we needs {@link MenuManager} to ask Android to show context menu for us. * {@link MenuManager} can choose to defeat this request. diff --git a/src/com/android/documentsui/Model.java b/src/com/android/documentsui/Model.java index afc85467b..9e258056a 100644 --- a/src/com/android/documentsui/Model.java +++ b/src/com/android/documentsui/Model.java @@ -111,7 +111,7 @@ public class Model { } @VisibleForTesting - protected void update(DirectoryResult result) { + public void update(DirectoryResult result) { assert(result != null); if (DEBUG) Log.i(TAG, "Updating model with new result set."); diff --git a/src/com/android/documentsui/dirlist/DirectoryFragment.java b/src/com/android/documentsui/dirlist/DirectoryFragment.java index dc45d19ff..22c5f322e 100644 --- a/src/com/android/documentsui/dirlist/DirectoryFragment.java +++ b/src/com/android/documentsui/dirlist/DirectoryFragment.java @@ -1121,6 +1121,7 @@ public class DirectoryFragment extends Fragment implements SwipeRefreshLayout.On mModel.doc != null ? mModel.doc.derivedUri : null); // For orientation changed case, sometimes the docs loading comes after the menu // update. We need to update the menu here to ensure the status is correct. + mInjector.menuManager.updateModel(mModel); mInjector.menuManager.updateOptionMenu(); mActivity.updateHeaderTitle(); diff --git a/src/com/android/documentsui/dirlist/DocumentHolder.java b/src/com/android/documentsui/dirlist/DocumentHolder.java index 41257cce9..263c5863d 100644 --- a/src/com/android/documentsui/dirlist/DocumentHolder.java +++ b/src/com/android/documentsui/dirlist/DocumentHolder.java @@ -31,8 +31,8 @@ import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; import androidx.recyclerview.widget.RecyclerView; import com.android.documentsui.base.Shared; +import com.android.documentsui.base.State; -import java.util.function.Consumer; import java.util.function.Function; import javax.annotation.Nullable; @@ -49,6 +49,8 @@ public abstract class DocumentHolder protected @Nullable String mModelId; + protected @State.ActionType int mAction; + // See #addKeyEventListener for details on the need for this field. private KeyboardEventListener<DocumentItemDetails> mKeyEventListener; @@ -99,6 +101,10 @@ public abstract class DocumentHolder setEnabledRecursive(itemView, enabled); } + public void setAction(@State.ActionType int action) { + mAction = action; + } + public void bindPreviewIcon(boolean show, Function<View, Boolean> clickCallback) {} @Override diff --git a/src/com/android/documentsui/dirlist/GridDirectoryHolder.java b/src/com/android/documentsui/dirlist/GridDirectoryHolder.java index 807af4dd8..e32a48b34 100644 --- a/src/com/android/documentsui/dirlist/GridDirectoryHolder.java +++ b/src/com/android/documentsui/dirlist/GridDirectoryHolder.java @@ -30,6 +30,7 @@ import android.widget.TextView; import com.android.documentsui.IconUtils; import com.android.documentsui.R; +import com.android.documentsui.base.State; import com.android.documentsui.ui.Views; final class GridDirectoryHolder extends DocumentHolder { @@ -73,7 +74,7 @@ final class GridDirectoryHolder extends DocumentHolder { @Override public boolean inSelectRegion(MotionEvent event) { - return Views.isEventOver(event, mIconLayout); + return mAction == State.ACTION_BROWSE ? Views.isEventOver(event, mIconLayout) : false; } /** diff --git a/src/com/android/documentsui/dirlist/ListDocumentHolder.java b/src/com/android/documentsui/dirlist/ListDocumentHolder.java index c26d80098..55b4ec050 100644 --- a/src/com/android/documentsui/dirlist/ListDocumentHolder.java +++ b/src/com/android/documentsui/dirlist/ListDocumentHolder.java @@ -34,6 +34,7 @@ import com.android.documentsui.R; import com.android.documentsui.base.DocumentInfo; import com.android.documentsui.base.Lookup; import com.android.documentsui.base.Shared; +import com.android.documentsui.base.State; import com.android.documentsui.roots.RootCursorWrapper; import com.android.documentsui.ui.Views; @@ -158,7 +159,8 @@ final class ListDocumentHolder extends DocumentHolder { @Override public boolean inSelectRegion(MotionEvent event) { - return Views.isEventOver(event, mIconLayout); + return (mDoc.isDirectory() && !(mAction == State.ACTION_BROWSE)) ? + false : Views.isEventOver(event, mIconLayout); } @Override diff --git a/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapter.java b/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapter.java index 0b6457102..da98ea62f 100644 --- a/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapter.java +++ b/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapter.java @@ -139,6 +139,7 @@ final class ModelBackedDocumentsAdapter extends DocumentsAdapter { } holder.setEnabled(enabled); holder.setSelected(mEnv.isSelected(modelId), false); + holder.setAction(mEnv.getDisplayState().action); holder.bindPreviewIcon(Shared.hasQuickViewer(mEnv.getContext()) && mEnv.getDisplayState().shouldShowPreview() && enabled, view -> mEnv.getActionHandler().previewItem(holder.getItemDetails())); diff --git a/src/com/android/documentsui/picker/MenuManager.java b/src/com/android/documentsui/picker/MenuManager.java index b1272d7f7..b9e68ece8 100644 --- a/src/com/android/documentsui/picker/MenuManager.java +++ b/src/com/android/documentsui/picker/MenuManager.java @@ -16,16 +16,21 @@ package com.android.documentsui.picker; +import static com.android.documentsui.base.DocumentInfo.getCursorString; import static com.android.documentsui.base.State.ACTION_CREATE; import static com.android.documentsui.base.State.ACTION_GET_CONTENT; import static com.android.documentsui.base.State.ACTION_OPEN; import static com.android.documentsui.base.State.ACTION_OPEN_TREE; import static com.android.documentsui.base.State.ACTION_PICK_COPY_DESTINATION; +import android.database.Cursor; +import android.provider.DocumentsContract.Document; import android.view.KeyboardShortcutGroup; import android.view.Menu; import android.view.MenuItem; +import com.android.documentsui.Model; +import com.android.documentsui.base.MimeTypes; import com.android.documentsui.base.State; import com.android.documentsui.queries.SearchViewManager; @@ -35,6 +40,8 @@ import com.android.documentsui.R; public final class MenuManager extends com.android.documentsui.MenuManager { + private boolean mOnlyDirectory; + public MenuManager(SearchViewManager searchManager, State displayState, DirectoryDetails dirDetails) { super(searchManager, displayState, dirDetails); @@ -63,6 +70,19 @@ public final class MenuManager extends com.android.documentsui.MenuManager { } @Override + public void updateModel(Model model) { + for (String id : model.getModelIds()) { + Cursor cursor = model.getItem(id); + String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE); + if (!MimeTypes.mimeMatches(Document.MIME_TYPE_DIR, docMimeType)) { + mOnlyDirectory = false; + return; + } + } + mOnlyDirectory = true; + } + + @Override protected void updateModePicker(MenuItem grid, MenuItem list) { // No display options in recent directories if (picking() && mDirDetails.isInRecents()) { @@ -75,8 +95,9 @@ public final class MenuManager extends com.android.documentsui.MenuManager { @Override protected void updateSelectAll(MenuItem selectAll) { - boolean enabled = mState.allowMultiple; - selectAll.setVisible(enabled); + boolean visible = mState.allowMultiple; + boolean enabled = visible && !mOnlyDirectory; + selectAll.setVisible(visible); selectAll.setEnabled(enabled); } diff --git a/tests/unit/com/android/documentsui/picker/MenuManagerTest.java b/tests/unit/com/android/documentsui/picker/MenuManagerTest.java index 2eaf7554f..8287e9f17 100644 --- a/tests/unit/com/android/documentsui/picker/MenuManagerTest.java +++ b/tests/unit/com/android/documentsui/picker/MenuManagerTest.java @@ -23,16 +23,22 @@ import static com.android.documentsui.base.State.ACTION_OPEN; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import android.database.MatrixCursor; +import android.provider.DocumentsContract.Document; import android.provider.DocumentsContract.Root; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import com.android.documentsui.DirectoryResult; +import com.android.documentsui.Model; import com.android.documentsui.R; import com.android.documentsui.base.DocumentInfo; import com.android.documentsui.base.RootInfo; import com.android.documentsui.base.State; +import com.android.documentsui.roots.RootCursorWrapper; import com.android.documentsui.testing.TestDirectoryDetails; +import com.android.documentsui.testing.TestFeatures; import com.android.documentsui.testing.TestMenu; import com.android.documentsui.testing.TestMenuItem; import com.android.documentsui.testing.TestSearchViewManager; @@ -278,6 +284,27 @@ public final class MenuManagerTest { subOptionList.assertInvisible(); } + + @Test + public void testOptionMenu_onlyContainer() { + state.allowMultiple = true; + mgr.updateModel(getTestModel(true)); + mgr.updateOptionMenu(testMenu); + + optionSelectAll.assertVisible(); + optionSelectAll.assertDisabled(); + } + + @Test + public void testOptionMenu_containerAndFile() { + state.allowMultiple = true; + mgr.updateModel(getTestModel(false)); + mgr.updateOptionMenu(testMenu); + + optionSelectAll.assertVisible(); + optionSelectAll.assertEnabled(); + } + @Test public void testContextMenu_EmptyArea() { dirDetails.hasItemsToPaste = false; @@ -465,4 +492,35 @@ public final class MenuManagerTest { rootEjectRoot.assertInvisible(); } + + private Model getTestModel(boolean onlyDirectory) { + String[] COLUMNS = new String[]{ + RootCursorWrapper.COLUMN_AUTHORITY, + Document.COLUMN_DOCUMENT_ID, + Document.COLUMN_FLAGS, + Document.COLUMN_DISPLAY_NAME, + Document.COLUMN_SIZE, + Document.COLUMN_LAST_MODIFIED, + Document.COLUMN_MIME_TYPE + }; + MatrixCursor c = new MatrixCursor(COLUMNS); + for (int i = 0; i < 3; ++i) { + MatrixCursor.RowBuilder row = c.newRow(); + row.add(Document.COLUMN_DOCUMENT_ID, Integer.toString(i)); + row.add(Document.COLUMN_MIME_TYPE, Document.MIME_TYPE_DIR); + } + + if (!onlyDirectory) { + MatrixCursor.RowBuilder row = c.newRow(); + row.add(Document.COLUMN_DOCUMENT_ID, "4"); + row.add(Document.COLUMN_MIME_TYPE, "image/jpg"); + } + + DirectoryResult r = new DirectoryResult(); + r.cursor = c; + Model model = new Model(new TestFeatures()); + model.update(r); + + return model; + } } |