Merge "Sends user home when stashed taskbar handle is clicked." into udc-qpr-dev

This commit is contained in:
Pat Manning
2023-07-19 18:24:06 +00:00
committed by Android (Google) Code Review
5 changed files with 111 additions and 18 deletions
@@ -888,7 +888,8 @@ public class TouchInteractionService extends Service {
.append(SUBSTRING_PREFIX)
.append("TaskbarActivityContext != null, "
+ "using TaskbarUnstashInputConsumer");
base = new TaskbarUnstashInputConsumer(this, base, mInputMonitorCompat, tac);
base = new TaskbarUnstashInputConsumer(this, base, mInputMonitorCompat, tac,
mOverviewCommandHelper);
}
} else if (canStartSystemGesture && FeatureFlags.ENABLE_LONG_PRESS_NAV_HANDLE.get()) {
base = new NavHandleLongPressInputConsumer(this, base, mInputMonitorCompat);
@@ -15,6 +15,7 @@
*/
package com.android.quickstep.inputconsumers;
import static android.view.MotionEvent.ACTION_BUTTON_RELEASE;
import static android.view.MotionEvent.INVALID_POINTER_ID;
import static com.android.launcher3.MotionEventsUtils.isTrackpadMotionEvent;
@@ -41,6 +42,7 @@ import com.android.launcher3.taskbar.bubbles.BubbleControllers;
import com.android.launcher3.touch.OverScroll;
import com.android.launcher3.util.DisplayController;
import com.android.quickstep.InputConsumer;
import com.android.quickstep.OverviewCommandHelper;
import com.android.systemui.shared.system.InputMonitorCompat;
/**
@@ -51,6 +53,7 @@ import com.android.systemui.shared.system.InputMonitorCompat;
public class TaskbarUnstashInputConsumer extends DelegateInputConsumer {
private final TaskbarActivityContext mTaskbarActivityContext;
private final OverviewCommandHelper mOverviewCommandHelper;
private final GestureDetector mLongPressDetector;
private final float mSquaredTouchSlop;
@@ -80,9 +83,11 @@ public class TaskbarUnstashInputConsumer extends DelegateInputConsumer {
private final @Nullable TransitionCallback mTransitionCallback;
public TaskbarUnstashInputConsumer(Context context, InputConsumer delegate,
InputMonitorCompat inputMonitor, TaskbarActivityContext taskbarActivityContext) {
InputMonitorCompat inputMonitor, TaskbarActivityContext taskbarActivityContext,
OverviewCommandHelper overviewCommandHelper) {
super(delegate, inputMonitor);
mTaskbarActivityContext = taskbarActivityContext;
mOverviewCommandHelper = overviewCommandHelper;
// TODO(b/270395798): remove this when cleaning up old Persistent Taskbar code.
mSquaredTouchSlop = Utilities.squaredTouchSlop(context);
mScreenWidth = taskbarActivityContext.getDeviceProfile().widthPx;
@@ -123,7 +128,11 @@ public class TaskbarUnstashInputConsumer extends DelegateInputConsumer {
public void onMotionEvent(MotionEvent ev) {
mLongPressDetector.onTouchEvent(ev);
if (mState != STATE_ACTIVE) {
mDelegate.onMotionEvent(ev);
boolean isStashedTaskbarHovered =
isStashedTaskbarHovered((int) ev.getX(), (int) ev.getY());
if (!isStashedTaskbarHovered) {
mDelegate.onMotionEvent(ev);
}
// Only show the transient task bar if the touch events are on the screen.
if (mTaskbarActivityContext != null && !isTrackpadMotionEvent(ev)) {
@@ -218,6 +227,11 @@ public class TaskbarUnstashInputConsumer extends DelegateInputConsumer {
mHasPassedTaskbarNavThreshold = false;
mIsInBubbleBarArea = false;
break;
case ACTION_BUTTON_RELEASE:
if (isStashedTaskbarHovered) {
mOverviewCommandHelper.addCommand(OverviewCommandHelper.TYPE_HOME);
}
break;
}
}
}
@@ -274,19 +288,17 @@ public class TaskbarUnstashInputConsumer extends DelegateInputConsumer {
private void updateHoveredTaskbarState(int x, int y) {
DeviceProfile dp = mTaskbarActivityContext.getDeviceProfile();
mStashedTaskbarHandleBounds.set(
mBottomEdgeBounds.set(
(dp.widthPx - (int) mUnstashArea) / 2,
dp.heightPx - dp.stashedTaskbarHeight,
dp.heightPx - mStashedTaskbarBottomEdge,
(int) (((dp.widthPx - mUnstashArea) / 2) + mUnstashArea),
dp.heightPx);
mBottomEdgeBounds.set(mStashedTaskbarHandleBounds);
mBottomEdgeBounds.top = dp.heightPx - mStashedTaskbarBottomEdge;
if (mBottomEdgeBounds.contains(x, y)) {
// If hovering stashed taskbar and then hover screen bottom edge, unstash it.
mTaskbarActivityContext.onSwipeToUnstashTaskbar();
mIsStashedTaskbarHovered = false;
} else if (!mStashedTaskbarHandleBounds.contains(x, y)) {
} else if (!isStashedTaskbarHovered(x, y)) {
// If exit hovering stashed taskbar, remove hint.
startStashedTaskbarHover(/* isHovered = */ false);
}
@@ -294,18 +306,13 @@ public class TaskbarUnstashInputConsumer extends DelegateInputConsumer {
private void updateUnhoveredTaskbarState(int x, int y) {
DeviceProfile dp = mTaskbarActivityContext.getDeviceProfile();
mStashedTaskbarHandleBounds.set(
(dp.widthPx - (int) mUnstashArea) / 2,
dp.heightPx - dp.stashedTaskbarHeight,
(int) (((dp.widthPx - mUnstashArea) / 2) + mUnstashArea),
dp.heightPx);
mBottomEdgeBounds.set(
0,
dp.heightPx - mBottomScreenEdge,
dp.widthPx,
dp.heightPx);
if (mStashedTaskbarHandleBounds.contains(x, y)) {
if (isStashedTaskbarHovered(x, y)) {
// If enter hovering stashed taskbar, start hint.
startStashedTaskbarHover(/* isHovered = */ true);
} else if (mBottomEdgeBounds.contains(x, y)) {
@@ -318,4 +325,19 @@ public class TaskbarUnstashInputConsumer extends DelegateInputConsumer {
mTaskbarActivityContext.startTaskbarUnstashHint(isHovered, /* forceUnstash = */ true);
mIsStashedTaskbarHovered = isHovered;
}
private boolean isStashedTaskbarHovered(int x, int y) {
if (!mTaskbarActivityContext.isTaskbarStashed()
|| mTaskbarActivityContext.isTaskbarAllAppsOpen()
|| !ENABLE_CURSOR_HOVER_STATES.get()) {
return false;
}
DeviceProfile dp = mTaskbarActivityContext.getDeviceProfile();
mStashedTaskbarHandleBounds.set(
(dp.widthPx - (int) mUnstashArea) / 2,
dp.heightPx - dp.stashedTaskbarHeight,
(int) (((dp.widthPx - mUnstashArea) / 2) + mUnstashArea),
dp.heightPx);
return mStashedTaskbarHandleBounds.contains(x, y);
}
}
@@ -18,7 +18,6 @@ package com.android.quickstep;
import static com.android.launcher3.config.FeatureFlags.ENABLE_CURSOR_HOVER_STATES;
import static com.android.quickstep.TaskbarModeSwitchRule.Mode.TRANSIENT;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
@@ -64,4 +63,15 @@ public class TaplTestsTransientTaskbar extends AbstractTaplTestsTaskbar {
throw new RuntimeException(e);
}
}
@Test
@TaskbarModeSwitch(mode = TRANSIENT)
public void testClickHoveredTaskbarToGoHome() {
try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_CURSOR_HOVER_STATES, true)) {
getTaskbar().getAppIcon(TEST_APP_NAME).launch(TEST_APP_PACKAGE);
mLauncher.getLaunchedAppState().clickStashedTaskbarToGoHome();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
@@ -37,6 +37,7 @@ import androidx.test.uiautomator.By;
import androidx.test.uiautomator.Condition;
import androidx.test.uiautomator.UiDevice;
import com.android.launcher3.testing.shared.ResourceUtils;
import com.android.launcher3.testing.shared.TestProtocol;
/**
@@ -50,6 +51,8 @@ public final class LaunchedAppState extends Background {
// UNSTASHED_TASKBAR_HANDLE_HINT_SCALE value from TaskbarStashController.
private static final float UNSTASHED_TASKBAR_HANDLE_HINT_SCALE = 1.1f;
private static final int STASHED_TASKBAR_BOTTOM_EDGE_DP = 1;
private final Condition<UiDevice, Boolean> mStashedTaskbarHintScaleCondition =
device -> mLauncher.getTestInfo(REQUEST_STASHED_TASKBAR_SCALE).getFloat(
TestProtocol.TEST_INFO_RESPONSE_FIELD) - UNSTASHED_TASKBAR_HANDLE_HINT_SCALE
@@ -209,7 +212,7 @@ public final class LaunchedAppState extends Background {
*
* <p>This unstashing occurs when not actively hovering the taskbar.
*/
public void hoverScreenBottomEdgeToUnstashTaskbar() {
public Taskbar hoverScreenBottomEdgeToUnstashTaskbar() {
try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"cursor hover entering screen edge to unstash taskbar")) {
@@ -226,13 +229,15 @@ public final class LaunchedAppState extends Background {
mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_HOVER_EXIT,
new Point(taskbarUnstashArea.x, taskbarUnstashArea.y), null);
return new Taskbar(mLauncher);
}
}
/**
* Emulate the cursor hovering the taskbar to get unstash hint, then hovering below to unstash.
*/
public void hoverBelowHintedTaskbarToUnstash() {
public Taskbar hoverBelowHintedTaskbarToUnstash() {
try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"cursor hover entering stashed taskbar")) {
@@ -254,6 +259,7 @@ public final class LaunchedAppState extends Background {
new Point(taskbarUnstashArea.x, taskbarUnstashArea.y), null);
mLauncher.waitForSystemLauncherObject(TASKBAR_RES_ID);
return new Taskbar(mLauncher);
}
}
}
@@ -288,4 +294,45 @@ public final class LaunchedAppState extends Background {
}
}
}
/**
* Emulate the cursor clicking the stashed taskbar to go home.
*/
public Workspace clickStashedTaskbarToGoHome() {
try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"cursor hover entering stashed taskbar")) {
long downTime = SystemClock.uptimeMillis();
int stashedTaskbarBottomEdge = ResourceUtils.pxFromDp(STASHED_TASKBAR_BOTTOM_EDGE_DP,
mLauncher.getResources().getDisplayMetrics());
Point stashedTaskbarHintArea = new Point(mLauncher.getRealDisplaySize().x / 2,
mLauncher.getRealDisplaySize().y - stashedTaskbarBottomEdge - 1);
mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_HOVER_ENTER,
new Point(stashedTaskbarHintArea.x, stashedTaskbarHintArea.y), null);
mLauncher.getDevice().wait(mStashedTaskbarHintScaleCondition,
LauncherInstrumentation.WAIT_TIME_MS);
try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
"cursor clicking stashed taskbar to go home")) {
mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_HOVER_EXIT,
new Point(stashedTaskbarHintArea.x, stashedTaskbarHintArea.y),
null);
mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN,
new Point(stashedTaskbarHintArea.x, stashedTaskbarHintArea.y),
LauncherInstrumentation.GestureScope.OUTSIDE_WITHOUT_PILFER);
mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_BUTTON_PRESS,
new Point(stashedTaskbarHintArea.x, stashedTaskbarHintArea.y),
null);
mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_BUTTON_RELEASE,
new Point(stashedTaskbarHintArea.x, stashedTaskbarHintArea.y),
null);
mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_UP,
new Point(stashedTaskbarHintArea.x, stashedTaskbarHintArea.y),
LauncherInstrumentation.GestureScope.OUTSIDE_WITHOUT_PILFER);
return mLauncher.getWorkspace();
}
}
}
}
@@ -110,6 +110,9 @@ public final class LauncherInstrumentation {
static final Pattern EVENT_TOUCH_CANCEL_TIS = getTouchEventPatternTIS("ACTION_CANCEL");
static final Pattern EVENT_HOVER_ENTER_TIS = getTouchEventPatternTIS("ACTION_HOVER_ENTER");
static final Pattern EVENT_HOVER_EXIT_TIS = getTouchEventPatternTIS("ACTION_HOVER_EXIT");
static final Pattern EVENT_BUTTON_PRESS_TIS = getTouchEventPatternTIS("ACTION_BUTTON_PRESS");
static final Pattern EVENT_BUTTON_RELEASE_TIS =
getTouchEventPatternTIS("ACTION_BUTTON_RELEASE");
private static final Pattern EVENT_KEY_BACK_DOWN =
getKeyEventPattern("ACTION_DOWN", "KEYCODE_BACK");
@@ -173,7 +176,7 @@ public final class LauncherInstrumentation {
void close();
}
private static final String WORKSPACE_RES_ID = "workspace";
static final String WORKSPACE_RES_ID = "workspace";
private static final String APPS_RES_ID = "apps_view";
private static final String OVERVIEW_RES_ID = "overview_panel";
private static final String WIDGETS_RES_ID = "primary_widgets_list_view";
@@ -1834,6 +1837,12 @@ public final class LauncherInstrumentation {
}
mPointerCount--;
break;
case MotionEvent.ACTION_BUTTON_PRESS:
expectEvent(TestProtocol.SEQUENCE_TIS, EVENT_BUTTON_PRESS_TIS);
break;
case MotionEvent.ACTION_BUTTON_RELEASE:
expectEvent(TestProtocol.SEQUENCE_TIS, EVENT_BUTTON_RELEASE_TIS);
break;
}
final MotionEvent event = isTrackpadGesture
@@ -1841,6 +1850,10 @@ public final class LauncherInstrumentation {
downTime, currentTime, action, point.x, point.y, pointerCount,
mTrackpadGestureType)
: getMotionEvent(downTime, currentTime, action, point.x, point.y);
if (action == MotionEvent.ACTION_BUTTON_PRESS
|| action == MotionEvent.ACTION_BUTTON_RELEASE) {
event.setActionButton(MotionEvent.BUTTON_PRIMARY);
}
assertTrue("injectInputEvent failed",
mInstrumentation.getUiAutomation().injectInputEvent(event, true, false));
event.recycle();