diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml index 50f123676f..5a58bc25f6 100644 --- a/quickstep/res/values/dimens.xml +++ b/quickstep/res/values/dimens.xml @@ -272,8 +272,6 @@ 108dp 316dp 4dp - 25dp - 4dp 112dp 88dp 40dp diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java index 0945bf2d1d..87753594fe 100644 --- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java @@ -42,7 +42,6 @@ import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.logging.InstanceId; import com.android.launcher3.logging.InstanceIdSequence; import com.android.launcher3.model.data.ItemInfo; -import com.android.launcher3.model.data.ItemInfoWithIcon; import com.android.launcher3.uioverrides.QuickstepLauncher; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.OnboardingPrefs; @@ -51,7 +50,6 @@ import com.android.quickstep.RecentsAnimationCallbacks; import com.android.quickstep.views.RecentsView; import java.io.PrintWriter; -import java.util.Arrays; import java.util.Set; import java.util.stream.Stream; @@ -256,11 +254,6 @@ public class LauncherTaskbarUIController extends TaskbarUIController { mTaskbarOverrideBackgroundAlpha.updateValue(forceHide ? 0 : 1); } - @Override - public Stream getAppIconsForEdu() { - return Arrays.stream(mLauncher.getAppsView().getAppsStore().getApps()); - } - /** * Starts the taskbar education flow, if the user hasn't seen it yet. */ diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java index 365ec75715..c53595d5b8 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java @@ -15,70 +15,27 @@ */ package com.android.launcher3.taskbar; -import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY; -import static com.android.launcher3.anim.Interpolators.ACCEL_2; -import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL; -import static com.android.launcher3.anim.Interpolators.DEACCEL; -import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN; - -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.AnimatorSet; -import android.animation.Keyframe; -import android.animation.ObjectAnimator; -import android.animation.PropertyValuesHolder; -import android.animation.TimeInterpolator; -import android.content.res.Resources; -import android.text.TextUtils; -import android.view.View; +import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_STASHED_IN_APP_EDU; +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import com.android.launcher3.R; -import com.android.launcher3.icons.BitmapInfo; -import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext; -import com.android.launcher3.uioverrides.PredictedAppIcon; +import com.android.launcher3.taskbar.overlay.TaskbarOverlayController; import java.io.PrintWriter; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; /** Handles the Taskbar Education flow. */ public class TaskbarEduController implements TaskbarControllers.LoggableTaskbarController { - private static final long WAVE_ANIM_DELAY = 250; - private static final long WAVE_ANIM_STAGGER = 50; - private static final long WAVE_ANIM_EACH_ICON_DURATION = 633; - private static final long WAVE_ANIM_SLOT_MACHINE_DURATION = 1085; - // The fraction of each icon's animation at which we reach the top point of the wave. - private static final float WAVE_ANIM_FRACTION_TOP = 0.4f; - // The fraction of each icon's animation at which we reach the bottom, before overshooting. - private static final float WAVE_ANIM_FRACTION_BOTTOM = 0.9f; - private static final TimeInterpolator WAVE_ANIM_TO_TOP_INTERPOLATOR = FAST_OUT_SLOW_IN; - private static final TimeInterpolator WAVE_ANIM_TO_BOTTOM_INTERPOLATOR = ACCEL_2; - private static final TimeInterpolator WAVE_ANIM_OVERSHOOT_INTERPOLATOR = DEACCEL; - private static final TimeInterpolator WAVE_ANIM_OVERSHOOT_RETURN_INTERPOLATOR = ACCEL_DEACCEL; - private static final float WAVE_ANIM_ICON_SCALE = 1.2f; - // How many icons to cycle through in the slot machine (+ the original icon at each end). - private static final int WAVE_ANIM_SLOT_MACHINE_NUM_ICONS = 3; - private final TaskbarActivityContext mActivity; - private final float mWaveAnimTranslationY; - private final float mWaveAnimTranslationYReturnOvershoot; // Initialized in init. TaskbarControllers mControllers; private TaskbarEduView mTaskbarEduView; - private Animator mAnim; public TaskbarEduController(TaskbarActivityContext activity) { mActivity = activity; - - final Resources resources = activity.getResources(); - mWaveAnimTranslationY = resources.getDimension(R.dimen.taskbar_edu_wave_anim_trans_y); - mWaveAnimTranslationYReturnOvershoot = resources.getDimension( - R.dimen.taskbar_edu_wave_anim_trans_y_return_overshoot); } public void init(TaskbarControllers controllers) { @@ -86,115 +43,32 @@ public class TaskbarEduController implements TaskbarControllers.LoggableTaskbarC } void showEdu() { - mActivity.setTaskbarWindowFullscreen(true); - mActivity.getDragLayer().post(() -> { - TaskbarOverlayContext overlayContext = - mControllers.taskbarOverlayController.requestWindow(); - mTaskbarEduView = (TaskbarEduView) overlayContext.getLayoutInflater().inflate( - R.layout.taskbar_edu, overlayContext.getDragLayer(), false); - mTaskbarEduView.init(new TaskbarEduCallbacks()); - mControllers.navbarButtonsViewController.setSlideInViewVisible(true); - mTaskbarEduView.setOnCloseBeginListener( - () -> mControllers.navbarButtonsViewController.setSlideInViewVisible(false)); - mTaskbarEduView.addOnCloseListener(() -> mTaskbarEduView = null); - mTaskbarEduView.show(); - startAnim(createWaveAnim()); + TaskbarOverlayController overlayController = mControllers.taskbarOverlayController; + TaskbarOverlayContext overlayContext = overlayController.requestWindow(); + mTaskbarEduView = (TaskbarEduView) overlayContext.getLayoutInflater().inflate( + R.layout.taskbar_edu, overlayContext.getDragLayer(), false); + mTaskbarEduView.init(new TaskbarEduCallbacks()); + mControllers.navbarButtonsViewController.setSlideInViewVisible(true); + + TaskbarStashController stashController = mControllers.taskbarStashController; + stashController.updateStateForFlag(FLAG_STASHED_IN_APP_EDU, true); + stashController.applyState(overlayController.getOpenDuration()); + + mTaskbarEduView.setOnCloseBeginListener(() -> { + mControllers.navbarButtonsViewController.setSlideInViewVisible(false); + // Post in case view is closing due to gesture navigation. If a gesture is in progress, + // wait to unstash until after the gesture is finished. + MAIN_EXECUTOR.post(() -> stashController.resetFlagIfNoGestureInProgress( + FLAG_STASHED_IN_APP_EDU)); }); - } - - /** - * Starts the given animation, ending the previous animation first if it's still playing. - */ - private void startAnim(Animator anim) { - if (mAnim != null) { - mAnim.end(); - } - mAnim = anim; - mAnim.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mAnim = null; - } - }); - mAnim.start(); - } - - /** - * Creates a staggered "wave" animation where each icon translates and scales up in succession. - */ - private Animator createWaveAnim() { - AnimatorSet waveAnim = new AnimatorSet(); - View[] icons = mControllers.taskbarViewController.getIconViews(); - for (int i = 0; i < icons.length; i++) { - View icon = icons[i]; - AnimatorSet iconAnim = new AnimatorSet(); - - Keyframe[] scaleKeyframes = new Keyframe[] { - Keyframe.ofFloat(0, 1f), - Keyframe.ofFloat(WAVE_ANIM_FRACTION_TOP, WAVE_ANIM_ICON_SCALE), - Keyframe.ofFloat(WAVE_ANIM_FRACTION_BOTTOM, 1f), - Keyframe.ofFloat(1f, 1f) - }; - scaleKeyframes[1].setInterpolator(WAVE_ANIM_TO_TOP_INTERPOLATOR); - scaleKeyframes[2].setInterpolator(WAVE_ANIM_TO_BOTTOM_INTERPOLATOR); - - Keyframe[] translationYKeyframes = new Keyframe[] { - Keyframe.ofFloat(0, 0f), - Keyframe.ofFloat(WAVE_ANIM_FRACTION_TOP, -mWaveAnimTranslationY), - Keyframe.ofFloat(WAVE_ANIM_FRACTION_BOTTOM, 0f), - // Half of the remaining fraction overshoots, then the other half returns to 0. - Keyframe.ofFloat( - WAVE_ANIM_FRACTION_BOTTOM + (1 - WAVE_ANIM_FRACTION_BOTTOM) / 2f, - mWaveAnimTranslationYReturnOvershoot), - Keyframe.ofFloat(1f, 0f) - }; - translationYKeyframes[1].setInterpolator(WAVE_ANIM_TO_TOP_INTERPOLATOR); - translationYKeyframes[2].setInterpolator(WAVE_ANIM_TO_BOTTOM_INTERPOLATOR); - translationYKeyframes[3].setInterpolator(WAVE_ANIM_OVERSHOOT_INTERPOLATOR); - translationYKeyframes[4].setInterpolator(WAVE_ANIM_OVERSHOOT_RETURN_INTERPOLATOR); - - iconAnim.play(ObjectAnimator.ofPropertyValuesHolder(icon, - PropertyValuesHolder.ofKeyframe(SCALE_PROPERTY, scaleKeyframes)) - .setDuration(WAVE_ANIM_EACH_ICON_DURATION)); - iconAnim.play(ObjectAnimator.ofPropertyValuesHolder(icon, - PropertyValuesHolder.ofKeyframe(View.TRANSLATION_Y, translationYKeyframes)) - .setDuration(WAVE_ANIM_EACH_ICON_DURATION)); - - if (icon instanceof PredictedAppIcon) { - // Play slot machine animation through random icons from AllAppsList. - PredictedAppIcon predictedAppIcon = (PredictedAppIcon) icon; - ItemInfo itemInfo = (ItemInfo) icon.getTag(); - List iconsToAnimate = mControllers.uiController.getAppIconsForEdu() - .filter(appInfo -> !TextUtils.equals(appInfo.title, itemInfo.title)) - .map(appInfo -> appInfo.bitmap) - .filter(bitmap -> !bitmap.isNullOrLowRes()) - .collect(Collectors.toList()); - // Pick n icons at random. - Collections.shuffle(iconsToAnimate); - if (iconsToAnimate.size() > WAVE_ANIM_SLOT_MACHINE_NUM_ICONS) { - iconsToAnimate = iconsToAnimate.subList(0, WAVE_ANIM_SLOT_MACHINE_NUM_ICONS); - } - Animator slotMachineAnim = predictedAppIcon.createSlotMachineAnim(iconsToAnimate); - if (slotMachineAnim != null) { - iconAnim.play(slotMachineAnim.setDuration(WAVE_ANIM_SLOT_MACHINE_DURATION)); - } - } - - iconAnim.setStartDelay(WAVE_ANIM_STAGGER * i); - waveAnim.play(iconAnim); - } - waveAnim.setStartDelay(WAVE_ANIM_DELAY); - return waveAnim; + mTaskbarEduView.addOnCloseListener(() -> mTaskbarEduView = null); + mTaskbarEduView.show(); } @Override public void dumpLogs(String prefix, PrintWriter pw) { pw.println(prefix + "TaskbarEduController:"); - pw.println(prefix + "\tisShowingEdu=" + (mTaskbarEduView != null)); - pw.println(prefix + "\tmWaveAnimTranslationY=" + mWaveAnimTranslationY); - pw.println(prefix + "\tmWaveAnimTranslationYReturnOvershoot=" - + mWaveAnimTranslationYReturnOvershoot); } /** @@ -221,5 +95,13 @@ public class TaskbarEduController implements TaskbarControllers.LoggableTaskbarC int getIconLayoutBoundsWidth() { return mControllers.taskbarViewController.getIconLayoutWidth(); } + + int getOpenDuration() { + return mControllers.taskbarOverlayController.getOpenDuration(); + } + + int getCloseDuration() { + return mControllers.taskbarOverlayController.getCloseDuration(); + } } } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduView.java index bb87f48a92..d38c6d1d4d 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduView.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduView.java @@ -35,9 +35,6 @@ import com.android.launcher3.views.AbstractSlideInView; public class TaskbarEduView extends AbstractSlideInView implements Insettable { - private static final int DEFAULT_OPEN_DURATION = 500; - private static final int DEFAULT_CLOSE_DURATION = 200; - private final Rect mInsets = new Rect(); // Initialized in init. @@ -65,7 +62,7 @@ public class TaskbarEduView extends AbstractSlideInView @Override protected void handleClose(boolean animate) { - handleClose(animate, DEFAULT_CLOSE_DURATION); + handleClose(animate, mTaskbarEduCallbacks.getCloseDuration()); } @Override @@ -161,7 +158,7 @@ public class TaskbarEduView extends AbstractSlideInView mOpenCloseAnimator.setValues( PropertyValuesHolder.ofFloat(TRANSLATION_SHIFT, TRANSLATION_SHIFT_OPENED)); mOpenCloseAnimator.setInterpolator(AGGRESSIVE_EASE); - mOpenCloseAnimator.setDuration(DEFAULT_OPEN_DURATION).start(); + mOpenCloseAnimator.setDuration(mTaskbarEduCallbacks.getOpenDuration()).start(); } void snapToPage(int page) { diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java index 722430e808..11755d9646 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java @@ -17,7 +17,6 @@ package com.android.launcher3.taskbar; import static android.view.HapticFeedbackConstants.LONG_PRESS; -import static com.android.launcher3.LauncherState.ALL_APPS; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_LONGPRESS_HIDE; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_LONGPRESS_SHOW; import static com.android.launcher3.taskbar.Utilities.appendFlag; @@ -80,6 +79,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba public static final int FLAG_IN_SETUP = 1 << 8; // In the Setup Wizard public static final int FLAG_STASHED_SMALL_SCREEN = 1 << 9; // phone screen gesture nav, stashed public static final int FLAG_STASHED_IN_APP_AUTO = 1 << 10; // Autohide (transient taskbar). + public static final int FLAG_STASHED_IN_APP_EDU = 1 << 11; // EDU is visible. // If any of these flags are enabled, isInApp should return true. private static final int FLAGS_IN_APP = FLAG_IN_APP | FLAG_IN_SETUP; @@ -88,7 +88,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba private static final int FLAGS_STASHED_IN_APP = FLAG_STASHED_IN_APP_MANUAL | FLAG_STASHED_IN_SYSUI_STATE | FLAG_STASHED_IN_APP_EMPTY | FLAG_STASHED_IN_APP_SETUP | FLAG_STASHED_IN_APP_IME | FLAG_STASHED_IN_TASKBAR_ALL_APPS - | FLAG_STASHED_SMALL_SCREEN | FLAG_STASHED_IN_APP_AUTO; + | FLAG_STASHED_SMALL_SCREEN | FLAG_STASHED_IN_APP_AUTO | FLAG_STASHED_IN_APP_EDU; private static final int FLAGS_STASHED_IN_APP_IGNORING_IME = FLAGS_STASHED_IN_APP & ~FLAG_STASHED_IN_APP_IME; @@ -98,7 +98,8 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba // Currently any flag that causes us to stash in an app is included, except for IME or All Apps // since those cover the underlying app anyway and thus the app shouldn't change insets. private static final int FLAGS_REPORT_STASHED_INSETS_TO_APP = FLAGS_STASHED_IN_APP - & ~FLAG_STASHED_IN_APP_IME & ~FLAG_STASHED_IN_TASKBAR_ALL_APPS; + & ~FLAG_STASHED_IN_APP_IME & ~FLAG_STASHED_IN_TASKBAR_ALL_APPS + & ~FLAG_STASHED_IN_APP_EDU; /** * How long to stash/unstash when manually invoked via long press. @@ -706,34 +707,27 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba // Only update the following flags when system gesture is not in progress. boolean shouldStashForIme = shouldStashForIme(); - maybeResetStashedInAppAllApps( - hasAnyFlag(FLAG_STASHED_IN_APP_IME) == shouldStashForIme); + updateStateForFlag(FLAG_STASHED_IN_TASKBAR_ALL_APPS, false); + updateStateForFlag(FLAG_STASHED_IN_APP_EDU, false); if (hasAnyFlag(FLAG_STASHED_IN_APP_IME) != shouldStashForIme) { updateStateForFlag(FLAG_STASHED_IN_APP_IME, shouldStashForIme); applyState(TASKBAR_STASH_DURATION_FOR_IME, getTaskbarStashStartDelayForIme()); + } else { + applyState(mControllers.taskbarOverlayController.getCloseDuration()); } } /** - * Reset stashed in all apps only if no system gesture is in progress. + * Resets the flag if no system gesture is in progress. *

* Otherwise, the reset should be deferred until after the gesture is finished. * * @see #setSystemGestureInProgress */ - public void maybeResetStashedInAppAllApps() { - maybeResetStashedInAppAllApps(true); - } - - private void maybeResetStashedInAppAllApps(boolean applyState) { - if (mIsSystemGestureInProgress) { - return; - } - - updateStateForFlag(FLAG_STASHED_IN_TASKBAR_ALL_APPS, false); - if (applyState) { - applyState(ALL_APPS.getTransitionDuration( - mControllers.taskbarActivityContext, false /* isToState */)); + public void resetFlagIfNoGestureInProgress(int flag) { + if (!mIsSystemGestureInProgress) { + updateStateForFlag(flag, false); + applyState(mControllers.taskbarOverlayController.getCloseDuration()); } } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java index 4ec9b41ea2..6c6b002959 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java @@ -29,7 +29,6 @@ import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskView; import java.io.PrintWriter; -import java.util.stream.Stream; /** * Base class for providing different taskbar UI @@ -66,10 +65,6 @@ public class TaskbarUIController { protected void onStashedInAppChanged() { } - public Stream getAppIconsForEdu() { - return Stream.empty(); - } - /** Called when an icon is launched. */ public void onTaskbarIconLaunched(ItemInfo item) { } diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java index c8bfc2aed0..8502752652 100644 --- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java +++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java @@ -15,7 +15,6 @@ */ package com.android.launcher3.taskbar.allapps; -import static com.android.launcher3.LauncherState.ALL_APPS; import static com.android.launcher3.anim.Interpolators.EMPHASIZED; import android.animation.PropertyValuesHolder; @@ -28,6 +27,7 @@ import android.view.animation.Interpolator; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Insettable; import com.android.launcher3.R; +import com.android.launcher3.taskbar.allapps.TaskbarAllAppsViewController.TaskbarAllAppsCallbacks; import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext; import com.android.launcher3.views.AbstractSlideInView; @@ -37,6 +37,9 @@ public class TaskbarAllAppsSlideInView extends AbstractSlideInView mTaskbarStashController.resetFlagIfNoGestureInProgress( + FLAG_STASHED_IN_TASKBAR_ALL_APPS)); }); } + + class TaskbarAllAppsCallbacks { + int getOpenDuration() { + return mOverlayController.getOpenDuration(); + } + + int getCloseDuration() { + return mOverlayController.getCloseDuration(); + } + } } diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java index 019e5a608f..476e0a8bab 100644 --- a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java +++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java @@ -20,6 +20,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; import static com.android.launcher3.AbstractFloatingView.TYPE_ALL; import static com.android.launcher3.AbstractFloatingView.TYPE_REBIND_SAFE; +import static com.android.launcher3.LauncherState.ALL_APPS; import android.annotation.SuppressLint; import android.content.Context; @@ -150,6 +151,16 @@ public final class TaskbarOverlayController { }); } + /** The default open duration for overlays. */ + public int getOpenDuration() { + return ALL_APPS.getTransitionDuration(mTaskbarContext, true); + } + + /** The default close duration for overlays. */ + public int getCloseDuration() { + return ALL_APPS.getTransitionDuration(mTaskbarContext, false); + } + @SuppressLint("WrongConstant") private LayoutParams createLayoutParams() { LayoutParams layoutParams = new LayoutParams(