From 06ecd24ee397451ab7f5c3b4953807dbebb5eaf7 Mon Sep 17 00:00:00 2001 From: Pat Manning Date: Tue, 21 Nov 2023 14:41:33 +0000 Subject: [PATCH] Allow right-click of taskbar icons to launch long-click menu. Fix: 290459491 Test: TaplTestsTaskbar#testOpenMenuViaRightClick Flag: NONE. Change-Id: Ide85f62e5b08d5261f15871e85d3250cc66d0919 --- .../launcher3/taskbar/TaskbarView.java | 11 ++++++++ .../android/quickstep/TaplTestsTaskbar.java | 5 ++++ .../tapl/LauncherInstrumentation.java | 26 ++++++++++++++++++- .../launcher3/tapl/TaskbarAppIcon.java | 16 ++++++++++++ 4 files changed, 57 insertions(+), 1 deletion(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java index 81e4ad521d..e4daa03f88 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java @@ -29,6 +29,7 @@ import android.graphics.Canvas; import android.graphics.Rect; import android.os.Bundle; import android.util.AttributeSet; +import android.view.InputDevice; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; @@ -408,6 +409,16 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar public void setClickAndLongClickListenersForIcon(View icon) { icon.setOnClickListener(mIconClickListener); icon.setOnLongClickListener(mIconLongClickListener); + // Add right-click support to btv icons. + icon.setOnTouchListener((v, event) -> { + if (event.isFromSource(InputDevice.SOURCE_MOUSE) + && (event.getButtonState() & MotionEvent.BUTTON_SECONDARY) != 0 + && v instanceof BubbleTextView) { + mActivityContext.showPopupMenuForIcon((BubbleTextView) v); + return true; + } + return false; + }); } /** diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java b/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java index 28473cdebe..f0683f9082 100644 --- a/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java +++ b/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java @@ -154,6 +154,11 @@ public class TaplTestsTaskbar extends AbstractTaplTestsTaskbar { getTaskbar().openAllApps().dismissByTappingOutsideForTablet(/* tapRight= */ false); } + @Test + public void testOpenMenuViaRightClick() { + getTaskbar().getAppIcon(TEST_APP_NAME).openDeepShortcutMenuWithRightClick(); + } + private boolean isTaskbarTestModeTransient() { return TRANSIENT == mTaskbarMode; } diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 720c8e5567..02059529f2 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -1820,7 +1820,7 @@ public final class LauncherInstrumentation { public void sendPointer(long downTime, long currentTime, int action, Point point, GestureScope gestureScope) { sendPointer(downTime, currentTime, action, point, gestureScope, - InputDevice.SOURCE_TOUCHSCREEN); + InputDevice.SOURCE_TOUCHSCREEN, false); } private void injectEvent(InputEvent event) { @@ -1830,6 +1830,11 @@ public final class LauncherInstrumentation { public void sendPointer(long downTime, long currentTime, int action, Point point, GestureScope gestureScope, int source) { + sendPointer(downTime, currentTime, action, point, gestureScope, source, false); + } + + public void sendPointer(long downTime, long currentTime, int action, Point point, + GestureScope gestureScope, int source, boolean isRightClick) { final boolean hasTIS = hasTIS(); int pointerCount = mPointerCount; @@ -1865,6 +1870,9 @@ public final class LauncherInstrumentation { || action == MotionEvent.ACTION_BUTTON_RELEASE) { event.setActionButton(MotionEvent.BUTTON_PRIMARY); } + if (isRightClick) { + event.setButtonState(event.getButtonState() & MotionEvent.BUTTON_SECONDARY); + } injectEvent(event); } @@ -1975,6 +1983,22 @@ public final class LauncherInstrumentation { return result; } + @NonNull + UiObject2 rightClickAndGet( + @NonNull final UiObject2 target, @NonNull String resName, Pattern rightClickEvent) { + final Point targetCenter = target.getVisibleCenter(); + final long downTime = SystemClock.uptimeMillis(); + sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN, targetCenter, + GestureScope.DONT_EXPECT_PILFER, InputDevice.SOURCE_MOUSE, + /* isRightClick= */ true); + expectEvent(TestProtocol.SEQUENCE_MAIN, rightClickEvent); + final UiObject2 result = waitForLauncherObject(resName); + sendPointer(downTime, SystemClock.uptimeMillis(), ACTION_UP, targetCenter, + GestureScope.DONT_EXPECT_PILFER, InputDevice.SOURCE_MOUSE, + /* isRightClick= */ true); + return result; + } + private static int getSystemIntegerRes(Context context, String resName) { Resources res = context.getResources(); int resId = res.getIdentifier(resName, "integer", "android"); diff --git a/tests/tapl/com/android/launcher3/tapl/TaskbarAppIcon.java b/tests/tapl/com/android/launcher3/tapl/TaskbarAppIcon.java index 099acd4716..55c649f147 100644 --- a/tests/tapl/com/android/launcher3/tapl/TaskbarAppIcon.java +++ b/tests/tapl/com/android/launcher3/tapl/TaskbarAppIcon.java @@ -25,6 +25,7 @@ import java.util.regex.Pattern; public final class TaskbarAppIcon extends AppIcon implements SplitscreenDragSource { private static final Pattern LONG_CLICK_EVENT = Pattern.compile("onTaskbarItemLongClick"); + private static final Pattern RIGHT_CLICK_EVENT = Pattern.compile("onTaskbarItemRightClick"); TaskbarAppIcon(LauncherInstrumentation launcher, UiObject2 icon) { super(launcher, icon); @@ -35,11 +36,26 @@ public final class TaskbarAppIcon extends AppIcon implements SplitscreenDragSour return LONG_CLICK_EVENT; } + protected Pattern getRightClickEvent() { + return RIGHT_CLICK_EVENT; + } + @Override public TaskbarAppIconMenu openDeepShortcutMenu() { return (TaskbarAppIconMenu) super.openDeepShortcutMenu(); } + /** + * Right-clicks the icon to open its menu. + */ + public TaskbarAppIconMenu openDeepShortcutMenuWithRightClick() { + try (LauncherInstrumentation.Closable e = mLauncher.addContextLayer( + "want to return the shortcut menu when icon is right-clicked.")) { + return createMenu(mLauncher.rightClickAndGet( + mObject, /* resName= */ "deep_shortcuts_container", getRightClickEvent())); + } + } + @Override protected TaskbarAppIconMenu createMenu(UiObject2 menu) { return new TaskbarAppIconMenu(mLauncher, menu);