Merge "Fix touch focus not updated correctly after launching overview with live tile." into udc-dev
diff --git a/protos/launcher_atom.proto b/protos/launcher_atom.proto
index bf84820..55301ff 100644
--- a/protos/launcher_atom.proto
+++ b/protos/launcher_atom.proto
@@ -135,7 +135,7 @@
}
}
-// Next value 44
+// Next value 45
enum Attribute {
option allow_alias = true;
@@ -173,6 +173,7 @@
ALL_APPS_SEARCH_RESULT_SLICE = 19;
ALL_APPS_SEARCH_RESULT_WIDGETS = 20;
ALL_APPS_SEARCH_RESULT_PLAY = 21;
+ ALL_APPS_SEARCH_RESULT_PLAY_GMS = 44;
ALL_APPS_SEARCH_RESULT_FALLBACK = 22;
ALL_APPS_SEARCH_RESULT_SUGGEST = 22 [deprecated = true];
ALL_APPS_SEARCH_RESULT_ASSISTANT = 23;
diff --git a/protos/launcher_trace.proto b/protos/launcher_trace.proto
index 65fcfe5..e5a86a0 100644
--- a/protos/launcher_trace.proto
+++ b/protos/launcher_trace.proto
@@ -63,5 +63,6 @@
RECENTS = 2;
NEW_TASK = 3;
LAST_TASK = 4;
+ ALL_APPS = 5;
}
}
diff --git a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
index 18fe30d..5d4e19d 100644
--- a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
+++ b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
@@ -196,14 +196,13 @@
finish();
}
});
- mAnimator.start();
-
if (skipFirstFrame) {
// Because t=0 has the app icon in its original spot, we can skip the
// first frame and have the same movement one frame earlier.
mAnimator.setCurrentPlayTime(
Math.min(getSingleFrameMs(context), mAnimator.getTotalDuration()));
}
+ mAnimator.start();
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupController.kt
index 8dbc51a..83a3343 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupController.kt
@@ -38,14 +38,21 @@
view.post {
val popupView = createAndPopulate(view, context)
popupView.requestFocus()
- popupView.onCloseCallback = {
- context.onPopupVisibilityChanged(false)
- if (launcherPrefs.get(TASKBAR_PINNING)) {
- animateTransientToPersistentTaskBar()
- } else {
- animatePersistentToTransientTaskbar()
+
+ popupView.onCloseCallback =
+ callback@{ didPreferenceChange ->
+ context.dragLayer.post { context.onPopupVisibilityChanged(false) }
+
+ if (!didPreferenceChange) {
+ return@callback
+ }
+
+ if (launcherPrefs.get(TASKBAR_PINNING)) {
+ animateTransientToPersistentTaskbar()
+ } else {
+ animatePersistentToTransientTaskbar()
+ }
}
- }
popupView.changePreference = {
launcherPrefs.put(TASKBAR_PINNING, !launcherPrefs.get(TASKBAR_PINNING))
}
@@ -55,7 +62,7 @@
}
// TODO(b/265436799): provide animation/transition from transient taskbar to persistent one
- private fun animateTransientToPersistentTaskBar() {}
+ private fun animateTransientToPersistentTaskbar() {}
// TODO(b/265436799): provide animation/transition from persistent taskbar to transient one
private fun animatePersistentToTransientTaskbar() {}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupView.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupView.kt
index 2000d98..e07f0c0 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupView.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupView.kt
@@ -17,6 +17,7 @@
import android.annotation.SuppressLint
import android.content.Context
+import android.content.Intent
import android.graphics.Rect
import android.util.AttributeSet
import android.view.Gravity
@@ -42,6 +43,9 @@
companion object {
private const val TAG = "TaskbarDividerPopupView"
private const val DIVIDER_POPUP_CLOSING_DELAY = 500L
+ private const val SETTINGS_PACKAGE_NAME = "com.android.settings"
+ private const val CHANGE_NAVIGATION_MODE_ACTION =
+ "com.android.settings.NAVIGATION_MODE_SETTINGS"
@JvmStatic
fun createAndPopulate(
@@ -71,7 +75,7 @@
private var didPreferenceChange = false
/** Callback invoked when the pinning popup view is closing. */
- var onCloseCallback: () -> Unit = {}
+ var onCloseCallback: (preferenceChanged: Boolean) -> Unit = {}
/**
* Callback invoked when the user preference changes in popup view. Preference change will be
@@ -98,12 +102,21 @@
super.onFinishInflate()
val taskbarSwitchOption = findViewById<LinearLayout>(R.id.taskbar_switch_option)
val alwaysShowTaskbarSwitch = findViewById<Switch>(R.id.taskbar_pinning_switch)
+ val navigationModeChangeOption =
+ findViewById<LinearLayout>(R.id.navigation_mode_switch_option)
alwaysShowTaskbarSwitch.isChecked = alwaysShowTaskbarOn
taskbarSwitchOption.setOnClickListener {
alwaysShowTaskbarSwitch.isClickable = true
alwaysShowTaskbarSwitch.isChecked = !alwaysShowTaskbarOn
onClickAlwaysShowTaskbarSwitchOption()
}
+ navigationModeChangeOption.setOnClickListener {
+ context.startActivity(
+ Intent(CHANGE_NAVIGATION_MODE_ACTION)
+ .setPackage(SETTINGS_PACKAGE_NAME)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ )
+ }
}
/** Orient object as usual and then center object horizontally. */
@@ -156,9 +169,7 @@
}
override fun closeComplete() {
- if (didPreferenceChange) {
- onCloseCallback()
- }
+ onCloseCallback(didPreferenceChange)
super.closeComplete()
}
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index d64347f..b7a29e0 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -39,6 +39,7 @@
import static com.android.launcher3.util.SystemUiController.UI_STATE_FULLSCREEN_TASK;
import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
+import static com.android.quickstep.GestureState.GestureEndTarget.ALL_APPS;
import static com.android.quickstep.GestureState.GestureEndTarget.HOME;
import static com.android.quickstep.GestureState.GestureEndTarget.LAST_TASK;
import static com.android.quickstep.GestureState.GestureEndTarget.NEW_TASK;
@@ -161,6 +162,9 @@
private static final ArrayList<String> STATE_NAMES = new ArrayList<>();
+ /** Shift distance to transition to All Apps if ENABLE_ALL_APPS_FROM_OVERVIEW. */
+ public static final float ALL_APPS_SHIFT_THRESHOLD = 2f;
+
protected final BaseActivityInterface<S, T> mActivityInterface;
protected final InputConsumerProxy mInputConsumerProxy;
protected final ActivityInitListener mActivityInitListener;
@@ -247,6 +251,8 @@
getNextStateFlag("STATE_CURRENT_TASK_FINISHED");
private static final int STATE_FINISH_WITH_NO_END =
getNextStateFlag("STATE_FINISH_WITH_NO_END");
+ private static final int STATE_SETTLED_ON_ALL_APPS =
+ getNextStateFlag("STATE_SETTLED_ON_ALL_APPS");
private static final int LAUNCHER_UI_STATES =
STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN | STATE_LAUNCHER_STARTED |
@@ -299,6 +305,7 @@
private boolean mGestureStarted;
private boolean mLogDirectionUpOrLeft = true;
private boolean mIsLikelyToStartNewTask;
+ private boolean mIsInAllAppsRegion;
private final long mTouchTimeMs;
private long mLauncherFrameDrawnTime;
@@ -432,6 +439,9 @@
this::finishCurrentTransitionToHome);
mStateCallback.runOnceAtState(STATE_SCALED_CONTROLLER_HOME | STATE_CURRENT_TASK_FINISHED,
this::reset);
+ mStateCallback.runOnceAtState(STATE_SETTLED_ON_ALL_APPS | STATE_SCREENSHOT_CAPTURED
+ | STATE_GESTURE_COMPLETED,
+ this::finishCurrentTransitionToAllApps);
mStateCallback.runOnceAtState(STATE_LAUNCHER_PRESENT | STATE_APP_CONTROLLER_RECEIVED
| STATE_LAUNCHER_DRAWN | STATE_SCALED_CONTROLLER_RECENTS
@@ -681,7 +691,9 @@
maybeUpdateRecentsAttachedState(true/* animate */, true/* moveRunningTask */);
Optional.ofNullable(mActivityInterface.getTaskbarController())
.ifPresent(TaskbarUIController::startTranslationSpring);
- performHapticFeedback();
+ if (!mIsInAllAppsRegion) {
+ performHapticFeedback();
+ }
}
@Override
@@ -695,7 +707,7 @@
maybeUpdateRecentsAttachedState(true /* animate */);
}
- private void maybeUpdateRecentsAttachedState(boolean animate) {
+ protected void maybeUpdateRecentsAttachedState(boolean animate) {
maybeUpdateRecentsAttachedState(animate, false /* moveRunningTask */);
}
@@ -716,7 +728,9 @@
? mRecentsAnimationTargets.findTask(mGestureState.getRunningTaskId())
: null;
final boolean recentsAttachedToAppWindow;
- if (mGestureState.getEndTarget() != null) {
+ if (mIsInAllAppsRegion) {
+ recentsAttachedToAppWindow = false;
+ } else if (mGestureState.getEndTarget() != null) {
recentsAttachedToAppWindow = mGestureState.getEndTarget().recentsAttachedToAppWindow;
} else if (mContinuingLastGesture
&& mRecentsView.getRunningTaskIndex() != mRecentsView.getNextPage()) {
@@ -772,6 +786,26 @@
}
}
+ /**
+ * Update whether user is currently dragging in a region that will trigger all apps.
+ */
+ private void setIsInAllAppsRegion(boolean isInAllAppsRegion) {
+ if (mIsInAllAppsRegion == isInAllAppsRegion
+ || !mActivityInterface.allowAllAppsFromOverview()) {
+ return;
+ }
+ mIsInAllAppsRegion = isInAllAppsRegion;
+
+ // Newly entering or exiting the zone - do haptic and animate recent tasks.
+ VibratorWrapper.INSTANCE.get(mContext).vibrate(OVERVIEW_HAPTIC);
+ maybeUpdateRecentsAttachedState(true);
+
+ // Draw active task below Launcher so that All Apps can appear over it.
+ runActionOnRemoteHandles(remoteTargetHandle ->
+ remoteTargetHandle.getTaskViewSimulator().setDrawsBelowRecents(isInAllAppsRegion));
+ }
+
+
private void buildAnimationController() {
if (!canCreateNewOrUpdateExistingLauncherTransitionController()) {
return;
@@ -792,10 +826,15 @@
@Override
public WindowInsets onApplyWindowInsets(View view, WindowInsets windowInsets) {
WindowInsets result = view.onApplyWindowInsets(windowInsets);
+ // Don't rebuild animation when we are animating the IME, because it will cause a loop
+ // where the insets change -> animation changes (updating ime) -> insets change -> ...
+ if (windowInsets.isVisible(WindowInsets.Type.ime())) {
+ return result;
+ }
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();
+ onCurrentShiftUpdated();
return result;
}
@@ -822,7 +861,8 @@
*/
@UiThread
@Override
- public void updateFinalShift() {
+ public void onCurrentShiftUpdated() {
+ setIsInAllAppsRegion(mCurrentShift.value >= ALL_APPS_SHIFT_THRESHOLD);
updateSysUiFlags(mCurrentShift.value);
applyScrollAndTransform();
@@ -1085,6 +1125,9 @@
}
switch (endTarget) {
+ case ALL_APPS:
+ mStateCallback.setState(STATE_SETTLED_ON_ALL_APPS | STATE_CAPTURE_SCREENSHOT);
+ break;
case HOME:
mStateCallback.setState(STATE_SCALED_CONTROLLER_HOME | STATE_CAPTURE_SCREENSHOT);
// Notify the SysUI to use fade-in animation when entering PiP
@@ -1173,6 +1216,9 @@
final boolean willGoToNewTask =
isScrollingToNewTask() && Math.abs(velocity.x) > Math.abs(endVelocity);
final boolean isSwipeUp = endVelocity < 0;
+ if (mIsInAllAppsRegion) {
+ return isSwipeUp ? ALL_APPS : LAST_TASK;
+ }
if (!isSwipeUp) {
final boolean isCenteredOnNewTask =
mRecentsView.getDestinationPage() != mRecentsView.getRunningTaskIndex();
@@ -1188,7 +1234,9 @@
// Fully gestural mode.
final boolean isFlingX = Math.abs(velocity.x) > mContext.getResources()
.getDimension(R.dimen.quickstep_fling_threshold_speed);
- if (isScrollingToNewTask && isFlingX) {
+ if (mIsInAllAppsRegion) {
+ return ALL_APPS;
+ } else if (isScrollingToNewTask && isFlingX) {
// Flinging towards new task takes precedence over mIsMotionPaused (which only
// checks y-velocity).
return NEW_TASK;
@@ -1236,7 +1284,8 @@
mGestureState.setEndTarget(endTarget, false /* isAtomic */);
mAnimationFactory.setEndTarget(endTarget);
- float endShift = endTarget.isLauncher ? 1 : 0;
+ float endShift = endTarget == ALL_APPS ? mDragLengthFactor
+ : endTarget.isLauncher ? 1 : 0;
final float startShift;
if (!isFling) {
long expectedDuration = Math.abs(Math.round((endShift - currentShift)
@@ -1793,6 +1842,12 @@
reset();
}
+ @UiThread
+ private void finishCurrentTransitionToAllApps() {
+ finishCurrentTransitionToHome();
+ reset();
+ }
+
private void reset() {
mStateCallback.setStateOnUiThread(STATE_HANDLER_INVALIDATED);
if (mActivity != null) {
@@ -1926,7 +1981,8 @@
private boolean updateThumbnail(int runningTaskId, boolean refreshView) {
boolean finishTransitionPosted = false;
final TaskView taskView;
- if (mGestureState.getEndTarget() == HOME || mGestureState.getEndTarget() == NEW_TASK) {
+ if (mGestureState.getEndTarget() == HOME || mGestureState.getEndTarget() == NEW_TASK
+ || mGestureState.getEndTarget() == ALL_APPS) {
// Capture the screenshot before finishing the transition to home or quickswitching to
// ensure it's taken in the correct orientation, but no need to update the thumbnail.
taskView = null;
@@ -2072,7 +2128,7 @@
private void onRecentsViewScroll() {
if (moveWindowWithRecentsScroll()) {
- updateFinalShift();
+ onCurrentShiftUpdated();
}
}
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index fd7aa58..60083c6 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -187,6 +187,9 @@
public abstract boolean allowMinimizeSplitScreen();
+ /** @return whether to allow going to All Apps from Overview. */
+ public abstract boolean allowAllAppsFromOverview();
+
public boolean deferStartingActivity(RecentsAnimationDeviceState deviceState, MotionEvent ev) {
return deviceState.isInDeferredGestureRegion(ev) || deviceState.isImeRenderingNavButtons()
|| isTrackpadMultiFingerSwipe(ev);
diff --git a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
index 8bb189a..5c96000 100644
--- a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
@@ -139,6 +139,11 @@
}
@Override
+ public boolean allowAllAppsFromOverview() {
+ return false;
+ }
+
+ @Override
public boolean deferStartingActivity(RecentsAnimationDeviceState deviceState, MotionEvent ev) {
// In non-gesture mode, user might be clicking on the home button which would directly
// start the home activity instead of going through recents. In that case, defer starting
@@ -196,6 +201,7 @@
case LAST_TASK:
return BACKGROUND_APP;
case HOME:
+ case ALL_APPS:
default:
return HOME;
}
diff --git a/quickstep/src/com/android/quickstep/GestureState.java b/quickstep/src/com/android/quickstep/GestureState.java
index 02f9f57..9d7ccb4 100644
--- a/quickstep/src/com/android/quickstep/GestureState.java
+++ b/quickstep/src/com/android/quickstep/GestureState.java
@@ -18,11 +18,13 @@
import static com.android.launcher3.MotionEventsUtils.isTrackpadFourFingerSwipe;
import static com.android.launcher3.MotionEventsUtils.isTrackpadMultiFingerSwipe;
import static com.android.launcher3.MotionEventsUtils.isTrackpadThreeFingerSwipe;
+import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_ALLAPPS;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_OVERVIEW;
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.SET_END_TARGET;
+import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.SET_END_TARGET_ALL_APPS;
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.SET_END_TARGET_HOME;
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.SET_END_TARGET_NEW_TASK;
@@ -68,7 +70,9 @@
GestureStateProto.GestureEndTarget.NEW_TASK),
LAST_TASK(false, LAUNCHER_STATE_BACKGROUND, true,
- GestureStateProto.GestureEndTarget.LAST_TASK);
+ GestureStateProto.GestureEndTarget.LAST_TASK),
+
+ ALL_APPS(true, LAUNCHER_STATE_ALLAPPS, false, GestureStateProto.GestureEndTarget.ALL_APPS);
GestureEndTarget(boolean isLauncher, int containerType, boolean recentsAttachedToAppWindow,
GestureStateProto.GestureEndTarget protoEndTarget) {
@@ -385,6 +389,9 @@
case NEW_TASK:
ActiveGestureLog.INSTANCE.trackEvent(SET_END_TARGET_NEW_TASK);
break;
+ case ALL_APPS:
+ ActiveGestureLog.INSTANCE.trackEvent(SET_END_TARGET_ALL_APPS);
+ break;
case LAST_TASK:
case RECENTS:
default:
diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
index ea9f032..0e0b022 100644
--- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
@@ -15,6 +15,7 @@
*/
package com.android.quickstep;
+import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
@@ -39,6 +40,7 @@
import com.android.launcher3.LauncherInitListener;
import com.android.launcher3.LauncherState;
import com.android.launcher3.anim.PendingAnimation;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.statehandlers.DesktopVisibilityController;
import com.android.launcher3.statemanager.StateManager;
@@ -264,6 +266,11 @@
}
@Override
+ public boolean allowAllAppsFromOverview() {
+ return FeatureFlags.ENABLE_ALL_APPS_FROM_OVERVIEW.get();
+ }
+
+ @Override
public boolean isInLiveTileMode() {
Launcher launcher = getCreatedActivity();
return launcher != null && launcher.getStateManager().getState() == OVERVIEW &&
@@ -347,6 +354,8 @@
case NEW_TASK:
case LAST_TASK:
return BACKGROUND_APP;
+ case ALL_APPS:
+ return ALL_APPS;
case HOME:
default:
return NORMAL;
diff --git a/quickstep/src/com/android/quickstep/RotationTouchHelper.java b/quickstep/src/com/android/quickstep/RotationTouchHelper.java
index 66d1e1e..8626c40 100644
--- a/quickstep/src/com/android/quickstep/RotationTouchHelper.java
+++ b/quickstep/src/com/android/quickstep/RotationTouchHelper.java
@@ -350,7 +350,8 @@
enableMultipleRegions(true);
}
activityInterface.onExitOverview(this, mExitOverviewRunnable);
- } else if (endTarget == GestureState.GestureEndTarget.HOME) {
+ } else if (endTarget == GestureState.GestureEndTarget.HOME
+ || endTarget == GestureState.GestureEndTarget.ALL_APPS) {
enableMultipleRegions(false);
} else if (endTarget == GestureState.GestureEndTarget.NEW_TASK) {
if (mOrientationTouchTransformer.getQuickStepStartingRotation() == -1) {
diff --git a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
index f913aff..1b4fdc4 100644
--- a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
+++ b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
@@ -67,7 +67,7 @@
// 0 => preview snapShot is completely visible, and hotseat is completely translated down
// 1 => preview snapShot is completely aligned with the recents view and hotseat is completely
// visible.
- protected final AnimatedFloat mCurrentShift = new AnimatedFloat(this::updateFinalShift);
+ protected final AnimatedFloat mCurrentShift = new AnimatedFloat(this::onCurrentShiftUpdated);
protected float mCurrentDisplacement;
// The distance needed to drag to reach the task size in recents.
@@ -148,7 +148,7 @@
* Called when the value of {@link #mCurrentShift} changes
*/
@UiThread
- public abstract void updateFinalShift();
+ public abstract void onCurrentShiftUpdated();
protected PagedOrientationHandler getOrientationHandler() {
// OrientationHandler should be independent of remote target, can directly take one
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index 512d47e..fdb30ce 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -967,7 +967,7 @@
IRemoteAnimationRunner runner) {
mBackToLauncherCallback = callback;
mBackToLauncherRunner = runner;
- if (mBackAnimation == null) {
+ if (mBackAnimation == null || mBackToLauncherCallback == null) {
return;
}
try {
diff --git a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
index b3243ff..a8af05e 100644
--- a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
@@ -309,7 +309,7 @@
}
@Override
- public void updateFinalShift() {
+ public void onCurrentShiftUpdated() {
mRemoteTargetHandles[0].getPlaybackController()
.setProgress(mCurrentShift.value, mDragLengthFactor);
mRemoteTargetHandles[0].getTaskViewSimulator().apply(
diff --git a/quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java b/quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java
index 6eadd2b..8335523 100644
--- a/quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java
+++ b/quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java
@@ -33,10 +33,11 @@
*/
public enum GestureEvent {
MOTION_DOWN, MOTION_UP, MOTION_MOVE, SET_END_TARGET, SET_END_TARGET_HOME,
- SET_END_TARGET_NEW_TASK, ON_SETTLED_ON_END_TARGET, START_RECENTS_ANIMATION,
- FINISH_RECENTS_ANIMATION, CANCEL_RECENTS_ANIMATION, SET_ON_PAGE_TRANSITION_END_CALLBACK,
- CANCEL_CURRENT_ANIMATION, CLEANUP_SCREENSHOT, SCROLLER_ANIMATION_ABORTED, TASK_APPEARED,
- EXPECTING_TASK_APPEARED, FLAG_USING_OTHER_ACTIVITY_INPUT_CONSUMER, LAUNCHER_DESTROYED,
+ SET_END_TARGET_NEW_TASK, SET_END_TARGET_ALL_APPS, ON_SETTLED_ON_END_TARGET,
+ START_RECENTS_ANIMATION, FINISH_RECENTS_ANIMATION, CANCEL_RECENTS_ANIMATION,
+ SET_ON_PAGE_TRANSITION_END_CALLBACK, CANCEL_CURRENT_ANIMATION, CLEANUP_SCREENSHOT,
+ SCROLLER_ANIMATION_ABORTED, TASK_APPEARED, EXPECTING_TASK_APPEARED,
+ FLAG_USING_OTHER_ACTIVITY_INPUT_CONSUMER, LAUNCHER_DESTROYED,
/**
* These GestureEvents are specifically associated to state flags that get set in
@@ -220,6 +221,7 @@
case MOTION_DOWN:
case SET_END_TARGET:
case SET_END_TARGET_HOME:
+ case SET_END_TARGET_ALL_APPS:
case SET_END_TARGET_NEW_TASK:
case START_RECENTS_ANIMATION:
case SET_ON_PAGE_TRANSITION_END_CALLBACK:
diff --git a/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java b/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java
index baca76c..a92ab2a 100644
--- a/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java
+++ b/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java
@@ -17,9 +17,11 @@
import static com.android.launcher3.anim.Interpolators.DEACCEL;
import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.quickstep.AbsSwipeUpHandler.ALL_APPS_SHIFT_THRESHOLD;
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
+import android.animation.AnimatorSet;
import android.animation.TimeInterpolator;
import android.content.Context;
import android.graphics.Matrix;
@@ -32,11 +34,15 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
+import com.android.launcher3.statemanager.StateManager;
+import com.android.launcher3.statemanager.StatefulActivity;
+import com.android.launcher3.states.StateAnimationConfig;
+import com.android.launcher3.touch.AllAppsSwipeController;
import com.android.launcher3.touch.PagedOrientationHandler;
-import com.android.quickstep.LauncherActivityInterface;
import com.android.quickstep.views.RecentsView;
/**
@@ -49,7 +55,9 @@
private enum RecentsResistanceParams {
FROM_APP(0.75f, 0.5f, 1f, false),
+ FROM_APP_TO_ALL_APPS(0.75f, 0.5f, 0.8f, false),
FROM_APP_TABLET(1f, 0.7f, 1f, true),
+ FROM_APP_TO_ALL_APPS_TABLET(1f, 0.5f, 0.5f, false),
FROM_OVERVIEW(1f, 0.75f, 0.5f, false);
RecentsResistanceParams(float scaleStartResist, float scaleMaxResist,
@@ -86,6 +94,8 @@
private static final TimeInterpolator RECENTS_SCALE_RESIST_INTERPOLATOR = DEACCEL;
private static final TimeInterpolator RECENTS_TRANSLATE_RESIST_INTERPOLATOR = LINEAR;
+ private static final Rect TEMP_RECT = new Rect();
+
private final AnimatorPlaybackController mNormalController;
private final AnimatorPlaybackController mResistanceController;
@@ -145,10 +155,42 @@
scaleProperty, translationTarget, translationProperty);
PendingAnimation resistAnim = createRecentsResistanceAnim(params);
+ // Apply All Apps animation during the resistance animation.
+ if (recentsOrientedState.getActivityInterface().allowAllAppsFromOverview()) {
+ StatefulActivity activity =
+ recentsOrientedState.getActivityInterface().getCreatedActivity();
+ if (activity != null) {
+ StateManager<LauncherState> stateManager = activity.getStateManager();
+ if (stateManager.isInStableState(LauncherState.BACKGROUND_APP)
+ && stateManager.isInTransition()) {
+
+ // Calculate the resistance progress threshold where All Apps will trigger.
+ float threshold = getAllAppsThreshold(context, recentsOrientedState, dp);
+
+ StateAnimationConfig config = new StateAnimationConfig();
+ AllAppsSwipeController.applyOverviewToAllAppsAnimConfig(dp, config, threshold);
+ AnimatorSet allAppsAnimator = stateManager.createAnimationToNewWorkspace(
+ LauncherState.ALL_APPS, config).getTarget();
+ resistAnim.add(allAppsAnimator);
+ }
+ }
+ }
+
AnimatorPlaybackController resistanceController = resistAnim.createPlaybackController();
return new AnimatorControllerWithResistance(normalController, resistanceController);
}
+ private static float getAllAppsThreshold(Context context,
+ RecentsOrientedState recentsOrientedState, DeviceProfile dp) {
+ int transitionDragLength =
+ recentsOrientedState.getActivityInterface().getSwipeUpDestinationAndLength(
+ dp, context, TEMP_RECT,
+ recentsOrientedState.getOrientationHandler());
+ float dragLengthFactor = (float) dp.heightPx / transitionDragLength;
+ // -1s are because 0-1 is reserved for the normal transition.
+ return (ALL_APPS_SHIFT_THRESHOLD - 1) / (dragLengthFactor - 1);
+ }
+
/**
* Creates the resistance animation for {@link #createForRecents}, or can be used separately
* when starting from recents, i.e. {@link #createRecentsResistanceFromOverviewAnim}.
@@ -158,8 +200,8 @@
Rect startRect = new Rect();
PagedOrientationHandler orientationHandler = params.recentsOrientedState
.getOrientationHandler();
- LauncherActivityInterface.INSTANCE.calculateTaskSize(params.context, params.dp, startRect,
- orientationHandler);
+ params.recentsOrientedState.getActivityInterface()
+ .calculateTaskSize(params.context, params.dp, startRect, orientationHandler);
long distanceToCover = startRect.bottom;
PendingAnimation resistAnim = params.resistAnim != null
? params.resistAnim
@@ -257,9 +299,15 @@
this.translationTarget = translationTarget;
this.translationProperty = translationProperty;
if (dp.isTablet) {
- resistanceParams = RecentsResistanceParams.FROM_APP_TABLET;
+ resistanceParams =
+ recentsOrientedState.getActivityInterface().allowAllAppsFromOverview()
+ ? RecentsResistanceParams.FROM_APP_TO_ALL_APPS_TABLET
+ : RecentsResistanceParams.FROM_APP_TABLET;
} else {
- resistanceParams = RecentsResistanceParams.FROM_APP;
+ resistanceParams =
+ recentsOrientedState.getActivityInterface().allowAllAppsFromOverview()
+ ? RecentsResistanceParams.FROM_APP_TO_ALL_APPS
+ : RecentsResistanceParams.FROM_APP;
}
}
diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
index c4ba39a..f6ad692 100644
--- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
+++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
@@ -116,6 +116,7 @@
| FLAG_SWIPE_UP_NOT_RUNNING;
private final Context mContext;
+ private final BaseActivityInterface mActivityInterface;
private final OrientationEventListener mOrientationListener;
private final SettingsCache mSettingsCache;
private final SettingsCache.OnChangeListener mRotationChangeListener =
@@ -135,9 +136,10 @@
* is enabled
* @see #setRotationWatcherEnabled(boolean)
*/
- public RecentsOrientedState(Context context, BaseActivityInterface sizeStrategy,
+ public RecentsOrientedState(Context context, BaseActivityInterface activityInterface,
IntConsumer rotationChangeListener) {
mContext = context;
+ mActivityInterface = activityInterface;
mOrientationListener = new OrientationEventListener(context) {
@Override
public void onOrientationChanged(int degrees) {
@@ -149,7 +151,7 @@
}
};
- mFlags = sizeStrategy.rotationSupportedByActivity
+ mFlags = mActivityInterface.rotationSupportedByActivity
? FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_ACTIVITY : 0;
mFlags |= FLAG_SWIPE_UP_NOT_RUNNING;
@@ -157,6 +159,10 @@
initFlags();
}
+ public BaseActivityInterface getActivityInterface() {
+ return mActivityInterface;
+ }
+
/**
* Sets the device profile for the current state.
*/
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index c165acc..697a1c1 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -17,6 +17,7 @@
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
+import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.CLEAR_ALL_BUTTON;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
@@ -129,7 +130,7 @@
@Override
public void onStateTransitionComplete(LauncherState finalState) {
- if (finalState == NORMAL || finalState == SPRING_LOADED) {
+ if (finalState == NORMAL || finalState == SPRING_LOADED || finalState == ALL_APPS) {
// Clean-up logic that occurs when recents is no longer in use/visible.
reset();
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 42589ce..53660b5 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -581,6 +581,7 @@
mIconView, STAGE_POSITION_UNDEFINED);
mSnapshotView.bind(task);
setOrientationState(orientedState);
+ mDigitalWellBeingToast.initialize(mTask);
}
/**
@@ -984,10 +985,7 @@
}
if (needsUpdate(changes, FLAG_UPDATE_ICON)) {
mIconLoadRequest = iconCache.updateIconInBackground(mTask,
- (task) -> {
- setIcon(mIconView, task.icon);
- mDigitalWellBeingToast.initialize(mTask);
- });
+ (task) -> setIcon(mIconView, task.icon));
}
} else {
if (needsUpdate(changes, FLAG_UPDATE_THUMBNAIL)) {
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java b/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java
index 6243471..4540eee 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java
@@ -27,6 +27,7 @@
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.launcher3.tapl.Overview;
import com.android.launcher3.tapl.Taskbar;
import com.android.launcher3.ui.TaplTestsLauncher3;
import com.android.launcher3.util.LauncherLayoutBuilder;
@@ -63,6 +64,10 @@
"com.android.launcher3.testcomponent.BaseTestingActivity");
mLauncherLayout = TestUtil.setLauncherDefaultLayout(mTargetContext, layoutBuilder);
TaplTestsLauncher3.initialize(this);
+ Overview overview = mLauncher.getWorkspace().switchToOverview();
+ if (overview.hasTasks()) {
+ overview.dismissAllTasks();
+ }
startAppFast(CALCULATOR_APP_PACKAGE);
mLauncher.enableBlockTimeout(true);
diff --git a/res/layout/launcher.xml b/res/layout/launcher.xml
index 039d8d3..a709fbc 100644
--- a/res/layout/launcher.xml
+++ b/res/layout/launcher.xml
@@ -69,15 +69,15 @@
android:background="@android:color/transparent" />
<include
+ android:id="@+id/overview_panel"
+ layout="@layout/overview_panel" />
+
+ <include
android:id="@+id/apps_view"
layout="@layout/all_apps"
android:layout_width="match_parent"
android:layout_height="match_parent" />
- <include
- android:id="@+id/overview_panel"
- layout="@layout/overview_panel" />
-
</com.android.launcher3.dragndrop.DragLayer>
</com.android.launcher3.LauncherRootView>
diff --git a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
index 470a75c..01a4876 100644
--- a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
@@ -40,6 +40,7 @@
import android.os.Process;
import android.os.UserManager;
import android.util.AttributeSet;
+import android.util.FloatProperty;
import android.util.Log;
import android.util.SparseArray;
import android.util.TypedValue;
@@ -101,6 +102,20 @@
OnDeviceProfileChangeListener, PersonalWorkSlidingTabStrip.OnActivePageChangedListener,
ScrimView.ScrimDrawingController {
+
+ public static final FloatProperty<ActivityAllAppsContainerView<?>> BOTTOM_SHEET_ALPHA =
+ new FloatProperty<>("bottomSheetAlpha") {
+ @Override
+ public Float get(ActivityAllAppsContainerView<?> containerView) {
+ return containerView.mBottomSheetAlpha;
+ }
+
+ @Override
+ public void setValue(ActivityAllAppsContainerView<?> containerView, float v) {
+ containerView.setBottomSheetAlpha(v);
+ }
+ };
+
public static final float PULL_MULTIPLIER = .02f;
public static final float FLING_VELOCITY_MULTIPLIER = 1200f;
protected static final String BUNDLE_KEY_CURRENT_PAGE = "launcher.allapps.current_page";
@@ -159,6 +174,8 @@
private ScrimView mScrimView;
private int mHeaderColor;
private int mBottomSheetBackgroundColor;
+ private float mBottomSheetAlpha = 1f;
+ private boolean mForceBottomSheetVisible;
private int mTabsProtectionAlpha;
@Nullable private AllAppsTransitionController mAllAppsTransitionController;
@@ -258,7 +275,7 @@
final TypedValue value = new TypedValue();
getContext().getTheme().resolveAttribute(android.R.attr.colorBackground, value, true);
mBottomSheetBackgroundColor = value.data;
- updateBackground(mActivityContext.getDeviceProfile());
+ updateBackgroundVisibility(mActivityContext.getDeviceProfile());
mSearchUiManager.initializeSearch(this);
}
@@ -282,6 +299,16 @@
return mBottomSheetBackground;
}
+ /**
+ * Temporarily force the bottom sheet to be visible on non-tablets.
+ *
+ * @param force {@code true} means bottom sheet will be visible on phones until {@code reset()}.
+ **/
+ public void forceBottomSheetVisible(boolean force) {
+ mForceBottomSheetVisible = force;
+ updateBackgroundVisibility(mActivityContext.getDeviceProfile());
+ }
+
public View getSearchView() {
return mSearchContainer;
}
@@ -408,6 +435,7 @@
if (mHeader != null && mHeader.getVisibility() == VISIBLE) {
mHeader.reset(animate);
}
+ forceBottomSheetVisible(false);
// Reset the base recycler view after transitioning home.
updateHeaderScroll(0);
if (exitSearch) {
@@ -830,7 +858,7 @@
holder.mRecyclerView.getRecycledViewPool().clear();
}
}
- updateBackground(dp);
+ updateBackgroundVisibility(dp);
int navBarScrimColor = Themes.getNavBarScrimColor(mActivityContext);
if (mNavBarScrimPaint.getColor() != navBarScrimColor) {
@@ -839,13 +867,19 @@
}
}
- protected void updateBackground(DeviceProfile deviceProfile) {
- mBottomSheetBackground.setVisibility(deviceProfile.isTablet ? View.VISIBLE : View.GONE);
+ protected void updateBackgroundVisibility(DeviceProfile deviceProfile) {
+ boolean visible = deviceProfile.isTablet || mForceBottomSheetVisible;
+ mBottomSheetBackground.setVisibility(visible ? View.VISIBLE : View.GONE);
// Note: For tablets, the opaque background and header protection are added in drawOnScrim.
// For the taskbar entrypoint, the scrim is drawn differently, so a static background is
// added in TaskbarAllAppsContainerView and header protection is not yet supported.
}
+ private void setBottomSheetAlpha(float alpha) {
+ // Bottom sheet alpha is always 1 for tablets.
+ mBottomSheetAlpha = mActivityContext.getDeviceProfile().isTablet ? 1f : alpha;
+ }
+
private void onAppsUpdated() {
mHasWorkApps = Stream.of(mAllAppsStore.getApps()).anyMatch(mWorkManager.getMatcher());
if (TestProtocol.sDebugTracing) {
@@ -1148,8 +1182,8 @@
@Override
public void drawOnScrimWithScale(Canvas canvas, float scale) {
- final boolean isTablet = mActivityContext.getDeviceProfile().isTablet;
final View panel = mBottomSheetBackground;
+ final boolean hasBottomSheet = panel.getVisibility() == VISIBLE;
final float translationY = ((View) panel.getParent()).getTranslationY();
final float horizontalScaleOffset = (1 - scale) * panel.getWidth() / 2;
@@ -1160,8 +1194,9 @@
final float leftWithScale = panel.getLeft() + horizontalScaleOffset;
final float rightWithScale = panel.getRight() - horizontalScaleOffset;
// Draw full background panel for tablets.
- if (isTablet) {
+ if (hasBottomSheet) {
mHeaderPaint.setColor(mBottomSheetBackgroundColor);
+ mHeaderPaint.setAlpha((int) (255 * mBottomSheetAlpha));
mTmpRectF.set(
leftWithScale,
@@ -1192,7 +1227,7 @@
final float headerBottomOffset = (getVisibleContainerView().getHeight() * (1 - scale) / 2);
final float headerBottomWithScaleOnPhone = headerBottomNoScale * scale + headerBottomOffset;
final FloatingHeaderView headerView = getFloatingHeaderView();
- if (isTablet) {
+ if (hasBottomSheet) {
// Start adding header protection if search bar or tabs will attach to the top.
if (!FeatureFlags.ENABLE_FLOATING_SEARCH_BAR.get() || mUsingTabs) {
mTmpRectF.set(
@@ -1219,12 +1254,12 @@
}
float left = 0f;
float right = canvas.getWidth();
- if (isTablet) {
+ if (hasBottomSheet) {
left = mBottomSheetBackground.getLeft() + horizontalScaleOffset;
right = mBottomSheetBackground.getRight() - horizontalScaleOffset;
}
- final float tabTopWithScale = isTablet
+ final float tabTopWithScale = hasBottomSheet
? headerBottomWithScaleOnTablet
: headerBottomWithScaleOnPhone;
final float tabBottomWithScale = tabTopWithScale + tabsHeight * scale;
@@ -1263,7 +1298,7 @@
* Returns a view that denotes the visible part of all apps container view.
*/
public View getVisibleContainerView() {
- return mActivityContext.getDeviceProfile().isTablet ? mBottomSheetBackground : this;
+ return mBottomSheetBackground.getVisibility() == VISIBLE ? mBottomSheetBackground : this;
}
protected void onInitializeRecyclerView(RecyclerView rv) {
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 4d1006a..d4f152a 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -21,8 +21,10 @@
import static com.android.launcher3.LauncherState.ALL_APPS_CONTENT;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7;
+import static com.android.launcher3.anim.Interpolators.INSTANT;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.PropertySetter.NO_ANIM_PROPERTY_SETTER;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_BOTTOM_SHEET_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
import static com.android.launcher3.util.SystemUiController.FLAG_DARK_NAV;
@@ -410,8 +412,12 @@
setter.setFloat(getAppsViewPullbackAlpha(), MultiPropertyFactory.MULTI_PROPERTY_VALUE,
hasAllAppsContent ? 1 : 0, allAppsFade);
- boolean shouldProtectHeader =
- ALL_APPS == state || mLauncher.getStateManager().getState() == ALL_APPS;
+ setter.setFloat(mLauncher.getAppsView(),
+ ActivityAllAppsContainerView.BOTTOM_SHEET_ALPHA, hasAllAppsContent ? 1 : 0,
+ config.getInterpolator(ANIM_ALL_APPS_BOTTOM_SHEET_FADE, INSTANT));
+
+ boolean shouldProtectHeader = !config.hasAnimationFlag(StateAnimationConfig.SKIP_SCRIM)
+ && (ALL_APPS == state || mLauncher.getStateManager().getState() == ALL_APPS);
mScrimView.setDrawingController(shouldProtectHeader ? mAppsView : null);
}
diff --git a/src/com/android/launcher3/allapps/SecondaryLauncherAllAppsContainerView.java b/src/com/android/launcher3/allapps/SecondaryLauncherAllAppsContainerView.java
index 684e98e..d7f5463 100644
--- a/src/com/android/launcher3/allapps/SecondaryLauncherAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/SecondaryLauncherAllAppsContainerView.java
@@ -41,7 +41,7 @@
}
@Override
- protected void updateBackground(DeviceProfile deviceProfile) {}
+ protected void updateBackgroundVisibility(DeviceProfile deviceProfile) {}
@Override
public boolean isInAllApps() {
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 492bcf5..1aa7f05 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -118,9 +118,13 @@
// TODO(Block 4): Cleanup flags
public static final BooleanFlag ENABLE_FLOATING_SEARCH_BAR =
- getReleaseFlag(270390286, "ENABLE_FLOATING_SEARCH_BAR", DISABLED,
+ getReleaseFlag(268388460, "ENABLE_FLOATING_SEARCH_BAR", DISABLED,
"Keep All Apps search bar at the bottom (but above keyboard if open)");
+ public static final BooleanFlag ENABLE_ALL_APPS_FROM_OVERVIEW =
+ getDebugFlag(275132633, "ENABLE_ALL_APPS_FROM_OVERVIEW", DISABLED,
+ "Allow entering All Apps from Overview (e.g. long swipe up from app)");
+
public static final BooleanFlag ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS = getReleaseFlag(
270394468, "ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS", ENABLED,
"Enable option to show keyboard when going to all-apps");
diff --git a/src/com/android/launcher3/model/BaseModelUpdateTask.java b/src/com/android/launcher3/model/BaseModelUpdateTask.java
index bf839bf..70c9802 100644
--- a/src/com/android/launcher3/model/BaseModelUpdateTask.java
+++ b/src/com/android/launcher3/model/BaseModelUpdateTask.java
@@ -151,7 +151,12 @@
}
public void bindApplicationsIfNeeded() {
- if (mAllAppsList.getAndResetChangeFlag()) {
+ boolean changeFlag = mAllAppsList.getAndResetChangeFlag();
+ if (TestProtocol.sDebugTracing) {
+ Log.d(WORK_TAB_MISSING, "bindApplicationsIfNeeded changeFlag? " +
+ changeFlag);
+ }
+ if (changeFlag) {
AppInfo[] apps = mAllAppsList.copyData();
int flags = mAllAppsList.getFlags();
scheduleCallbackTask(c -> c.bindAllApplications(apps, flags));
diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java
index 1ab64df..d4a5e1b 100644
--- a/src/com/android/launcher3/model/PackageUpdatedTask.java
+++ b/src/com/android/launcher3/model/PackageUpdatedTask.java
@@ -44,6 +44,7 @@
import com.android.launcher3.pm.PackageInstallInfo;
import com.android.launcher3.pm.UserCache;
import com.android.launcher3.shortcuts.ShortcutRequest;
+import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.util.FlagOp;
import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.ItemInfoMatcher;
@@ -67,7 +68,7 @@
*/
public class PackageUpdatedTask extends BaseModelUpdateTask {
- private static final boolean DEBUG = false;
+ private static boolean DEBUG = false;
private static final String TAG = "PackageUpdatedTask";
public static final int OP_NONE = 0;
@@ -92,6 +93,11 @@
mOp = op;
mUser = user;
mPackages = packages;
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.WORK_TAB_MISSING, "PackageUpdatedTask mOp: " + mOp +
+ " packageCount: " + mPackages.length);
+ DEBUG = true;
+ }
}
@Override
@@ -136,6 +142,9 @@
// The update may have changed which shortcuts/widgets are available.
// Refresh the widgets for the package if we have an activity running.
Launcher launcher = Launcher.ACTIVITY_TRACKER.getCreatedActivity();
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.WORK_TAB_MISSING, "launcher: " + launcher);
+ }
if (launcher != null) {
launcher.refreshAndBindWidgetsForPackageUser(
new PackageUserKey(packages[i], mUser));
diff --git a/src/com/android/launcher3/states/StateAnimationConfig.java b/src/com/android/launcher3/states/StateAnimationConfig.java
index 54735f0..d1e816b 100644
--- a/src/com/android/launcher3/states/StateAnimationConfig.java
+++ b/src/com/android/launcher3/states/StateAnimationConfig.java
@@ -65,7 +65,8 @@
ANIM_OVERVIEW_ACTIONS_FADE,
ANIM_WORKSPACE_PAGE_TRANSLATE_X,
ANIM_OVERVIEW_SPLIT_SELECT_FLOATING_TASK_TRANSLATE_OFFSCREEN,
- ANIM_OVERVIEW_SPLIT_SELECT_INSTRUCTIONS_FADE
+ ANIM_OVERVIEW_SPLIT_SELECT_INSTRUCTIONS_FADE,
+ ANIM_ALL_APPS_BOTTOM_SHEET_FADE
})
@Retention(RetentionPolicy.SOURCE)
public @interface AnimType {}
@@ -88,8 +89,9 @@
public static final int ANIM_WORKSPACE_PAGE_TRANSLATE_X = 15;
public static final int ANIM_OVERVIEW_SPLIT_SELECT_FLOATING_TASK_TRANSLATE_OFFSCREEN = 17;
public static final int ANIM_OVERVIEW_SPLIT_SELECT_INSTRUCTIONS_FADE = 18;
+ public static final int ANIM_ALL_APPS_BOTTOM_SHEET_FADE = 19;
- private static final int ANIM_TYPES_COUNT = 19;
+ private static final int ANIM_TYPES_COUNT = 20;
protected final Interpolator[] mInterpolators = new Interpolator[ANIM_TYPES_COUNT];
diff --git a/src/com/android/launcher3/touch/AllAppsSwipeController.java b/src/com/android/launcher3/touch/AllAppsSwipeController.java
index a53751f..d028f24 100644
--- a/src/com/android/launcher3/touch/AllAppsSwipeController.java
+++ b/src/com/android/launcher3/touch/AllAppsSwipeController.java
@@ -23,6 +23,8 @@
import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
import static com.android.launcher3.anim.Interpolators.INSTANT;
import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.anim.Interpolators.clampToProgress;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_BOTTOM_SHEET_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_DEPTH;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_FADE;
@@ -32,11 +34,14 @@
import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCALE;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_TRANSLATE;
+import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
import android.view.MotionEvent;
import android.view.animation.Interpolator;
import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.anim.Interpolators;
@@ -269,4 +274,44 @@
: ALL_APPS_VERTICAL_PROGRESS_ATOMIC);
}
}
+
+ /**
+ * Applies Animation config values for transition from overview to all apps.
+ *
+ * @param threshold progress at which all apps will open upon release
+ */
+ public static void applyOverviewToAllAppsAnimConfig(
+ DeviceProfile deviceProfile, StateAnimationConfig config, float threshold) {
+ config.userControlled = true;
+ config.animFlags = SKIP_OVERVIEW;
+ if (deviceProfile.isTablet) {
+ config.setInterpolator(ANIM_ALL_APPS_FADE, INSTANT);
+ config.setInterpolator(ANIM_SCRIM_FADE, ALL_APPS_SCRIM_RESPONDER);
+ // The fact that we end on Workspace is not very ideal, but since we do, fade it in at
+ // the end of the transition. Don't scale/translate it.
+ config.setInterpolator(ANIM_WORKSPACE_FADE, clampToProgress(LINEAR, 0.8f, 1));
+ config.setInterpolator(ANIM_WORKSPACE_SCALE, INSTANT);
+ config.setInterpolator(ANIM_WORKSPACE_TRANSLATE, INSTANT);
+ } else {
+ // Remove scrim for this transition.
+ config.setInterpolator(ANIM_SCRIM_FADE, progress -> 0);
+
+ // For now, pop the background panel in at full opacity at the threshold.
+ config.setInterpolator(ANIM_ALL_APPS_BOTTOM_SHEET_FADE,
+ thresholdInterpolator(threshold, INSTANT));
+
+ // Fade the apps in when the scrim normally does, so it's apparent sooner what is
+ // happening (in this case we are fading them on top of the background panel).
+ config.setInterpolator(ANIM_ALL_APPS_FADE,
+ thresholdInterpolator(threshold, SCRIM_FADE_MANUAL));
+
+ config.setInterpolator(ANIM_VERTICAL_PROGRESS,
+ thresholdInterpolator(threshold, ALL_APPS_VERTICAL_PROGRESS_MANUAL));
+ }
+ }
+
+ /** Creates an interpolator that is 0 until the threshold, then follows given interpolator. */
+ private static Interpolator thresholdInterpolator(float threshold, Interpolator interpolator) {
+ return progress -> progress <= threshold ? 0 : interpolator.getInterpolation(progress);
+ }
}
diff --git a/tests/src/com/android/launcher3/ui/WorkProfileTest.java b/tests/src/com/android/launcher3/ui/WorkProfileTest.java
index 54da7de..c83820b 100644
--- a/tests/src/com/android/launcher3/ui/WorkProfileTest.java
+++ b/tests/src/com/android/launcher3/ui/WorkProfileTest.java
@@ -105,6 +105,8 @@
}
private void waitForWorkTabSetup() {
+ // Added for b/243688989 flake to determine if we really are in allApps or not at this point
+ mLauncher.getAllApps();
waitForLauncherCondition("Work tab not setup", launcher -> {
if (launcher.getAppsView().getContentView() instanceof AllAppsPagedView) {
Log.d(WORK_TAB_MISSING, "Deferring AppsStore updates");