Merge "Coordinate the SUW All Set page first reveal with the taskbar unstash to hotseat animation." into tm-dev am: 9c7551a9c9

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/17108605

Change-Id: If4a66b9d344b8a4e56fc5fea59aacdad4ffb5cbe
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Schneider Victor-tulias
2022-05-13 22:59:12 +00:00
committed by Automerger Merge Worker
7 changed files with 155 additions and 21 deletions

View File

@@ -19,6 +19,7 @@ import static com.android.launcher3.taskbar.TaskbarLauncherStateController.FLAG_
import static com.android.systemui.shared.system.WindowManagerWrapper.ITYPE_EXTRA_NAVIGATION_BAR;
import android.animation.Animator;
import android.animation.AnimatorSet;
import android.annotation.ColorInt;
import android.os.RemoteException;
import android.util.Log;
@@ -28,6 +29,7 @@ import android.view.TaskTransitionSpec;
import android.view.WindowManagerGlobal;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import com.android.launcher3.BaseQuickstepLauncher;
@@ -139,6 +141,24 @@ public class LauncherTaskbarUIController extends TaskbarUIController {
mControllers.taskbarStashController.onLongPressToUnstashTaskbar();
}
/**
* Adds the Launcher resume animator to the given animator set.
*
* This should be used to run a Launcher resume animation whose progress matches a
* swipe progress.
*
* @param placeholderDuration a placeholder duration to be used to ensure all full-length
* sub-animations are properly coordinated. This duration should not
* actually be used since this animation tracks a swipe progress.
*/
protected void addLauncherResumeAnimation(AnimatorSet animation, int placeholderDuration) {
animation.play(onLauncherResumedOrPaused(
/* isResumed= */ true,
/* fromInit= */ false,
/* startAnimation= */ false,
placeholderDuration));
}
/**
* Should be called from onResume() and onPause(), and animates the Taskbar accordingly.
*/
@@ -147,9 +167,19 @@ public class LauncherTaskbarUIController extends TaskbarUIController {
}
private void onLauncherResumedOrPaused(boolean isResumed, boolean fromInit) {
onLauncherResumedOrPaused(
isResumed,
fromInit,
/* startAnimation= */ true,
QuickstepTransitionManager.CONTENT_ALPHA_DURATION);
}
@Nullable
private Animator onLauncherResumedOrPaused(
boolean isResumed, boolean fromInit, boolean startAnimation, int duration) {
if (mKeyguardController.isScreenOff()) {
if (!isResumed) {
return;
return null;
} else {
// Resuming implicitly means device unlocked
mKeyguardController.setScreenOn();
@@ -157,8 +187,7 @@ public class LauncherTaskbarUIController extends TaskbarUIController {
}
mTaskbarLauncherStateController.updateStateForFlag(FLAG_RESUMED, isResumed);
mTaskbarLauncherStateController.applyState(
fromInit ? 0 : QuickstepTransitionManager.CONTENT_ALPHA_DURATION);
return mTaskbarLauncherStateController.applyState(fromInit ? 0 : duration, startAnimation);
}
/**

View File

@@ -29,6 +29,7 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_N
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.app.ActivityOptions;
import android.content.ActivityNotFoundException;
import android.content.Context;
@@ -60,6 +61,8 @@ import com.android.launcher3.BubbleTextView;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.R;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dot.DotInfo;
import com.android.launcher3.folder.Folder;
import com.android.launcher3.folder.FolderIcon;
@@ -734,6 +737,45 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
return mIsNavBarForceVisible;
}
/**
* Displays a single frame of the Launcher start from SUW animation.
*
* This animation is a combination of the Launcher resume animation, which animates the hotseat
* icons into position, the Taskbar unstash to hotseat animation, which animates the Taskbar
* stash bar into the hotseat icons, and an override to prevent showing the Taskbar all apps
* button.
*
* This should be used to run a Taskbar unstash to hotseat animation whose progress matches a
* swipe progress.
*
* @param duration a placeholder duration to be used to ensure all full-length
* sub-animations are properly coordinated. This duration should not actually
* be used since this animation tracks a swipe progress.
*/
protected AnimatorPlaybackController createLauncherStartFromSuwAnim(int duration) {
AnimatorSet fullAnimation = new AnimatorSet();
fullAnimation.setDuration(duration);
TaskbarUIController uiController = mControllers.uiController;
if (uiController instanceof LauncherTaskbarUIController) {
((LauncherTaskbarUIController) uiController).addLauncherResumeAnimation(
fullAnimation, duration);
}
mControllers.taskbarStashController.addUnstashToHotseatAnimation(fullAnimation, duration);
if (!FeatureFlags.ENABLE_ALL_APPS_BUTTON_IN_HOTSEAT.get()) {
ValueAnimator alphaOverride = ValueAnimator.ofFloat(0, 1);
alphaOverride.setDuration(duration);
alphaOverride.addUpdateListener(a -> {
// Override the alpha updates in the icon alignment animation.
mControllers.taskbarViewController.getAllAppsButtonView().setAlpha(0);
});
fullAnimation.play(alphaOverride);
}
return AnimatorPlaybackController.wrap(fullAnimation, duration);
}
/**
* Called when we determine the touchable region.
*

View File

@@ -39,6 +39,7 @@ import androidx.annotation.Nullable;
import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.taskbar.unfold.NonDestroyableScopedUnfoldTransitionProgressProvider;
import com.android.launcher3.util.DisplayController;
@@ -182,6 +183,17 @@ public class TaskbarManager {
}
}
/**
* Displays a frame of the first Launcher reveal animation.
*
* This should be used to run a first Launcher reveal animation whose progress matches a swipe
* progress.
*/
public AnimatorPlaybackController createLauncherStartFromSuwAnim(int duration) {
return mTaskbarActivityContext == null
? null : mTaskbarActivityContext.createLauncherStartFromSuwAnim(duration);
}
/**
* Called when the user is unlocked
*/

View File

@@ -35,6 +35,8 @@ import android.view.WindowInsets;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.taskbar.allapps.TaskbarAllAppsSlideInView;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
import com.android.quickstep.AnimatedFloat;
@@ -367,13 +369,34 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
return false;
}
/**
* Adds the Taskbar unstash to Hotseat animator to the animator set.
*
* This should be used to run a Taskbar unstash to Hotseat animation whose progress matches a
* swipe progress.
*
* @param placeholderDuration a placeholder duration to be used to ensure all full-length
* sub-animations are properly coordinated. This duration should not
* actually be used since this animation tracks a swipe progress.
*/
protected void addUnstashToHotseatAnimation(AnimatorSet animation, int placeholderDuration) {
createAnimToIsStashed(
/* isStashed= */ false,
placeholderDuration,
/* startDelay= */ 0,
/* animateBg= */ false);
animation.play(mAnimator);
}
/**
* Create a stash animation and save to {@link #mAnimator}.
* @param isStashed whether it's a stash animation or an unstash animation
* @param duration duration of the animation
* @param startDelay how many milliseconds to delay the animation after starting it.
* @param animateBg whether the taskbar's background should be animated
*/
private void createAnimToIsStashed(boolean isStashed, long duration, long startDelay) {
private void createAnimToIsStashed(
boolean isStashed, long duration, long startDelay, boolean animateBg) {
if (mAnimator != null) {
mAnimator.cancel();
}
@@ -408,10 +431,14 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
secondHalfDurationScale = 0.5f;
final float stashTranslation = (mUnstashedHeight - mStashedHeight) / 2f;
fullLengthAnimatorSet.playTogether(
mTaskbarBackgroundOffset.animateToValue(1),
mIconTranslationYForStash.animateToValue(stashTranslation)
);
fullLengthAnimatorSet.play(mIconTranslationYForStash.animateToValue(stashTranslation));
if (animateBg) {
fullLengthAnimatorSet.play(mTaskbarBackgroundOffset.animateToValue(1));
} else {
fullLengthAnimatorSet.addListener(AnimatorListeners.forEndCallback(
() -> mTaskbarBackgroundOffset.updateValue(1)));
}
firstHalfAnimatorSet.playTogether(
mIconAlphaForStash.animateToValue(0),
mIconScaleForStash.animateToValue(STASHED_TASKBAR_SCALE)
@@ -424,10 +451,15 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
secondHalfDurationScale = 0.75f;
fullLengthAnimatorSet.playTogether(
mTaskbarBackgroundOffset.animateToValue(0),
mIconScaleForStash.animateToValue(1),
mIconTranslationYForStash.animateToValue(0)
);
mIconTranslationYForStash.animateToValue(0));
if (animateBg) {
fullLengthAnimatorSet.play(mTaskbarBackgroundOffset.animateToValue(0));
} else {
fullLengthAnimatorSet.addListener(AnimatorListeners.forEndCallback(
() -> mTaskbarBackgroundOffset.updateValue(0)));
}
firstHalfAnimatorSet.playTogether(
mTaskbarStashedHandleAlpha.animateToValue(0)
);
@@ -728,7 +760,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
mIsStashed = isStashed;
// This sets mAnimator.
createAnimToIsStashed(mIsStashed, duration, startDelay);
createAnimToIsStashed(mIsStashed, duration, startDelay, /* animateBg= */ true);
if (start) {
mAnimator.start();
}

View File

@@ -258,21 +258,21 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
setter.addOnFrameListener(anim -> mActivity.setTaskbarWindowHeight(
anim.getAnimatedFraction() > 0 ? expandedHeight : collapsedHeight));
int count = mTaskbarView.getChildCount();
for (int i = 0; i < count; i++) {
for (int i = 0; i < mTaskbarView.getChildCount(); i++) {
View child = mTaskbarView.getChildAt(i);
int positionInHotseat = -1;
boolean isRtl = Utilities.isRtl(child.getResources());
int positionInHotseat;
if (FeatureFlags.ENABLE_ALL_APPS_IN_TASKBAR.get()
&& ((isRtl && i == 0) || (!isRtl && i == count - 1))) {
&& child == mTaskbarView.getAllAppsButtonView()) {
// Note that there is no All Apps button in the hotseat, this position is only used
// as its convenient for animation purposes.
positionInHotseat = isRtl
positionInHotseat = Utilities.isRtl(child.getResources())
? -1
: mActivity.getDeviceProfile().numShownHotseatIcons;
setter.setViewAlpha(child, 0, LINEAR);
if (!FeatureFlags.ENABLE_ALL_APPS_BUTTON_IN_HOTSEAT.get()) {
setter.setViewAlpha(child, 0, LINEAR);
}
} else if (child.getTag() instanceof ItemInfo) {
positionInHotseat = ((ItemInfo) child.getTag()).screenId;
} else {

View File

@@ -17,6 +17,7 @@ package com.android.quickstep.interaction;
import static com.android.launcher3.Utilities.mapBoundToRange;
import static com.android.launcher3.Utilities.mapRange;
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import android.animation.Animator;
@@ -54,6 +55,7 @@ import androidx.core.graphics.ColorUtils;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.util.Executors;
import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.GestureState;
@@ -78,6 +80,8 @@ public class AllSetActivity extends Activity {
private static final float HINT_BOTTOM_FACTOR = 1 - .94f;
private static final int MAX_SWIPE_DURATION = 350;
private TISBindHelper mTISBindHelper;
private TISBinder mBinder;
@@ -90,6 +94,8 @@ public class AllSetActivity extends Activity {
private LottieAnimationView mAnimatedBackground;
private Animator.AnimatorListener mBackgroundAnimatorListener;
private AnimatorPlaybackController mLauncherStartAnim = null;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -237,11 +243,20 @@ public class AllSetActivity extends Activity {
private void onSwipeProgressUpdate() {
mBackground.setProgress(mSwipeProgress.value);
float alpha = Utilities.mapBoundToRange(mSwipeProgress.value, 0, HINT_BOTTOM_FACTOR,
1, 0, LINEAR);
float alpha = Utilities.mapBoundToRange(
mSwipeProgress.value, 0, HINT_BOTTOM_FACTOR, 1, 0, LINEAR);
mContentView.setAlpha(alpha);
mContentView.setTranslationY((alpha - 1) * mSwipeUpShift);
if (mLauncherStartAnim == null) {
mLauncherStartAnim = mBinder.getTaskbarManager().createLauncherStartFromSuwAnim(
MAX_SWIPE_DURATION);
}
if (mLauncherStartAnim != null) {
mLauncherStartAnim.setPlayFraction(Utilities.mapBoundToRange(
mSwipeProgress.value, 0, 1, 0, 1, FAST_OUT_SLOW_IN));
}
if (alpha == 0f) {
mAnimatedBackground.pauseAnimation();
} else if (!mAnimatedBackground.isAnimating()) {

View File

@@ -246,6 +246,10 @@ public final class FeatureFlags {
"ENABLE_ALL_APPS_IN_TASKBAR", true,
"Enables accessing All Apps from the system Taskbar.");
public static final BooleanFlag ENABLE_ALL_APPS_BUTTON_IN_HOTSEAT = getDebugFlag(
"ENABLE_ALL_APPS_BUTTON_IN_HOTSEAT", false,
"Enables displaying the all apps button in the hotseat.");
public static final BooleanFlag ENABLE_ALL_APPS_ONE_SEARCH_IN_TASKBAR = getDebugFlag(
"ENABLE_ALL_APPS_ONE_SEARCH_IN_TASKBAR", false,
"Enables One Search box in Taskbar All Apps.");