Merge "Removing ENABLE_LOCAL_COLOR_POPUPS feature flag" into tm-qpr-dev
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index cd60879..c0b6657 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -289,6 +289,8 @@
<dimen name="transient_taskbar_key_shadow_distance">10dp</dimen>
<dimen name="transient_taskbar_stashed_size">32dp</dimen>
<dimen name="transient_taskbar_icon_spacing">10dp</dimen>
+ <!-- An additional touch slop to prevent x-axis movement during the swipe up to show taskbar -->
+ <dimen name="transient_taskbar_clamped_offset_bound">16dp</dimen>
<!-- Taskbar swipe up thresholds -->
<dimen name="taskbar_app_window_threshold">150dp</dimen>
<dimen name="taskbar_home_overview_threshold">225dp</dimen>
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index dcad873..59dbd4b 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -1678,9 +1678,10 @@
mLauncher.getStateManager().moveToRestState();
}
+ RectF windowTargetBounds =
+ new RectF(getWindowTargetBounds(appTargets, getRotationChange(appTargets)));
Pair<RectFSpringAnim, AnimatorSet> pair = createWallpaperOpenAnimations(
- appTargets, wallpaperTargets, mFromUnlock,
- new RectF(0, 0, mDeviceProfile.widthPx, mDeviceProfile.heightPx),
+ appTargets, wallpaperTargets, mFromUnlock, windowTargetBounds,
QuickStepContract.getWindowCornerRadius(mLauncher));
mLauncher.clearForceInvisibleFlag(INVISIBLE_ALL);
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index f51bc55..13ca58d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -762,9 +762,7 @@
});
} else if (tag instanceof WorkspaceItemInfo) {
WorkspaceItemInfo info = (WorkspaceItemInfo) tag;
- if (info.isDisabled()) {
- ItemClickHandler.handleDisabledItemClicked(info, this);
- } else {
+ if (!info.isDisabled() || !ItemClickHandler.handleDisabledItemClicked(info, this)) {
TaskbarUIController taskbarUIController = mControllers.uiController;
RecentsView recents = taskbarUIController.getRecentsView();
if (recents != null
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
index 3045eca..a26f5e5 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
@@ -207,8 +207,13 @@
if (FeatureFlags.ENABLE_TASKBAR_POPUP_MENU.get()
&& !shouldStartDrag(0)) {
- // Immediately close the popup menu.
- mDragView.setOnAnimationEndCallback(() -> callOnDragStart());
+ mDragView.setOnAnimationEndCallback(() -> {
+ // Drag might be cancelled during the DragView animation, so check
+ // mIsPreDrag again.
+ if (mIsInPreDrag) {
+ callOnDragStart();
+ }
+ });
}
}
@@ -305,6 +310,9 @@
if (mDisallowGlobalDrag) {
AbstractFloatingView.closeAllOpenViewsExcept(mActivity, TYPE_TASKBAR_ALL_APPS);
} else {
+ // stash the transient taskbar
+ mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true);
+
AbstractFloatingView.closeAllOpenViews(mActivity);
}
@@ -413,6 +421,9 @@
if (dragEvent.getResult()) {
maybeOnDragEnd();
} else {
+ // un-stash the transient taskbar in case drag and drop was canceled
+ mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(false);
+
// This will take care of calling maybeOnDragEnd() after the animation
animateGlobalDragViewToOriginalPosition(btv, dragEvent);
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
index ea5df87..d790b4b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
@@ -186,6 +186,10 @@
animatorSet.play(stashController.applyStateWithoutStart(duration));
animatorSet.play(applyState(duration, false));
+ if (mTaskBarRecentsAnimationListener != null) {
+ mTaskBarRecentsAnimationListener.endGestureStateOverride(
+ !mLauncher.isInState(LauncherState.OVERVIEW));
+ }
mTaskBarRecentsAnimationListener = new TaskBarRecentsAnimationListener(callbacks);
callbacks.addListener(mTaskBarRecentsAnimationListener);
((RecentsView) mLauncher.getOverviewPanel()).setTaskLaunchListener(() ->
diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java
index 6c7bdbf..019e5a6 100644
--- a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java
@@ -61,6 +61,11 @@
public void onTaskStackChanged() {
mProxyView.close(false);
}
+
+ @Override
+ public void onTaskMovedToFront(int taskId) {
+ mProxyView.close(false);
+ }
};
private DeviceProfile mLauncherDeviceProfile;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
index fe0bca6..e3d386c 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
@@ -28,9 +28,9 @@
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.systemui.plugins.Plugin;
import com.android.systemui.plugins.PluginListener;
+import com.android.systemui.plugins.PluginManager;
import com.android.systemui.shared.plugins.PluginActionManager;
import com.android.systemui.shared.plugins.PluginInstance;
-import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.shared.plugins.PluginManagerImpl;
import com.android.systemui.shared.plugins.PluginPrefs;
import com.android.systemui.shared.system.UncaughtExceptionPreHandlerManager;
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index b09e531..4b35859 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -95,6 +95,7 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorPlaybackController;
+import com.android.launcher3.dragndrop.DragView;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.logging.StatsLogManager.StatsLogger;
import com.android.launcher3.statemanager.BaseState;
@@ -287,7 +288,7 @@
private AnimatorControllerWithResistance mLauncherTransitionController;
private boolean mHasEndedLauncherTransition;
- private AnimationFactory mAnimationFactory = (t, s) -> { };
+ private AnimationFactory mAnimationFactory = (t) -> { };
private boolean mWasLauncherAlreadyVisible;
@@ -317,6 +318,9 @@
private final int mTaskbarAppWindowThreshold;
private final int mTaskbarCatchUpThreshold;
private boolean mTaskbarAlreadyOpen;
+ private final boolean mIsTransientTaskbar;
+ // Only used when mIsTransientTaskbar is true.
+ private boolean mHasReachedHomeOverviewThreshold;
public AbsSwipeUpHandler(Context context, RecentsAnimationDeviceState deviceState,
TaskAnimationManager taskAnimationManager, GestureState gestureState,
@@ -343,6 +347,7 @@
mTaskbarAppWindowThreshold = res
.getDimensionPixelSize(R.dimen.taskbar_app_window_threshold);
mTaskbarCatchUpThreshold = res.getDimensionPixelSize(R.dimen.taskbar_catch_up_threshold);
+ mIsTransientTaskbar = DisplayController.isTransientTaskbar(mActivity);
mQuickSwitchScaleScrollThreshold = res
.getDimension(R.dimen.quick_switch_scaling_scroll_threshold);
@@ -531,9 +536,7 @@
Runnable initAnimFactory = () -> {
mAnimationFactory = mActivityInterface.prepareRecentsUI(mDeviceState,
mWasLauncherAlreadyVisible, this::onAnimatorPlaybackControllerCreated);
- maybeUpdateRecentsAttachedState(
- false /* animate */,
- new ActiveGestureLog.CompoundString("on Launcher start (animate=false)"));
+ maybeUpdateRecentsAttachedState(false /* animate */);
if (mGestureState.getEndTarget() != null) {
// Update the end target in case the gesture ended before we init.
mAnimationFactory.setEndTarget(mGestureState.getEndTarget());
@@ -638,8 +641,7 @@
}
private void initializeLauncherAnimationController() {
- buildAnimationController(new ActiveGestureLog.CompoundString(
- "initializing launcher animation controller"));
+ buildAnimationController();
Object traceToken = TraceHelper.INSTANCE.beginSection("logToggleRecents",
TraceHelper.FLAG_IGNORE_BINDERS);
@@ -658,11 +660,7 @@
@Override
public void onMotionPauseDetected() {
mHasMotionEverBeenPaused = true;
- maybeUpdateRecentsAttachedState(
- true/* animate */,
- true/* moveFocusedTask */,
- new ActiveGestureLog.CompoundString(
- "motion pause detected (animate=true)"));
+ maybeUpdateRecentsAttachedState(true/* animate */, true/* moveFocusedTask */);
Optional.ofNullable(mActivityInterface.getTaskbarController())
.ifPresent(TaskbarUIController::startTranslationSpring);
performHapticFeedback();
@@ -675,13 +673,12 @@
};
}
- private void maybeUpdateRecentsAttachedState(ActiveGestureLog.CompoundString reason) {
- maybeUpdateRecentsAttachedState(true /* animate */, reason.append(" (animate=true)"));
+ private void maybeUpdateRecentsAttachedState() {
+ maybeUpdateRecentsAttachedState(true /* animate */);
}
- private void maybeUpdateRecentsAttachedState(
- boolean animate, ActiveGestureLog.CompoundString reason) {
- maybeUpdateRecentsAttachedState(animate, false /* moveFocusedTask */, reason);
+ private void maybeUpdateRecentsAttachedState(boolean animate) {
+ maybeUpdateRecentsAttachedState(animate, false /* moveFocusedTask */);
}
/**
@@ -693,8 +690,7 @@
* @param animate whether to animate when attaching RecentsView
* @param moveFocusedTask whether to move focused task to front when attaching
*/
- private void maybeUpdateRecentsAttachedState(
- boolean animate, boolean moveFocusedTask, ActiveGestureLog.CompoundString reason) {
+ private void maybeUpdateRecentsAttachedState(boolean animate, boolean moveFocusedTask) {
if (!mDeviceState.isFullyGesturalNavMode() || mRecentsView == null) {
return;
}
@@ -704,25 +700,14 @@
final boolean recentsAttachedToAppWindow;
if (mGestureState.getEndTarget() != null) {
recentsAttachedToAppWindow = mGestureState.getEndTarget().recentsAttachedToAppWindow;
- reason.append("; gesture state end target != null (attached=")
- .append(Boolean.toString(recentsAttachedToAppWindow))
- .append(")");
} else if (mContinuingLastGesture
&& mRecentsView.getRunningTaskIndex() != mRecentsView.getNextPage()) {
recentsAttachedToAppWindow = true;
- reason.append("; continuing last gesture (attached=true)");
} else if (runningTaskTarget != null && isNotInRecents(runningTaskTarget)) {
// The window is going away so make sure recents is always visible in this case.
recentsAttachedToAppWindow = true;
- reason.append("; make sure recents is always visible (attached=true)");
} else {
recentsAttachedToAppWindow = mHasMotionEverBeenPaused || mIsLikelyToStartNewTask;
- reason.append(mHasMotionEverBeenPaused
- ? "; motion has been paused"
- : "; gesture is likely to start a new task")
- .append(" (attached=")
- .append(Boolean.toString(recentsAttachedToAppWindow))
- .append(")");
}
if (moveFocusedTask && !mAnimationFactory.hasRecentsEverAttachedToAppWindow()
&& recentsAttachedToAppWindow) {
@@ -730,8 +715,7 @@
// TaskView jumping to new position as we move the tasks.
mRecentsView.moveFocusedTaskToFront();
}
- mAnimationFactory.setRecentsAttachedToAppWindow(
- recentsAttachedToAppWindow, animate, reason);
+ mAnimationFactory.setRecentsAttachedToAppWindow(recentsAttachedToAppWindow, animate);
// Reapply window transform throughout the attach animation, as the animation affects how
// much the window is bound by overscroll (vs moving freely).
@@ -750,30 +734,38 @@
}
}
- public void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask) {
- setIsLikelyToStartNewTask(
- isLikelyToStartNewTask,
- true /* animate */,
- new ActiveGestureLog.CompoundString(
- "setting gesture likely to start (animate=true)"));
+ /**
+ * Sets whether or not we should clamp the scroll offset.
+ * This is used to avoid x-axis movement when swiping up transient taskbar.
+ * @param clampScrollOffset When true, we clamp the scroll to 0 before the clamp threshold is
+ * met.
+ */
+ public void setClampScrollOffset(boolean clampScrollOffset) {
+ if (mRecentsView == null) {
+ mStateCallback.runOnceAtState(STATE_LAUNCHER_PRESENT,
+ () -> mRecentsView.setClampScrollOffset(clampScrollOffset));
+ return;
+ }
+ mRecentsView.setClampScrollOffset(clampScrollOffset);
}
- private void setIsLikelyToStartNewTask(
- boolean isLikelyToStartNewTask,
- boolean animate,
- ActiveGestureLog.CompoundString reason) {
+ public void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask) {
+ setIsLikelyToStartNewTask(isLikelyToStartNewTask, true /* animate */);
+ }
+
+ private void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask, boolean animate) {
if (mIsLikelyToStartNewTask != isLikelyToStartNewTask) {
mIsLikelyToStartNewTask = isLikelyToStartNewTask;
- maybeUpdateRecentsAttachedState(animate, reason);
+ maybeUpdateRecentsAttachedState(animate);
}
}
- private void buildAnimationController(ActiveGestureLog.CompoundString reason) {
+ private void buildAnimationController() {
if (!canCreateNewOrUpdateExistingLauncherTransitionController()) {
return;
}
initTransitionEndpoints(mActivity.getDeviceProfile());
- mAnimationFactory.createActivityInterface(mTransitionDragLength, reason);
+ mAnimationFactory.createActivityInterface(mTransitionDragLength);
}
/**
@@ -788,7 +780,7 @@
@Override
public WindowInsets onApplyWindowInsets(View view, WindowInsets windowInsets) {
WindowInsets result = view.onApplyWindowInsets(windowInsets);
- buildAnimationController(new ActiveGestureLog.CompoundString("applying window insets"));
+ buildAnimationController();
// Reapply the current shift to ensure it takes new insets into account, e.g. when long
// pressing to stash taskbar without moving the finger.
updateFinalShift();
@@ -819,7 +811,7 @@
@UiThread
@Override
public void updateFinalShift() {
- final boolean passed = mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW;
+ final boolean passed = hasReachedHomeOverviewThreshold();
if (passed != mPassedOverviewThreshold) {
mPassedOverviewThreshold = passed;
if (mDeviceState.isTwoButtonNavMode() && !mGestureState.isHandlingAtomicEvent()) {
@@ -962,10 +954,7 @@
});
}
notifyGestureStartedAsync();
- setIsLikelyToStartNewTask(
- isLikelyToStartNewTask,
- false /* animate */,
- new ActiveGestureLog.CompoundString("on gesture started (animate=false)"));
+ setIsLikelyToStartNewTask(isLikelyToStartNewTask, false /* animate */);
mStateCallback.setStateOnUiThread(STATE_GESTURE_STARTED);
mGestureStarted = true;
}
@@ -1046,8 +1035,7 @@
private void onSettledOnEndTarget() {
// Fast-finish the attaching animation if it's still running.
- maybeUpdateRecentsAttachedState(false, new ActiveGestureLog.CompoundString(
- "on settled on end target (animate=false)"));
+ maybeUpdateRecentsAttachedState(false);
final GestureEndTarget endTarget = mGestureState.getEndTarget();
// Wait until the given View (if supplied) draws before resuming the last task.
View postResumeLastTask = mActivityInterface.onSettledOnEndTarget(endTarget);
@@ -1145,16 +1133,16 @@
}
if (!mDeviceState.isFullyGesturalNavMode()) {
- return (!hasReachedOverviewThreshold() && willGoToNewTask) ? NEW_TASK : RECENTS;
+ return (!hasReachedHomeOverviewThreshold() && willGoToNewTask) ? NEW_TASK : RECENTS;
}
return willGoToNewTask ? NEW_TASK : HOME;
}
private GestureEndTarget calculateEndTargetForNonFling(PointF velocity) {
final boolean isScrollingToNewTask = isScrollingToNewTask();
- final boolean reachedOverviewThreshold = hasReachedOverviewThreshold();
+ final boolean reachedHomeOverviewThreshold = hasReachedHomeOverviewThreshold();
if (!mDeviceState.isFullyGesturalNavMode()) {
- return reachedOverviewThreshold && mGestureStarted
+ return reachedHomeOverviewThreshold && mGestureStarted
? RECENTS
: (isScrollingToNewTask ? NEW_TASK : LAST_TASK);
}
@@ -1170,7 +1158,7 @@
return RECENTS;
} else if (isScrollingToNewTask) {
return NEW_TASK;
- } else if (reachedOverviewThreshold) {
+ } else if (reachedHomeOverviewThreshold) {
return HOME;
}
return LAST_TASK;
@@ -1189,8 +1177,22 @@
return runningTaskIndex >= 0 && mRecentsView.getNextPage() != runningTaskIndex;
}
- private boolean hasReachedOverviewThreshold() {
- return getTaskbarProgress() > MIN_PROGRESS_FOR_OVERVIEW;
+ /**
+ * Sets whether the current swipe has reached the threshold where if user lets go they would
+ * go to either the home state or overview state.
+ */
+ public void setHasReachedHomeOverviewThreshold(boolean hasReachedHomeOverviewThreshold) {
+ mHasReachedHomeOverviewThreshold = hasReachedHomeOverviewThreshold;
+ }
+
+ /**
+ * Returns true iff swipe has reached the overview threshold.
+ */
+ public boolean hasReachedHomeOverviewThreshold() {
+ if (mIsTransientTaskbar) {
+ return mHasReachedHomeOverviewThreshold;
+ }
+ return mCurrentShift.value > MIN_PROGRESS_FOR_OVERVIEW;
}
@UiThread
@@ -1357,12 +1359,15 @@
@UiThread
private void animateToProgressInternal(float start, float end, long duration,
Interpolator interpolator, GestureEndTarget target, PointF velocityPxPerMs) {
- maybeUpdateRecentsAttachedState(new ActiveGestureLog.CompoundString(
- "animate to progress internal"));
+ maybeUpdateRecentsAttachedState();
// If we are transitioning to launcher, then listen for the activity to be restarted while
// the transition is in progress
if (mGestureState.getEndTarget().isLauncher) {
+ // This is also called when the launcher is resumed, in order to clear the pending
+ // widgets that have yet to be configured.
+ DragView.removeAllViews(mActivity);
+
TaskStackChangeListeners.getInstance().registerTaskStackListener(
mActivityRestartListener);
@@ -1677,9 +1682,7 @@
mRecentsView.post(mRecentsView::resetTaskVisuals);
}
// Make sure recents is in its final state
- maybeUpdateRecentsAttachedState(
- false, new ActiveGestureLog.CompoundString(
- "setting up window animation (animate=false)"));
+ maybeUpdateRecentsAttachedState(false);
mActivityInterface.onSwipeUpToHomeComplete(mDeviceState);
}
});
@@ -2267,7 +2270,7 @@
* There is also a catch up period so that the window can start moving 1:1 with the swipe.
*/
private float getTaskbarProgress() {
- if (!DisplayController.isTransientTaskbar(mContext)) {
+ if (!mIsTransientTaskbar) {
return mCurrentShift.value;
}
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index 2c3ba85..274b686 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -60,7 +60,6 @@
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.NavigationMode;
import com.android.launcher3.views.ScrimView;
-import com.android.quickstep.util.ActiveGestureLog;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.views.RecentsView;
@@ -399,16 +398,14 @@
public interface AnimationFactory {
- void createActivityInterface(long transitionLength, ActiveGestureLog.CompoundString reason);
+ void createActivityInterface(long transitionLength);
/**
* @param attached Whether to show RecentsView alongside the app window. If false, recents
* will be hidden by some property we can animate, e.g. alpha.
* @param animate Whether to animate recents to/from its new attached state.
- * @param reason Explanation for why this method is being called with the given param values
*/
- default void setRecentsAttachedToAppWindow(
- boolean attached, boolean animate, ActiveGestureLog.CompoundString reason) { }
+ default void setRecentsAttachedToAppWindow(boolean attached, boolean animate) { }
default boolean isRecentsAttachedToAppWindow() {
return false;
@@ -450,8 +447,7 @@
}
@Override
- public void createActivityInterface(
- long transitionLength, ActiveGestureLog.CompoundString reason) {
+ public void createActivityInterface(long transitionLength) {
PendingAnimation pa = new PendingAnimation(transitionLength * 2);
createBackgroundToOverviewAnim(mActivity, pa);
AnimatorPlaybackController controller = pa.createPlaybackController();
@@ -474,29 +470,13 @@
// (because we set the animation as the current state animation), so we reapply the
// attached state here as well to ensure recents is shown/hidden appropriately.
if (DisplayController.getNavigationMode(mActivity) == NavigationMode.NO_BUTTON) {
- setRecentsAttachedToAppWindow(
- mIsAttachedToWindow,
- false,
- reason.append("; reapplying the attached state (attached=")
- .append(Boolean.toString(mIsAttachedToWindow))
- .append(", animate=false)"));
+ setRecentsAttachedToAppWindow(mIsAttachedToWindow, false);
}
}
@Override
- public void setRecentsAttachedToAppWindow(
- boolean attached, boolean animate, ActiveGestureLog.CompoundString reason) {
- // TODO(b/244593270): remove these logs; too verbose
- ActiveGestureLog.INSTANCE.addLog(
- new ActiveGestureLog.CompoundString("setRecentsAttachedToAppWindow: attached=")
- .append(Boolean.toString(attached))
- .append(", animate=")
- .append(Boolean.toString(animate))
- .append(", reason=")
- .append(reason));
+ public void setRecentsAttachedToAppWindow(boolean attached, boolean animate) {
if (mIsAttachedToWindow == attached && animate) {
- ActiveGestureLog.INSTANCE.addLog(new ActiveGestureLog.CompoundString(
- "setRecentsAttachedToAppWindow: exiting early"));
return;
}
mActivity.getStateManager()
@@ -525,11 +505,6 @@
float fromTranslation = ADJACENT_PAGE_HORIZONTAL_OFFSET.get(
mActivity.getOverviewPanel());
float toTranslation = attached ? 0 : 1;
- ActiveGestureLog.INSTANCE.addLog(new ActiveGestureLog.CompoundString(
- "setRecentsAttachedToAppWindow: fromTranslation=")
- .append(Float.toString(fromTranslation))
- .append(", toTranslation=")
- .append(Float.toString(toTranslation)));
Animator translationAnimator = mActivity.getStateManager().createStateElementAnimation(
INDEX_RECENTS_TRANSLATE_X_ANIM, fromTranslation, toTranslation);
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
index 8410149..db7e087 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
@@ -53,6 +53,7 @@
import com.android.quickstep.RecentsAnimationController;
import com.android.quickstep.RecentsAnimationDeviceState;
import com.android.quickstep.RecentsAnimationTargets;
+import com.android.quickstep.RemoteAnimationTargets;
import com.android.quickstep.TaskAnimationManager;
import com.android.quickstep.util.SurfaceTransaction.SurfaceProperties;
import com.android.quickstep.util.TransformParams;
@@ -226,6 +227,10 @@
mStateCallback.setState(STATE_HANDLER_INVALIDATED);
}
});
+ RemoteAnimationTargets targets = mTransformParams.getTargetSet();
+ if (targets != null) {
+ targets.addReleaseCheck(new DeviceLockedReleaseCheck(animator));
+ }
animator.start();
} else {
mStateCallback.setState(STATE_HANDLER_INVALIDATED);
@@ -304,4 +309,27 @@
public boolean allowInterceptByParent() {
return !mThresholdCrossed;
}
+
+ private static final class DeviceLockedReleaseCheck extends
+ RemoteAnimationTargets.ReleaseCheck {
+
+ private DeviceLockedReleaseCheck(Animator animator) {
+ setCanRelease(true);
+
+ animator.addListener(new AnimatorListenerAdapter() {
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+ super.onAnimationStart(animation);
+ setCanRelease(false);
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ setCanRelease(true);
+ }
+ });
+ }
+ }
}
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
index b3d3c3d..f842fd0 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
@@ -36,7 +36,6 @@
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
-import android.content.res.Resources;
import android.graphics.PointF;
import android.os.Build;
import android.util.Log;
@@ -151,10 +150,6 @@
mHandlerFactory = handlerFactory;
mActivityInterface = mGestureState.getActivityInterface();
- Resources res = base.getResources();
- mTaskbarHomeOverviewThreshold = res
- .getDimensionPixelSize(R.dimen.taskbar_home_overview_threshold);
-
mMotionPauseDetector = new MotionPauseDetector(base, false,
mNavBarPosition.isLeftEdge() || mNavBarPosition.isRightEdge()
? MotionEvent.AXIS_X : MotionEvent.AXIS_Y);
@@ -168,6 +163,8 @@
TaskbarUIController controller = mActivityInterface.getTaskbarController();
mTaskbarAlreadyOpen = controller != null && !controller.isTaskbarStashed();
mIsTransientTaskbar = DisplayController.isTransientTaskbar(base);
+ mTaskbarHomeOverviewThreshold = base.getResources()
+ .getDimensionPixelSize(R.dimen.taskbar_home_overview_threshold);
boolean continuingPreviousGesture = mTaskAnimationManager.isRecentsAnimationRunning();
mIsDeferredDownTarget = !continuingPreviousGesture && isDeferredDownTarget;
@@ -340,13 +337,12 @@
}
if (mDeviceState.isFullyGesturalNavMode()) {
- float minDisplacement = mMotionPauseMinDisplacement;
-
- if (mIsTransientTaskbar && !mTaskbarAlreadyOpen) {
- minDisplacement += mTaskbarHomeOverviewThreshold;
+ boolean minSwipeMet = upDist >= mMotionPauseMinDisplacement;
+ if (mIsTransientTaskbar) {
+ minSwipeMet = upDist >= mTaskbarHomeOverviewThreshold;
+ mInteractionHandler.setHasReachedHomeOverviewThreshold(minSwipeMet);
}
-
- mMotionPauseDetector.setDisallowPause(upDist < minDisplacement
+ mMotionPauseDetector.setDisallowPause(!minSwipeMet
|| isLikelyToStartNewTask);
mMotionPauseDetector.addPosition(ev);
mInteractionHandler.setIsLikelyToStartNewTask(isLikelyToStartNewTask);
@@ -382,6 +378,9 @@
mInteractionHandler.onGestureStarted(isLikelyToStartNewTask);
mInteractionHandler.setTaskbarAlreadyOpen(mTaskbarAlreadyOpen);
+ if (mIsTransientTaskbar && !mTaskbarAlreadyOpen && !isLikelyToStartNewTask) {
+ mInteractionHandler.setClampScrollOffset(true);
+ }
}
private void startTouchTrackingForWindowAnimation(long touchTimeMs) {
@@ -477,6 +476,9 @@
@UiThread
private void onInteractionGestureFinished() {
Preconditions.assertUIThread();
+ if (mInteractionHandler != null) {
+ mInteractionHandler.setClampScrollOffset(false);
+ }
removeListener();
mInteractionHandler = null;
cleanupAfterGesture();
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 80b41a7..5a26f32 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -498,6 +498,9 @@
private boolean mOverviewFullscreenEnabled;
private boolean mOverviewSelectEnabled;
+ private boolean mShouldClampScrollOffset;
+ private int mClampedScrollOffsetBound;
+
private float mAdjacentPageHorizontalOffset = 0;
protected float mTaskViewsSecondaryTranslation = 0;
protected float mTaskViewsPrimarySplitTranslation = 0;
@@ -752,6 +755,8 @@
mSplitPlaceholderInset = getResources().getDimensionPixelSize(
R.dimen.split_placeholder_inset);
mSquaredTouchSlop = squaredTouchSlop(context);
+ mClampedScrollOffsetBound = getResources().getDimensionPixelSize(
+ R.dimen.transient_taskbar_clamped_offset_bound);
mEmptyIcon = context.getDrawable(R.drawable.ic_empty_recents);
mEmptyIcon.setCallback(this);
@@ -5055,9 +5060,35 @@
}
/**
+ * Sets whether or not we should clamp the scroll offset.
+ * This is used to avoid x-axis movement when swiping up transient taskbar.
+ * Should only be set at the beginning and end of the gesture, otherwise a jump may occur.
+ * @param clampScrollOffset When true, we clamp the scroll to 0 before the clamp threshold is
+ * met.
+ */
+ public void setClampScrollOffset(boolean clampScrollOffset) {
+ mShouldClampScrollOffset = clampScrollOffset;
+ }
+
+ /**
* Returns how many pixels the page is offset on the currently laid out dominant axis.
*/
public int getScrollOffset(int pageIndex) {
+ int unboundedOffset = getUnclampedScrollOffset(pageIndex);
+ if (!mShouldClampScrollOffset) {
+ return unboundedOffset;
+ }
+ if (Math.abs(unboundedOffset) < mClampedScrollOffsetBound) {
+ return 0;
+ }
+ return unboundedOffset
+ - Math.round(Math.signum(unboundedOffset) * mClampedScrollOffsetBound);
+ }
+
+ /**
+ * Returns how many pixels the page is offset on the currently laid out dominant axis.
+ */
+ private int getUnclampedScrollOffset(int pageIndex) {
if (pageIndex == -1) {
return 0;
}
diff --git a/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt b/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt
index 6d47281..0c96539 100644
--- a/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt
+++ b/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt
@@ -94,8 +94,13 @@
params.setProgress(/* fullscreenProgress= */ 1.0f, /* parentScale= */ 1.0f,
/* taskViewScale= */ 1.0f, /* previewWidth= */ 0, dp, mPreviewPositionHelper)
+ // Probably unhelpful, but also unclear how to test otherwise ¯\_(ツ)_/¯
+ val fullscreenTaskHeight = (dp.heightPx - dp.taskbarSize) *
+ (1 - (splitBounds.topTaskPercent + splitBounds.dividerHeightPercent))
+ val canvasScreenRatio = canvasHeight / fullscreenTaskHeight
+ val expectedBottomHint = dp.taskbarSize * canvasScreenRatio
assertThat(params.mCurrentDrawnInsets.bottom)
- .isWithin(1f).of((dp.taskbarSize * TASK_SCALE))
+ .isWithin(1f).of(expectedBottomHint)
}
@Test
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 3b92ac4..50b7563 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -368,6 +368,7 @@
<dimen name="transient_taskbar_shadow_blur">0dp</dimen>
<dimen name="transient_taskbar_key_shadow_distance">0dp</dimen>
<dimen name="transient_taskbar_stashed_size">0dp</dimen>
+ <dimen name="transient_taskbar_clamped_offset_bound">0dp</dimen>
<!-- Note that this applies to both sides of all icons, so visible space is double this. -->
<dimen name="transient_taskbar_icon_spacing">0dp</dimen>
<!-- Note that this applies to both sides of all icons, so visible space is double this. -->
diff --git a/res/xml/paddings_handhelds.xml b/res/xml/paddings_handhelds.xml
new file mode 100644
index 0000000..b9549a6
--- /dev/null
+++ b/res/xml/paddings_handhelds.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2022 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.
+ -->
+
+<!-- Putting in the test/xml folder gives an error that maxEmptySpace doesn't exist -->
+<device-paddings xmlns:launcher="http://schemas.android.com/apk/res-auto" >
+
+ <device-padding
+ launcher:maxEmptySpace="9999dp">
+ <workspaceTopPadding
+ launcher:a="0.48"
+ launcher:b="0"/>
+ <workspaceBottomPadding
+ launcher:a="0.52"
+ launcher:b="0"/>
+ <hotseatBottomPadding
+ launcher:a="0"
+ launcher:b="0"/>
+ </device-padding>
+</device-paddings>
\ No newline at end of file
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 3cb3461..92530ea 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -498,10 +498,11 @@
extraSpace = updateAvailableDimensions(res);
// Now that we have all of the variables calculated, we can tune certain sizes.
- if (isScalableGrid && inv.devicePaddings != null) {
+ if (isScalableGrid && inv.devicePaddingId != INVALID_RESOURCE_HANDLE) {
// Paddings were created assuming no scaling, so we first unscale the extra space.
int unscaledExtraSpace = (int) (extraSpace / cellScaleToFit);
- DevicePadding padding = inv.devicePaddings.getDevicePadding(unscaledExtraSpace);
+ DevicePaddings devicePaddings = new DevicePaddings(context, inv.devicePaddingId);
+ DevicePadding padding = devicePaddings.getDevicePadding(unscaledExtraSpace);
int paddingWorkspaceTop = padding.getWorkspaceTopPadding(unscaledExtraSpace);
int paddingWorkspaceBottom = padding.getWorkspaceBottomPadding(unscaledExtraSpace);
@@ -1565,10 +1566,11 @@
writer.println(prefix + pxToDpStr("extraSpace", extraSpace));
writer.println(prefix + pxToDpStr("unscaled extraSpace", extraSpace / iconScale));
- if (inv.devicePaddings != null) {
+ if (inv.devicePaddingId != INVALID_RESOURCE_HANDLE) {
int unscaledExtraSpace = (int) (extraSpace / iconScale);
+ DevicePaddings devicePaddings = new DevicePaddings(context, inv.devicePaddingId);
writer.println(prefix + pxToDpStr("maxEmptySpace",
- inv.devicePaddings.getDevicePadding(unscaledExtraSpace).getMaxEmptySpacePx()));
+ devicePaddings.getDevicePadding(unscaledExtraSpace).getMaxEmptySpacePx()));
}
writer.println(prefix + pxToDpStr("workspaceTopPadding", workspaceTopPadding));
writer.println(prefix + pxToDpStr("workspaceBottomPadding", workspaceBottomPadding));
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 87f5210..1f97535 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -47,9 +47,9 @@
import androidx.annotation.DimenRes;
import androidx.annotation.IntDef;
-import androidx.annotation.Nullable;
import androidx.annotation.StyleRes;
import androidx.annotation.VisibleForTesting;
+import androidx.annotation.XmlRes;
import androidx.core.content.res.ResourcesCompat;
import com.android.launcher3.icons.DotRenderer;
@@ -172,7 +172,8 @@
* Do not query directly. see {@link DeviceProfile#isScalableGrid}.
*/
protected boolean isScalable;
- public int devicePaddingId;
+ @XmlRes
+ public int devicePaddingId = INVALID_RESOURCE_HANDLE;
public String dbFile;
public int defaultLayoutId;
@@ -184,9 +185,6 @@
*/
public List<DeviceProfile> supportedProfiles = Collections.EMPTY_LIST;
- @Nullable
- public DevicePaddings devicePaddings;
-
public Point defaultWallpaperSize;
public Rect defaultWidgetPadding;
@@ -385,10 +383,6 @@
allAppsIconSize = displayOption.allAppsIconSizes;
allAppsIconTextSize = displayOption.allAppsIconTextSizes;
- if (devicePaddingId != 0) {
- devicePaddings = new DevicePaddings(context, devicePaddingId);
- }
-
inlineQsb = closestProfile.inlineQsb;
// If the partner customization apk contains any grid overrides, apply them
@@ -826,7 +820,7 @@
isScalable = a.getBoolean(
R.styleable.GridDisplayOption_isScalable, false);
devicePaddingId = a.getResourceId(
- R.styleable.GridDisplayOption_devicePaddingId, 0);
+ R.styleable.GridDisplayOption_devicePaddingId, INVALID_RESOURCE_HANDLE);
int deviceCategory = a.getInt(R.styleable.GridDisplayOption_deviceCategory,
DEVICE_CATEGORY_ALL);
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 517bbf8..191d063 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -2385,6 +2385,9 @@
ItemInfo item = d.dragInfo;
final View child = (mDragInfo == null) ? null : mDragInfo.cell;
if (!nearestDropOccupied) {
+ mDragTargetLayout.performReorder((int) mDragViewVisualCenter[0],
+ (int) mDragViewVisualCenter[1], minSpanX, minSpanY, item.spanX, item.spanY,
+ child, mTargetCell, new int[2], CellLayout.MODE_SHOW_REORDER_HINT);
mDragTargetLayout.visualizeDropLocation(mTargetCell[0], mTargetCell[1],
item.spanX, item.spanY, d);
} else if ((mDragMode == DRAG_MODE_NONE || mDragMode == DRAG_MODE_REORDER)
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index d522d88..982f6a9 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -269,6 +269,10 @@
"ENABLE_SEARCH_RESULT_BACKGROUND_DRAWABLES", false,
"Enable option to replace decorator-based search result backgrounds with drawables");
+ public static final BooleanFlag TWO_PREDICTED_ROWS_ALL_APPS_SEARCH = new DeviceFlag(
+ "TWO_PREDICTED_ROWS_ALL_APPS_SEARCH", false,
+ "Use 2 rows of app predictions in All Apps search zero-state");
+
public static final BooleanFlag ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS = new DeviceFlag(
"ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS", true,
"Enable option to show keyboard when going to all-apps");
diff --git a/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt b/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt
index fe30fdc..4e166ce 100644
--- a/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt
+++ b/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt
@@ -16,7 +16,6 @@
package com.android.launcher3
import android.content.Context
-import android.graphics.Point
import android.graphics.PointF
import android.graphics.Rect
import android.util.SparseArray
@@ -26,7 +25,6 @@
import com.android.launcher3.util.WindowBounds
import org.junit.Before
import org.mockito.ArgumentMatchers.any
-import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mockito.mock
import java.io.PrintWriter
import java.io.StringWriter
@@ -42,9 +40,6 @@
protected var transposeLayoutWithOrientation: Boolean = false
protected var useTwoPanels: Boolean = false
protected var isGestureMode: Boolean = true
- protected var devicePaddingsMock: DevicePaddings = mock(DevicePaddings::class.java)
- protected var staticdevicePaddingsMock: DevicePaddings.DevicePadding =
- mock(DevicePaddings.DevicePadding::class.java)
@Before
fun setUp() {
@@ -83,11 +78,6 @@
whenever(info.isTablet(any())).thenReturn(false)
whenever(info.getDensityDpi()).thenReturn(420)
whenever(info.smallestSizeDp(any())).thenReturn(411f)
- whenever(devicePaddingsMock.getDevicePadding(anyInt())).thenReturn(staticdevicePaddingsMock)
- whenever(staticdevicePaddingsMock.getWorkspaceTopPadding(anyInt())).thenReturn(95)
- whenever(staticdevicePaddingsMock.getWorkspaceBottomPadding(anyInt())).thenReturn(116)
- whenever(staticdevicePaddingsMock.maxEmptySpacePx)
- .thenReturn(if (isVerticalBar) if (isGestureMode) 131 else 184 else 315)
this.isGestureMode = isGestureMode
transposeLayoutWithOrientation = true
@@ -152,7 +142,7 @@
inlineQsb = BooleanArray(4) { false }
- devicePaddings = devicePaddingsMock
+ devicePaddingId = R.xml.paddings_handhelds
}
}
@@ -169,13 +159,6 @@
whenever(info.isTablet(any())).thenReturn(true)
whenever(info.getDensityDpi()).thenReturn(320)
whenever(info.smallestSizeDp(any())).thenReturn(800f)
- whenever(devicePaddingsMock.getDevicePadding(anyInt())).thenReturn(staticdevicePaddingsMock)
- whenever(staticdevicePaddingsMock.getWorkspaceTopPadding(anyInt()))
- .thenReturn(if (isLandscape) 32 else 159)
- whenever(staticdevicePaddingsMock.getWorkspaceBottomPadding(anyInt()))
- .thenReturn(if (isLandscape) 72 else 203)
- whenever(staticdevicePaddingsMock.maxEmptySpacePx).thenReturn(if (isLandscape) 200 else 19998)
-
this.isGestureMode = isGestureMode
useTwoPanels = false
@@ -246,7 +229,7 @@
false
)
- devicePaddings = devicePaddingsMock
+ devicePaddingId = R.xml.paddings_handhelds
}
}
@@ -263,15 +246,6 @@
whenever(info.isTablet(any())).thenReturn(true)
whenever(info.getDensityDpi()).thenReturn(420)
whenever(info.smallestSizeDp(any())).thenReturn(700f)
- whenever(devicePaddingsMock.getDevicePadding(anyInt())).thenReturn(staticdevicePaddingsMock)
-
- val topPadding = if (isLandscape) 18 else 89
- val bottomPadding = if (isLandscape) 39 else 146
- val maxEmptySpace = if (isLandscape) 131 else 236
- whenever(staticdevicePaddingsMock.getWorkspaceTopPadding(anyInt())).thenReturn(topPadding)
- whenever(staticdevicePaddingsMock.getWorkspaceBottomPadding(anyInt()))
- .thenReturn(bottomPadding)
- whenever(staticdevicePaddingsMock.maxEmptySpacePx).thenReturn(maxEmptySpace)
this.isGestureMode = isGestureMode
useTwoPanels = true
@@ -342,7 +316,7 @@
false
)
- devicePaddings = devicePaddingsMock
+ devicePaddingId = R.xml.paddings_handhelds
}
}