Merge "Revert "Make numFolderRows/numFolderColumns accept more values"" into main
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
index 81e4ad5..1be1798 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.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;
@@ -268,6 +269,8 @@
if (mTaskbarDivider != null) {
mTaskbarDivider.setOnLongClickListener(
mControllerCallbacks.getTaskbarDividerLongClickListener());
+ mTaskbarDivider.setOnTouchListener(
+ mControllerCallbacks.getTaskbarDividerRightClickListener());
}
}
@@ -408,6 +411,16 @@
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/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
index 0225de4..8a7a98c 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
@@ -44,6 +44,7 @@
import android.annotation.NonNull;
import android.graphics.Rect;
import android.util.Log;
+import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Interpolator;
@@ -883,6 +884,17 @@
};
}
+ public View.OnTouchListener getTaskbarDividerRightClickListener() {
+ return (v, event) -> {
+ if (event.isFromSource(InputDevice.SOURCE_MOUSE)
+ && event.getButtonState() == MotionEvent.BUTTON_SECONDARY) {
+ mControllers.taskbarPinningController.showPinningView(v);
+ return true;
+ }
+ return false;
+ };
+ }
+
public View.OnLongClickListener getIconOnLongClickListener() {
return mControllers.taskbarDragController::startDragOnLongClick;
}
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 3717d9c..b7576c3 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -982,12 +982,11 @@
base = new TaskbarUnstashInputConsumer(this, base, mInputMonitorCompat, tac,
mOverviewCommandHelper);
}
- } else if (canStartSystemGesture && FeatureFlags.ENABLE_LONG_PRESS_NAV_HANDLE.get()
- && !previousGestureState.isRecentsAnimationRunning()) {
+ } else if (canStartSystemGesture && !previousGestureState.isRecentsAnimationRunning()) {
reasonString.append(NEWLINE_PREFIX)
.append(reasonPrefix)
.append(SUBSTRING_PREFIX)
- .append("Long press nav handle enabled, ")
+ .append("Not running recents animation, ")
.append("using NavHandleLongPressInputConsumer");
base = new NavHandleLongPressInputConsumer(this, base, mInputMonitorCompat,
mDeviceState);
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressHandler.java b/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressHandler.java
index 14305cf..57c05e9 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressHandler.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressHandler.java
@@ -48,17 +48,13 @@
}
/**
- * Called when nav handle gesture starts. Returns true if long press nav handle is enabled and
- * supported.
+ * Called when nav handle gesture starts.
*/
- public boolean canStartTouch() {
- return false;
- }
+ public void onTouchStarted() {}
/**
* Called when nav handle gesture is finished by the user lifting their finger or the system
* cancelling the touch for some other reason.
*/
- public void onTouchFinished() {
- }
+ public void onTouchFinished() {}
}
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
index 8051e68..0127cc9 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
@@ -16,6 +16,8 @@
package com.android.quickstep.inputconsumers;
import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_TIMEOUT_MS;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_DEEP_PRESS_NAVBAR;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_LONG_PRESS_NAVBAR;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import android.content.Context;
@@ -25,9 +27,11 @@
import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R;
import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.util.DisplayController;
import com.android.quickstep.InputConsumer;
import com.android.quickstep.RecentsAnimationDeviceState;
+import com.android.quickstep.TopTaskTracker;
import com.android.systemui.shared.system.InputMonitorCompat;
/**
@@ -43,8 +47,11 @@
private final float mTouchSlopSquared;
private final int mLongPressTimeout;
private final boolean mDeepPressEnabled;
+ private final StatsLogManager mStatsLogManager;
+ private final TopTaskTracker mTopTaskTracker;
private MotionEvent mCurrentDownEvent;
+ private boolean mDeepPressLogged; // Whether deep press has been logged for the current touch.
public NavHandleLongPressInputConsumer(Context context, InputConsumer delegate,
InputMonitorCompat inputMonitor, RecentsAnimationDeviceState deviceState) {
@@ -60,6 +67,8 @@
}
mTouchSlopSquared = deviceState.getSquaredTouchSlop();
mNavHandleLongPressHandler = NavHandleLongPressHandler.newInstance(context);
+ mStatsLogManager = StatsLogManager.newInstance(context);
+ mTopTaskTracker = TopTaskTracker.INSTANCE.get(context);
}
@Override
@@ -87,8 +96,9 @@
mCurrentDownEvent.recycle();
}
mCurrentDownEvent = MotionEvent.obtain(ev);
- if (isInNavBarHorizontalArea(ev.getRawX())
- && mNavHandleLongPressHandler.canStartTouch()) {
+ mDeepPressLogged = false;
+ if (isInNavBarHorizontalArea(ev.getRawX())) {
+ mNavHandleLongPressHandler.onTouchStarted();
MAIN_EXECUTOR.getHandler().postDelayed(mTriggerLongPress,
mLongPressTimeout);
}
@@ -110,25 +120,41 @@
}
// If the gesture is deep press then trigger long press asap
- if (mDeepPressEnabled && MAIN_EXECUTOR.getHandler().hasCallbacks(mTriggerLongPress)
- && ev.getClassification() == MotionEvent.CLASSIFICATION_DEEP_PRESS) {
- MAIN_EXECUTOR.getHandler().removeCallbacks(mTriggerLongPress);
- MAIN_EXECUTOR.getHandler().post(mTriggerLongPress);
+ if (MAIN_EXECUTOR.getHandler().hasCallbacks(mTriggerLongPress)
+ && ev.getClassification() == MotionEvent.CLASSIFICATION_DEEP_PRESS
+ && !mDeepPressLogged) {
+ // Log deep press even if feature is disabled.
+ String runningPackage = mTopTaskTracker.getCachedTopTask(
+ /* filterOnlyVisibleRecents */ true).getPackageName();
+ mStatsLogManager.logger().withPackageName(runningPackage)
+ .log(LAUNCHER_DEEP_PRESS_NAVBAR);
+ mDeepPressLogged = true;
+
+ // But only trigger if the feature is enabled.
+ if (mDeepPressEnabled) {
+ MAIN_EXECUTOR.getHandler().removeCallbacks(mTriggerLongPress);
+ MAIN_EXECUTOR.getHandler().post(mTriggerLongPress);
+ }
}
}
private void triggerLongPress() {
+ String runningPackage = mTopTaskTracker.getCachedTopTask(
+ /* filterOnlyVisibleRecents */ true).getPackageName();
+ mStatsLogManager.logger().withPackageName(runningPackage).log(LAUNCHER_LONG_PRESS_NAVBAR);
+
Runnable longPressRunnable = mNavHandleLongPressHandler.getLongPressRunnable();
- if (longPressRunnable != null) {
- OtherActivityInputConsumer oaic = getInputConsumerOfClass(
- OtherActivityInputConsumer.class);
- if (oaic != null && oaic.hasStartedTouchTracking()) {
- oaic.setForceFinishRecentsTransitionCallback(longPressRunnable);
- setActive(mCurrentDownEvent);
- } else {
- setActive(mCurrentDownEvent);
- MAIN_EXECUTOR.post(longPressRunnable);
- }
+ if (longPressRunnable == null) {
+ return;
+ }
+
+ OtherActivityInputConsumer oaic = getInputConsumerOfClass(OtherActivityInputConsumer.class);
+ if (oaic != null && oaic.hasStartedTouchTracking()) {
+ oaic.setForceFinishRecentsTransitionCallback(longPressRunnable);
+ setActive(mCurrentDownEvent);
+ } else {
+ setActive(mCurrentDownEvent);
+ MAIN_EXECUTOR.post(longPressRunnable);
}
}
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java b/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java
index 28473cd..f0683f9 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java
@@ -154,6 +154,11 @@
getTaskbar().openAllApps().dismissByTappingOutsideForTablet(/* tapRight= */ false);
}
+ @Test
+ public void testOpenMenuViaRightClick() {
+ getTaskbar().getAppIcon(TEST_APP_NAME).openDeepShortcutMenuWithRightClick();
+ }
+
private boolean isTaskbarTestModeTransient() {
return TRANSIENT == mTaskbarMode;
}
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index 9980218..f90779c 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -275,6 +275,12 @@
@UiEvent(doc = "User swipes or fling in DOWN direction on the bottom bazel area.")
LAUNCHER_SWIPEDOWN_NAVBAR(573),
+ @UiEvent(doc = "User deep presses on the bottom bezel area.")
+ LAUNCHER_DEEP_PRESS_NAVBAR(1543),
+
+ @UiEvent(doc = "User long presses on the bottom bezel area.")
+ LAUNCHER_LONG_PRESS_NAVBAR(1544),
+
@UiEvent(doc = "User swipes or fling in UP direction from bottom bazel area.")
LAUNCHER_HOME_GESTURE(574),
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 51e1ae0..68e3af0 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -1820,7 +1820,7 @@
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 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 @@
|| 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 @@
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 d747150..064f80c 100644
--- a/tests/tapl/com/android/launcher3/tapl/TaskbarAppIcon.java
+++ b/tests/tapl/com/android/launcher3/tapl/TaskbarAppIcon.java
@@ -25,6 +25,7 @@
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 @@
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);