Merge "Test: using RuleChain to create a correct order of rules." into ub-launcher3-qt-dev
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
index a6c4445..d66af1a 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
@@ -98,9 +98,6 @@
if (mStartState == OVERVIEW || mStartState == ALL_APPS) {
return true;
}
- if (!mLauncher.hasWindowFocus()) {
- return true;
- }
if (AbstractFloatingView.getTopOpenView(mLauncher) != null) {
return true;
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
index cbc94ba..dc35440 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
@@ -62,6 +62,7 @@
import androidx.annotation.BinderThread;
+import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.R;
import com.android.launcher3.ResourceUtils;
@@ -79,6 +80,7 @@
import com.android.quickstep.inputconsumers.InputConsumer;
import com.android.quickstep.inputconsumers.OtherActivityInputConsumer;
import com.android.quickstep.inputconsumers.OverviewInputConsumer;
+import com.android.quickstep.inputconsumers.OverviewWithoutFocusInputConsumer;
import com.android.quickstep.inputconsumers.ScreenPinnedInputConsumer;
import com.android.systemui.shared.recents.IOverviewProxy;
import com.android.systemui.shared.recents.ISystemUiProxy;
@@ -566,10 +568,9 @@
info.id = mSwipeSharedState.nextRunningTaskId;
return createOtherActivityInputConsumer(event, info);
} else if (mSwipeSharedState.goingToLauncher || activityControl.isResumed()) {
- return OverviewInputConsumer.newInstance(activityControl, mInputMonitorCompat, false);
- } else if (ENABLE_QUICKSTEP_LIVE_TILE.get() &&
- activityControl.isInLiveTileMode()) {
- return OverviewInputConsumer.newInstance(activityControl, mInputMonitorCompat, false);
+ return createOverviewInputConsumer(event);
+ } else if (ENABLE_QUICKSTEP_LIVE_TILE.get() && activityControl.isInLiveTileMode()) {
+ return createOverviewInputConsumer(event);
} else if (mGestureBlockingActivity != null && runningTaskInfo != null
&& mGestureBlockingActivity.equals(runningTaskInfo.topActivity)) {
return InputConsumer.NO_OP;
@@ -578,20 +579,24 @@
}
}
+ private boolean disableHorizontalSwipe(MotionEvent event) {
+ // mExclusionRegion can change on binder thread, use a local instance here.
+ Region exclusionRegion = mExclusionRegion;
+ return mMode == Mode.NO_BUTTON && exclusionRegion != null
+ && exclusionRegion.contains((int) event.getX(), (int) event.getY());
+ }
+
private OtherActivityInputConsumer createOtherActivityInputConsumer(MotionEvent event,
RunningTaskInfo runningTaskInfo) {
final ActivityControlHelper activityControl =
mOverviewComponentObserver.getActivityControlHelper();
boolean shouldDefer = activityControl.deferStartingActivity(mActiveNavBarRegion, event);
- // mExclusionRegion can change on binder thread, use a local instance here.
- Region exclusionRegion = mExclusionRegion;
- boolean disableHorizontalSwipe = mMode == Mode.NO_BUTTON && exclusionRegion != null
- && exclusionRegion.contains((int) event.getX(), (int) event.getY());
return new OtherActivityInputConsumer(this, runningTaskInfo, mRecentsModel,
mOverviewComponentObserver.getOverviewIntent(), activityControl,
shouldDefer, mOverviewCallbacks, mInputConsumer, this::onConsumerInactive,
- mSwipeSharedState, mInputMonitorCompat, mSwipeTouchRegion, disableHorizontalSwipe);
+ mSwipeSharedState, mInputMonitorCompat, mSwipeTouchRegion,
+ disableHorizontalSwipe(event));
}
private InputConsumer createDeviceLockedInputConsumer(RunningTaskInfo taskInfo) {
@@ -603,6 +608,23 @@
}
}
+ public InputConsumer createOverviewInputConsumer(MotionEvent event) {
+ final ActivityControlHelper activityControl =
+ mOverviewComponentObserver.getActivityControlHelper();
+ BaseDraggingActivity activity = activityControl.getCreatedActivity();
+ if (activity == null) {
+ return InputConsumer.NO_OP;
+ }
+
+ if (activity.getRootView().hasWindowFocus()) {
+ return new OverviewInputConsumer(activity, mInputMonitorCompat,
+ false /* startingInActivityBounds */);
+ } else {
+ return new OverviewWithoutFocusInputConsumer(this, mInputMonitorCompat,
+ disableHorizontalSwipe(event));
+ }
+ }
+
/**
* To be called by the consumer when it's no longer active.
*/
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
index 87b7326..8b1efb2 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -267,6 +267,7 @@
private MultiStateCallback mStateCallback;
// Used to control launcher components throughout the swipe gesture.
private AnimatorPlaybackController mLauncherTransitionController;
+ private boolean mHasLauncherTransitionControllerStarted;
private T mActivity;
private RecentsView mRecentsView;
@@ -647,8 +648,7 @@
}
private void buildAnimationController() {
- if (mGestureEndTarget == HOME || (mLauncherTransitionController != null
- && mLauncherTransitionController.getAnimationPlayer().isStarted())) {
+ if (mGestureEndTarget == HOME || mHasLauncherTransitionControllerStarted) {
// We don't want a new mLauncherTransitionController if mGestureEndTarget == HOME (it
// has its own animation) or if we're already animating the current controller.
return;
@@ -858,7 +858,9 @@
setTargetAlphaProvider(WindowTransformSwipeHandler::getHiddenTargetAlpha);
}
- return OverviewInputConsumer.newInstance(mActivityControlHelper, null, true);
+ BaseDraggingActivity activity = mActivityControlHelper.getCreatedActivity();
+ return activity == null
+ ? InputConsumer.NO_OP : new OverviewInputConsumer(activity, null, true);
}
private void endRunningWindowAnim() {
@@ -1122,6 +1124,7 @@
}
mLauncherTransitionController.getAnimationPlayer().start();
}
+ mHasLauncherTransitionControllerStarted = true;
}
/**
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java
index 6e7cb8f..489eb27 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java
@@ -31,6 +31,7 @@
int TYPE_DEVICE_LOCKED = 1 << 4;
int TYPE_ACCESSIBILITY = 1 << 5;
int TYPE_SCREEN_PINNED = 1 << 6;
+ int TYPE_OVERVIEW_WITHOUT_FOCUS = 1 << 7;
InputConsumer NO_OP = () -> TYPE_NO_OP;
@@ -78,6 +79,8 @@
return "ACCESSIBILITY";
case TYPE_SCREEN_PINNED:
return "SCREEN_PINNED";
+ case TYPE_OVERVIEW_WITHOUT_FOCUS:
+ return "TYPE_OVERVIEW_WITHOUT_FOCUS";
default:
return "NO_OP";
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
index 0ed4c99..69b25db 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
@@ -28,7 +28,6 @@
import static com.android.launcher3.uioverrides.RecentsUiFactory.ROTATION_SEASCAPE;
import static com.android.launcher3.util.RaceConditionTracker.ENTER;
import static com.android.launcher3.util.RaceConditionTracker.EXIT;
-import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
@@ -43,10 +42,8 @@
import android.os.Handler;
import android.os.Looper;
import android.view.MotionEvent;
-import android.view.Surface;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;
-import android.view.WindowManager;
import androidx.annotation.UiThread;
@@ -65,6 +62,7 @@
import com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget;
import com.android.quickstep.util.CachedEventDispatcher;
import com.android.quickstep.util.MotionPauseDetector;
+import com.android.quickstep.util.NavBarPosition;
import com.android.quickstep.util.RecentsAnimationListenerSet;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.BackgroundExecutor;
@@ -95,7 +93,7 @@
private final SysUINavigationMode.Mode mMode;
private final RectF mSwipeTouchRegion;
- private final int mDisplayRotation;
+ private final NavBarPosition mNavBarPosition;
private final Consumer<OtherActivityInputConsumer> mOnCompleteCallback;
private final MotionPauseDetector mMotionPauseDetector;
@@ -157,7 +155,7 @@
mInputConsumer = inputConsumer;
mSwipeSharedState = swipeSharedState;
- mDisplayRotation = getSystemService(WindowManager.class).getDefaultDisplay().getRotation();
+ mNavBarPosition = new NavBarPosition(base);
mDragSlop = QuickStepContract.getQuickStepDragSlopPx();
float slop = QuickStepContract.getQuickStepTouchSlopPx();
mSquaredTouchSlop = slop * slop;
@@ -188,9 +186,7 @@
if (mPassedDragSlop && mInteractionHandler != null
&& !mRecentsViewDispatcher.hasConsumer()) {
mRecentsViewDispatcher.setConsumer(mInteractionHandler.getRecentsViewDispatcher(
- isNavBarOnLeft()
- ? ROTATION_SEASCAPE
- : (isNavBarOnRight() ? ROTATION_LANDSCAPE : RotationMode.NORMAL)));
+ mNavBarPosition.getRotationMode()));
}
int edgeFlags = ev.getEdgeFlags();
ev.setEdgeFlags(edgeFlags | EDGE_NAV_BAR);
@@ -329,14 +325,6 @@
mInteractionHandler.onGestureStarted();
}
- private boolean isNavBarOnRight() {
- return mMode != NO_BUTTON && mDisplayRotation == Surface.ROTATION_90;
- }
-
- private boolean isNavBarOnLeft() {
- return mMode != NO_BUTTON && mDisplayRotation == Surface.ROTATION_270;
- }
-
private void startTouchTrackingForWindowAnimation(long touchTimeMs) {
TOUCH_INTERACTION_LOG.addLog("startRecentsAnimation");
@@ -382,8 +370,8 @@
ViewConfiguration.get(this).getScaledMaximumFlingVelocity());
float velocityX = mVelocityTracker.getXVelocity(mActivePointerId);
float velocityY = mVelocityTracker.getYVelocity(mActivePointerId);
- float velocity = isNavBarOnRight() ? velocityX
- : isNavBarOnLeft() ? -velocityX
+ float velocity = mNavBarPosition.isRightEdge() ? velocityX
+ : mNavBarPosition.isLeftEdge() ? -velocityX
: velocityY;
mInteractionHandler.updateDisplacement(getDisplacement(ev) - mStartDisplacement);
@@ -444,9 +432,9 @@
}
private float getDisplacement(MotionEvent ev) {
- if (isNavBarOnRight()) {
+ if (mNavBarPosition.isRightEdge()) {
return ev.getX() - mDownPos.x;
- } else if (isNavBarOnLeft()) {
+ } else if (mNavBarPosition.isLeftEdge()) {
return mDownPos.x - ev.getX();
} else {
return ev.getY() - mDownPos.y;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
index bab3c71..4851e67 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
@@ -51,7 +51,7 @@
private final boolean mStartingInActivityBounds;
private boolean mTargetHandledTouch;
- OverviewInputConsumer(T activity, @Nullable InputMonitorCompat inputMonitor,
+ public OverviewInputConsumer(T activity, @Nullable InputMonitorCompat inputMonitor,
boolean startingInActivityBounds) {
mActivity = activity;
mInputMonitor = inputMonitor;
@@ -115,12 +115,12 @@
}
}
- public static InputConsumer newInstance(ActivityControlHelper activityHelper,
- @Nullable InputMonitorCompat inputMonitor, boolean startingInActivityBounds) {
+ public static InputConsumer newInstanceWithinActivityBounds(
+ ActivityControlHelper activityHelper) {
BaseDraggingActivity activity = activityHelper.getCreatedActivity();
if (activity == null) {
return InputConsumer.NO_OP;
}
- return new OverviewInputConsumer(activity, inputMonitor, startingInActivityBounds);
+ return new OverviewInputConsumer(activity, null, true);
}
}
\ No newline at end of file
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewWithoutFocusInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewWithoutFocusInputConsumer.java
new file mode 100644
index 0000000..425b8b6
--- /dev/null
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewWithoutFocusInputConsumer.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.inputconsumers;
+
+import static android.view.MotionEvent.ACTION_CANCEL;
+import static android.view.MotionEvent.ACTION_DOWN;
+import static android.view.MotionEvent.ACTION_MOVE;
+import static android.view.MotionEvent.ACTION_UP;
+
+import static com.android.launcher3.Utilities.squaredHypot;
+import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG;
+import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
+
+import android.content.Context;
+import android.graphics.PointF;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.ViewConfiguration;
+
+import com.android.launcher3.Utilities;
+import com.android.quickstep.OverviewCallbacks;
+import com.android.quickstep.util.NavBarPosition;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.InputMonitorCompat;
+
+public class OverviewWithoutFocusInputConsumer implements InputConsumer {
+
+ private final InputMonitorCompat mInputMonitor;
+ private final boolean mDisableHorizontalSwipe;
+ private final PointF mDownPos = new PointF();
+ private final float mSquaredTouchSlop;
+ private final Context mContext;
+ private final NavBarPosition mNavBarPosition;
+
+ private boolean mInterceptedTouch;
+ private VelocityTracker mVelocityTracker;
+
+
+ public OverviewWithoutFocusInputConsumer(Context context, InputMonitorCompat inputMonitor,
+ boolean disableHorizontalSwipe) {
+ mInputMonitor = inputMonitor;
+ mDisableHorizontalSwipe = disableHorizontalSwipe;
+ mContext = context;
+ mSquaredTouchSlop = Utilities.squaredTouchSlop(context);
+ mNavBarPosition = new NavBarPosition(context);
+
+ mVelocityTracker = VelocityTracker.obtain();
+ }
+
+ @Override
+ public int getType() {
+ return TYPE_OVERVIEW_WITHOUT_FOCUS;
+ }
+
+ @Override
+ public boolean allowInterceptByParent() {
+ return !mInterceptedTouch;
+ }
+
+ private void endTouchTracking() {
+ if (mVelocityTracker != null) {
+ mVelocityTracker.recycle();
+ mVelocityTracker = null;
+ }
+ }
+
+ @Override
+ public void onMotionEvent(MotionEvent ev) {
+ if (mVelocityTracker == null) {
+ return;
+ }
+
+ mVelocityTracker.addMovement(ev);
+ switch (ev.getActionMasked()) {
+ case ACTION_DOWN: {
+ mDownPos.set(ev.getX(), ev.getY());
+ break;
+ }
+ case ACTION_MOVE: {
+ if (!mInterceptedTouch) {
+ float displacementX = ev.getX() - mDownPos.x;
+ float displacementY = ev.getY() - mDownPos.y;
+ if (squaredHypot(displacementX, displacementY) >= mSquaredTouchSlop) {
+ if (mDisableHorizontalSwipe
+ && Math.abs(displacementX) > Math.abs(displacementY)) {
+ // Horizontal gesture is not allowed in this region
+ endTouchTracking();
+ break;
+ }
+
+ mInterceptedTouch = true;
+
+ if (mInputMonitor != null) {
+ mInputMonitor.pilferPointers();
+ }
+ }
+ }
+ break;
+ }
+
+ case ACTION_CANCEL:
+ endTouchTracking();
+ break;
+
+ case ACTION_UP: {
+ finishTouchTracking(ev);
+ endTouchTracking();
+ break;
+ }
+ }
+ }
+
+ private void finishTouchTracking(MotionEvent ev) {
+ mVelocityTracker.computeCurrentVelocity(100);
+ float velocityX = mVelocityTracker.getXVelocity();
+ float velocityY = mVelocityTracker.getYVelocity();
+ float velocity = mNavBarPosition.isRightEdge()
+ ? -velocityX : (mNavBarPosition.isLeftEdge() ? velocityX : -velocityY);
+
+ final boolean triggerQuickstep;
+ if (Math.abs(velocity) >= ViewConfiguration.get(mContext).getScaledMinimumFlingVelocity()) {
+ triggerQuickstep = velocity > 0;
+ } else {
+ float displacementX = mDisableHorizontalSwipe ? 0 : (ev.getX() - mDownPos.x);
+ float displacementY = ev.getY() - mDownPos.y;
+ triggerQuickstep = squaredHypot(displacementX, displacementY) >= mSquaredTouchSlop;
+ }
+
+ if (triggerQuickstep) {
+ OverviewCallbacks.get(mContext).closeAllWindows();
+ ActivityManagerWrapper.getInstance()
+ .closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
+ TOUCH_INTERACTION_LOG.addLog("startQuickstep");
+ } else {
+ // ignore
+ }
+ }
+}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/NavBarPosition.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/NavBarPosition.java
new file mode 100644
index 0000000..3ce341d
--- /dev/null
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/NavBarPosition.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.util;
+
+import static com.android.launcher3.uioverrides.RecentsUiFactory.ROTATION_LANDSCAPE;
+import static com.android.launcher3.uioverrides.RecentsUiFactory.ROTATION_SEASCAPE;
+import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
+
+import android.content.Context;
+import android.view.Surface;
+import android.view.WindowManager;
+
+import com.android.launcher3.graphics.RotationMode;
+import com.android.quickstep.SysUINavigationMode;
+
+/**
+ * Utility class to check nav bar position
+ */
+public class NavBarPosition {
+
+ private final SysUINavigationMode.Mode mMode;
+ private final int mDisplayRotation;
+
+ public NavBarPosition(Context context) {
+ mMode = SysUINavigationMode.getMode(context);
+ mDisplayRotation = context.getSystemService(WindowManager.class)
+ .getDefaultDisplay().getRotation();
+ }
+
+ public boolean isRightEdge() {
+ return mMode != NO_BUTTON && mDisplayRotation == Surface.ROTATION_90;
+ }
+
+ public boolean isLeftEdge() {
+ return mMode != NO_BUTTON && mDisplayRotation == Surface.ROTATION_270;
+ }
+
+ public RotationMode getRotationMode() {
+ return isLeftEdge() ? ROTATION_SEASCAPE
+ : (isRightEdge() ? ROTATION_LANDSCAPE : RotationMode.NORMAL);
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
index dcf2e3c..46161cb 100644
--- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
@@ -108,7 +108,7 @@
// Use a shorter duration for x or y translation to create a curve effect
private static final long APP_LAUNCH_CURVED_DURATION = 250;
private static final long APP_LAUNCH_ALPHA_DURATION = 50;
- private static final long APP_LAUNCH_ALPHA_START_DELAY = 50;
+ private static final long APP_LAUNCH_ALPHA_START_DELAY = 25;
// We scale the durations for the downward app launch animations (minus the scale animation).
private static final float APP_LAUNCH_DOWN_DUR_SCALE_FACTOR = 0.8f;