summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Erfan Norozi <erfanio@google.com> 2024-12-19 14:00:41 +1100
committer Erfan Norozi <erfanio@google.com> 2025-01-16 14:15:01 +1100
commit05e57300f2d12992adcda6f7bdbc2179cdcd6265 (patch)
tree23fdd80b340d04b78c8358dfb7060a9aa425a9d9
parentb3714e467f5df8c061218f5b6bc4e8b128c5129c (diff)
Add "Open" to context menu when a single file is selected
The open context has a slightly different behaviour to normal click. Normal click does a ACTION_PREVIEW, fallback=ACTION_VIEW but the context menu does a ACTION_VIEW without a fallback. Reusing an existing menu item which is unused. This was disabled for * picker in http://ag/4269998 * files in http://ag/4056064 Bug: 384607914 Flag: com.android.documentsui.flags.desktop_file_handling Test: Unit tests and manual testing Change-Id: I60b7a6a1cfaf0fe5f2b534341296a7c6322f4371
-rw-r--r--src/com/android/documentsui/AbstractActionHandler.java5
-rw-r--r--src/com/android/documentsui/ActionHandler.java6
-rw-r--r--src/com/android/documentsui/MenuManager.java2
-rw-r--r--src/com/android/documentsui/dirlist/DirectoryFragment.java27
-rw-r--r--src/com/android/documentsui/dirlist/SelectionMetadata.java2
-rw-r--r--src/com/android/documentsui/files/ActionHandler.java6
-rw-r--r--src/com/android/documentsui/files/MenuManager.java9
-rw-r--r--tests/common/com/android/documentsui/testing/TestSelectionDetails.java6
-rw-r--r--tests/unit/com/android/documentsui/files/ActionHandlerTest.java15
-rw-r--r--tests/unit/com/android/documentsui/files/MenuManagerTest.java32
10 files changed, 97 insertions, 13 deletions
diff --git a/src/com/android/documentsui/AbstractActionHandler.java b/src/com/android/documentsui/AbstractActionHandler.java
index b11567344..da599d47f 100644
--- a/src/com/android/documentsui/AbstractActionHandler.java
+++ b/src/com/android/documentsui/AbstractActionHandler.java
@@ -252,6 +252,11 @@ public abstract class AbstractActionHandler<T extends FragmentActivity & CommonA
}
@Override
+ public void openDocumentViewOnly(DocumentInfo doc) {
+ throw new UnsupportedOperationException("Open doc not supported!");
+ }
+
+ @Override
public void showInspector(DocumentInfo doc) {
throw new UnsupportedOperationException("Can't open properties.");
}
diff --git a/src/com/android/documentsui/ActionHandler.java b/src/com/android/documentsui/ActionHandler.java
index 15124eb33..c66a7e78c 100644
--- a/src/com/android/documentsui/ActionHandler.java
+++ b/src/com/android/documentsui/ActionHandler.java
@@ -129,6 +129,12 @@ public interface ActionHandler {
boolean openItem(ItemDetails<String> doc, @ViewType int type, @ViewType int fallback);
/**
+ * Similar to openItem but takes DocumentInfo instead of DocumentItemDetails and uses
+ * VIEW_TYPE_VIEW with no fallback.
+ */
+ void openDocumentViewOnly(DocumentInfo doc);
+
+ /**
* This is called when user hovers over a doc for enough time during a drag n' drop, to open a
* folder that accepts drop. We should only open a container that's not an archive, since archives
* do not accept dropping.
diff --git a/src/com/android/documentsui/MenuManager.java b/src/com/android/documentsui/MenuManager.java
index 78339862b..2d1e2a59a 100644
--- a/src/com/android/documentsui/MenuManager.java
+++ b/src/com/android/documentsui/MenuManager.java
@@ -427,7 +427,7 @@ public abstract class MenuManager {
boolean canExtract();
- boolean canOpenWith();
+ boolean canOpen();
boolean canViewInOwner();
}
diff --git a/src/com/android/documentsui/dirlist/DirectoryFragment.java b/src/com/android/documentsui/dirlist/DirectoryFragment.java
index 165599f71..43fc91e3a 100644
--- a/src/com/android/documentsui/dirlist/DirectoryFragment.java
+++ b/src/com/android/documentsui/dirlist/DirectoryFragment.java
@@ -21,6 +21,7 @@ import static com.android.documentsui.base.SharedMinimal.DEBUG;
import static com.android.documentsui.base.SharedMinimal.VERBOSE;
import static com.android.documentsui.base.State.MODE_GRID;
import static com.android.documentsui.base.State.MODE_LIST;
+import static com.android.documentsui.flags.Flags.desktopFileHandling;
import android.app.ActivityManager;
import android.content.BroadcastReceiver;
@@ -924,7 +925,17 @@ public class DirectoryFragment extends Fragment implements SwipeRefreshLayout.On
mSelectionMgr.copySelection(selection);
final int id = item.getItemId();
- if (id == R.id.action_menu_select || id == R.id.dir_menu_open) {
+ if (desktopFileHandling() && id == R.id.dir_menu_open) {
+ // On desktop, "open" is displayed in file management mode (i.e. `files.MenuManager`).
+ // This menu item behaves the same as double click on the menu item which is handled by
+ // onItemActivated but since onItemActivated requires a RecylcerView ItemDetails, we're
+ // using viewDocument that takes a Selection.
+ viewDocument(selection);
+ return true;
+ } else if (id == R.id.action_menu_select || id == R.id.dir_menu_open) {
+ // Note: this code path is never executed for `dir_menu_open`. The menu item is always
+ // hidden unless the desktopFileHandling flag is enabled, in which case the menu item
+ // will be handled by the condition above.
openDocuments(selection);
mActionModeController.finishActionMode();
return true;
@@ -1082,6 +1093,20 @@ public class DirectoryFragment extends Fragment implements SwipeRefreshLayout.On
mActions.showChooserForDoc(doc);
}
+ private void viewDocument(final Selection<String> selected) {
+ Metrics.logUserAction(MetricConsts.USER_ACTION_OPEN);
+
+ if (selected.isEmpty()) {
+ return;
+ }
+
+ assert selected.size() == 1;
+ DocumentInfo doc =
+ DocumentInfo.fromDirectoryCursor(mModel.getItem(selected.iterator().next()));
+
+ mActions.openDocumentViewOnly(doc);
+ }
+
private void transferDocuments(
final Selection<String> selected, @Nullable DocumentStack destination,
final @OpType int mode) {
diff --git a/src/com/android/documentsui/dirlist/SelectionMetadata.java b/src/com/android/documentsui/dirlist/SelectionMetadata.java
index 3abc3e190..74b6061b3 100644
--- a/src/com/android/documentsui/dirlist/SelectionMetadata.java
+++ b/src/com/android/documentsui/dirlist/SelectionMetadata.java
@@ -168,7 +168,7 @@ public class SelectionMetadata extends SelectionObserver<String>
}
@Override
- public boolean canOpenWith() {
+ public boolean canOpen() {
return size() == 1 && mDirectoryCount == 0 && mInArchiveCount == 0 && mPartialCount == 0;
}
}
diff --git a/src/com/android/documentsui/files/ActionHandler.java b/src/com/android/documentsui/files/ActionHandler.java
index 1fa771178..56eef8737 100644
--- a/src/com/android/documentsui/files/ActionHandler.java
+++ b/src/com/android/documentsui/files/ActionHandler.java
@@ -223,6 +223,12 @@ public class ActionHandler<T extends FragmentActivity & AbstractActionHandler.Co
}
@Override
+ public void openDocumentViewOnly(DocumentInfo doc) {
+ mInjector.searchManager.recordHistory();
+ openDocument(doc, VIEW_TYPE_REGULAR, VIEW_TYPE_NONE);
+ }
+
+ @Override
public void springOpenDirectory(DocumentInfo doc) {
assert(doc.isDirectory());
mActionModeAddons.finishActionMode();
diff --git a/src/com/android/documentsui/files/MenuManager.java b/src/com/android/documentsui/files/MenuManager.java
index 742bc9739..3e2e00feb 100644
--- a/src/com/android/documentsui/files/MenuManager.java
+++ b/src/com/android/documentsui/files/MenuManager.java
@@ -16,6 +16,8 @@
package com.android.documentsui.files;
+import static com.android.documentsui.flags.Flags.desktopFileHandling;
+
import android.content.Context;
import android.content.res.Resources;
import android.net.Uri;
@@ -161,7 +163,12 @@ public final class MenuManager extends com.android.documentsui.MenuManager {
@Override
protected void updateOpenWith(MenuItem openWith, SelectionDetails selectionDetails) {
- Menus.setEnabledAndVisible(openWith, selectionDetails.canOpenWith());
+ Menus.setEnabledAndVisible(openWith, selectionDetails.canOpen());
+ }
+
+ @Override
+ protected void updateOpenInContextMenu(MenuItem open, SelectionDetails selectionDetails) {
+ Menus.setEnabledAndVisible(open, desktopFileHandling() && selectionDetails.canOpen());
}
@Override
diff --git a/tests/common/com/android/documentsui/testing/TestSelectionDetails.java b/tests/common/com/android/documentsui/testing/TestSelectionDetails.java
index c63fdee59..e798174f8 100644
--- a/tests/common/com/android/documentsui/testing/TestSelectionDetails.java
+++ b/tests/common/com/android/documentsui/testing/TestSelectionDetails.java
@@ -32,7 +32,7 @@ public class TestSelectionDetails implements SelectionDetails {
public boolean containFiles;
public boolean canPasteInto;
public boolean canExtract;
- public boolean canOpenWith;
+ public boolean canOpen;
public boolean canViewInOwner;
@Override
@@ -76,8 +76,8 @@ public class TestSelectionDetails implements SelectionDetails {
}
@Override
- public boolean canOpenWith() {
- return canOpenWith;
+ public boolean canOpen() {
+ return canOpen;
}
@Override
diff --git a/tests/unit/com/android/documentsui/files/ActionHandlerTest.java b/tests/unit/com/android/documentsui/files/ActionHandlerTest.java
index 3de1a8ca7..a45778ecc 100644
--- a/tests/unit/com/android/documentsui/files/ActionHandlerTest.java
+++ b/tests/unit/com/android/documentsui/files/ActionHandlerTest.java
@@ -460,6 +460,21 @@ public class ActionHandlerTest {
}
@Test
+ public void testDocumentContextMenuOpen() throws Exception {
+ mActivity.resources.setQuickViewerPackage("corptropolis.viewer");
+ mActivity.currentRoot = TestProvidersAccess.HOME;
+
+ // Test normal picking (i.e. double click) behaviour will quick view
+ mHandler.openDocument(TestEnv.FILE_GIF, ActionHandler.VIEW_TYPE_PREVIEW,
+ ActionHandler.VIEW_TYPE_REGULAR);
+ mActivity.assertActivityStarted(Intent.ACTION_QUICK_VIEW);
+
+ // And verify open via context menu will view instead
+ mHandler.openDocumentViewOnly(TestEnv.FILE_GIF);
+ mActivity.assertActivityStarted(Intent.ACTION_VIEW);
+ }
+
+ @Test
@DisableFlags({Flags.FLAG_DESKTOP_FILE_HANDLING})
public void testShowChooser() throws Exception {
mActivity.currentRoot = TestProvidersAccess.DOWNLOADS;
diff --git a/tests/unit/com/android/documentsui/files/MenuManagerTest.java b/tests/unit/com/android/documentsui/files/MenuManagerTest.java
index 02988d62f..b869619a3 100644
--- a/tests/unit/com/android/documentsui/files/MenuManagerTest.java
+++ b/tests/unit/com/android/documentsui/files/MenuManagerTest.java
@@ -21,6 +21,9 @@ import static junit.framework.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import android.net.Uri;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.DocumentsContract.Document;
import android.provider.DocumentsContract.Root;
@@ -35,6 +38,7 @@ import com.android.documentsui.base.RootInfo;
import com.android.documentsui.base.State;
import com.android.documentsui.base.UserId;
import com.android.documentsui.dirlist.TestData;
+import com.android.documentsui.flags.Flags;
import com.android.documentsui.testing.TestDirectoryDetails;
import com.android.documentsui.testing.TestEnv;
import com.android.documentsui.testing.TestFeatures;
@@ -45,6 +49,7 @@ import com.android.documentsui.testing.TestSearchViewManager;
import com.android.documentsui.testing.TestSelectionDetails;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -123,6 +128,9 @@ public final class MenuManagerTest {
private int mFilesCount;
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
@Before
public void setUp() {
testMenu = TestMenu.create();
@@ -388,7 +396,7 @@ public final class MenuManagerTest {
@Test
public void testActionMenu_CanOpenWith() {
- selectionDetails.canOpenWith = true;
+ selectionDetails.canOpen = true;
mgr.updateActionMenu(testMenu, selectionDetails);
actionModeOpenWith.assertEnabledAndVisible();
@@ -396,7 +404,7 @@ public final class MenuManagerTest {
@Test
public void testActionMenu_NoOpenWith() {
- selectionDetails.canOpenWith = false;
+ selectionDetails.canOpen = false;
mgr.updateActionMenu(testMenu, selectionDetails);
actionModeOpenWith.assertDisabledAndInvisible();
@@ -590,16 +598,28 @@ public final class MenuManagerTest {
}
@Test
- public void testContextMenu_OnFile_CanOpenWith() {
- selectionDetails.canOpenWith = true;
+ @DisableFlags({Flags.FLAG_DESKTOP_FILE_HANDLING})
+ public void testContextMenu_OnFile_CanOpen() {
+ selectionDetails.canOpen = true;
+ mgr.updateContextMenuForFiles(testMenu, selectionDetails);
+ dirOpen.assertDisabledAndInvisible();
+ dirOpenWith.assertEnabledAndVisible();
+ }
+
+ @Test
+ @EnableFlags({Flags.FLAG_DESKTOP_FILE_HANDLING})
+ public void testContextMenu_OnFile_CanOpenDesktop() {
+ selectionDetails.canOpen = true;
mgr.updateContextMenuForFiles(testMenu, selectionDetails);
+ dirOpen.assertEnabledAndVisible();
dirOpenWith.assertEnabledAndVisible();
}
@Test
- public void testContextMenu_OnFile_NoOpenWith() {
- selectionDetails.canOpenWith = false;
+ public void testContextMenu_OnFile_NoOpen() {
+ selectionDetails.canOpen = false;
mgr.updateContextMenuForFiles(testMenu, selectionDetails);
+ dirOpen.assertDisabledAndInvisible();
dirOpenWith.assertDisabledAndInvisible();
}