Merge "Desktop Mode Taskbar Recreate Animation" into main
This commit is contained in:
@@ -1784,8 +1784,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
|
||||
}
|
||||
|
||||
/** Get animation duration for taskbar for going to home. */
|
||||
public static int getTaskbarToHomeDuration(boolean isPinnedTaskbar) {
|
||||
return getTaskbarToHomeDuration(false, isPinnedTaskbar);
|
||||
public static int getTaskbarToHomeDuration(boolean isPinnedTaskbarAndNotInDesktopMode) {
|
||||
return getTaskbarToHomeDuration(false, isPinnedTaskbarAndNotInDesktopMode);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1794,8 +1794,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
|
||||
* @param shouldOverrideToFastAnimation should overwrite scaling reveal home animation duration
|
||||
*/
|
||||
public static int getTaskbarToHomeDuration(boolean shouldOverrideToFastAnimation,
|
||||
boolean isPinnedTaskbar) {
|
||||
if (isPinnedTaskbar) {
|
||||
boolean isPinnedTaskbarAndNotInDesktopMode) {
|
||||
if (isPinnedTaskbarAndNotInDesktopMode) {
|
||||
return PINNED_TASKBAR_TRANSITION_DURATION;
|
||||
} else if (enableScalingRevealHomeAnimation() && !shouldOverrideToFastAnimation) {
|
||||
return TASKBAR_TO_HOME_DURATION_SLOW;
|
||||
|
||||
@@ -32,7 +32,8 @@ import com.android.launcher3.statemanager.StatefulActivity
|
||||
import com.android.launcher3.uioverrides.QuickstepLauncher
|
||||
import com.android.launcher3.util.DaggerSingletonObject
|
||||
import com.android.launcher3.util.DaggerSingletonTracker
|
||||
import com.android.launcher3.util.Executors
|
||||
import com.android.launcher3.util.DisplayController
|
||||
import com.android.launcher3.util.Executors.MAIN_EXECUTOR
|
||||
import com.android.launcher3.util.window.WindowManagerProxy.DesktopVisibilityListener
|
||||
import com.android.quickstep.GestureState.GestureEndTarget
|
||||
import com.android.quickstep.SystemUiProxy
|
||||
@@ -87,9 +88,22 @@ constructor(
|
||||
private val desktopVisibilityListeners: MutableSet<DesktopVisibilityListener> = HashSet()
|
||||
private val taskbarDesktopModeListeners: MutableSet<TaskbarDesktopModeListener> = HashSet()
|
||||
|
||||
// This simply indicates that user is currently in desktop mode or not.
|
||||
var isInDesktopMode = false
|
||||
private set
|
||||
|
||||
// to track if any pending notification to be done.
|
||||
var isNotifyingDesktopVisibilityPending = false
|
||||
|
||||
// to let launcher hold off on notifying desktop visibility listeners.
|
||||
var launcherAnimationRunning = false
|
||||
|
||||
// TODO: b/394387739 - Deprecate this and replace it with something that tracks the count per
|
||||
// desk.
|
||||
/** Number of visible desktop windows in desktop mode. */
|
||||
/**
|
||||
* Number of visible desktop windows in desktop mode. This can be > 0 when user goes to overview
|
||||
* from desktop window mode.
|
||||
*/
|
||||
var visibleDesktopTasksCount: Int = 0
|
||||
/**
|
||||
* Sets the number of desktop windows that are visible and updates launcher visibility based
|
||||
@@ -107,13 +121,27 @@ constructor(
|
||||
}
|
||||
|
||||
if (visibleTasksCount != field) {
|
||||
if (visibleDesktopTasksCount == 0 && visibleTasksCount == 1) {
|
||||
isInDesktopMode = true
|
||||
}
|
||||
if (visibleDesktopTasksCount == 1 && visibleTasksCount == 0) {
|
||||
isInDesktopMode = false
|
||||
}
|
||||
val wasVisible = field > 0
|
||||
val isVisible = visibleTasksCount > 0
|
||||
val wereDesktopTasksVisibleBefore = areDesktopTasksVisibleAndNotInOverview()
|
||||
field = visibleTasksCount
|
||||
val areDesktopTasksVisibleNow = areDesktopTasksVisibleAndNotInOverview()
|
||||
if (wereDesktopTasksVisibleBefore != areDesktopTasksVisibleNow) {
|
||||
notifyIsInDesktopModeChanged(DEFAULT_DISPLAY, areDesktopTasksVisibleNow)
|
||||
|
||||
if (
|
||||
wereDesktopTasksVisibleBefore != areDesktopTasksVisibleNow ||
|
||||
wasVisible != isVisible
|
||||
) {
|
||||
if (!launcherAnimationRunning) {
|
||||
notifyIsInDesktopModeChanged(DEFAULT_DISPLAY, areDesktopTasksVisibleNow)
|
||||
} else {
|
||||
isNotifyingDesktopVisibilityPending = true
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
@@ -169,7 +197,7 @@ constructor(
|
||||
/** Returns whether a desk is currently active on the display with the given [displayId]. */
|
||||
fun isInDesktopMode(displayId: Int): Boolean {
|
||||
if (!DesktopModeStatus.enableMultipleDesktops(context)) {
|
||||
return areDesktopTasksVisible()
|
||||
return isInDesktopMode
|
||||
}
|
||||
|
||||
val activeDeskId = getDisplayDeskConfig(displayId)?.activeDeskId ?: INACTIVE_DESK_ID
|
||||
@@ -195,15 +223,6 @@ constructor(
|
||||
return isInDesktopMode(displayId) && !inOverviewState
|
||||
}
|
||||
|
||||
/** Whether desktop tasks are visible in desktop mode. */
|
||||
private fun areDesktopTasksVisible(): Boolean {
|
||||
val desktopTasksVisible: Boolean = visibleDesktopTasksCount > 0
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "areDesktopTasksVisible: desktopVisible=$desktopTasksVisible")
|
||||
}
|
||||
return desktopTasksVisible
|
||||
}
|
||||
|
||||
/** Whether desktop tasks are visible in desktop mode. */
|
||||
private fun areDesktopTasksVisibleAndNotInOverview(): Boolean {
|
||||
val desktopTasksVisible: Boolean = visibleDesktopTasksCount > 0
|
||||
@@ -237,6 +256,22 @@ constructor(
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Launcher Driven Desktop Mode changes. For example, swipe to home and quick switch from
|
||||
* Desktop Windowing Mode. if there is any pending notification please notify desktop visibility
|
||||
* listeners.
|
||||
*/
|
||||
fun onLauncherAnimationFromDesktopEnd() {
|
||||
launcherAnimationRunning = false
|
||||
if (isNotifyingDesktopVisibilityPending) {
|
||||
isNotifyingDesktopVisibilityPending = false
|
||||
notifyIsInDesktopModeChanged(
|
||||
DEFAULT_DISPLAY,
|
||||
isInDesktopModeAndNotInOverview(DEFAULT_DISPLAY),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun onLauncherStateChanged(state: RecentsState) {
|
||||
onLauncherStateChanged(
|
||||
state,
|
||||
@@ -346,6 +381,26 @@ constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun notifyTaskbarDesktopModeListenersForEntry(duration: Int) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "notifyTaskbarDesktopModeListenersForEntry: duration=" + duration)
|
||||
}
|
||||
for (listener in taskbarDesktopModeListeners) {
|
||||
listener.onEnterDesktopMode(duration)
|
||||
}
|
||||
DisplayController.INSTANCE.get(context).notifyConfigChange()
|
||||
}
|
||||
|
||||
private fun notifyTaskbarDesktopModeListenersForExit(duration: Int) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "notifyTaskbarDesktopModeListenersForExit: duration=" + duration)
|
||||
}
|
||||
for (listener in taskbarDesktopModeListeners) {
|
||||
listener.onExitDesktopMode(duration)
|
||||
}
|
||||
DisplayController.INSTANCE.get(context).notifyConfigChange()
|
||||
}
|
||||
|
||||
/** TODO: b/333533253 - Remove after flag rollout */
|
||||
private fun setBackgroundStateEnabled(backgroundStateEnabled: Boolean) {
|
||||
if (DEBUG) {
|
||||
@@ -552,14 +607,14 @@ constructor(
|
||||
displayDeskStates: Array<DisplayDeskState>,
|
||||
canCreateDesks: Boolean,
|
||||
) {
|
||||
Executors.MAIN_EXECUTOR.execute {
|
||||
MAIN_EXECUTOR.execute {
|
||||
controller.get()?.onListenerConnected(displayDeskStates, canCreateDesks)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTasksVisibilityChanged(displayId: Int, visibleTasksCount: Int) {
|
||||
if (displayId != this.displayId) return
|
||||
Executors.MAIN_EXECUTOR.execute {
|
||||
MAIN_EXECUTOR.execute {
|
||||
controller.get()?.apply {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "desktop visible tasks count changed=$visibleTasksCount")
|
||||
@@ -575,7 +630,7 @@ constructor(
|
||||
|
||||
override fun onTaskbarCornerRoundingUpdate(doesAnyTaskRequireTaskbarRounding: Boolean) {
|
||||
if (!DesktopModeStatus.useRoundedCorners()) return
|
||||
Executors.MAIN_EXECUTOR.execute {
|
||||
MAIN_EXECUTOR.execute {
|
||||
controller.get()?.apply {
|
||||
Log.d(
|
||||
TAG,
|
||||
@@ -587,26 +642,46 @@ constructor(
|
||||
}
|
||||
}
|
||||
|
||||
override fun onEnterDesktopModeTransitionStarted(transitionDuration: Int) {}
|
||||
|
||||
override fun onExitDesktopModeTransitionStarted(transitionDuration: Int) {}
|
||||
|
||||
override fun onCanCreateDesksChanged(canCreateDesks: Boolean) {
|
||||
Executors.MAIN_EXECUTOR.execute {
|
||||
controller.get()?.onCanCreateDesksChanged(canCreateDesks)
|
||||
override fun onEnterDesktopModeTransitionStarted(transitionDuration: Int) {
|
||||
MAIN_EXECUTOR.execute {
|
||||
Log.d(
|
||||
TAG,
|
||||
("DesktopTaskListenerImpl: onEnterDesktopModeTransitionStarted with " +
|
||||
"duration= " +
|
||||
transitionDuration),
|
||||
)
|
||||
controller.get()?.isInDesktopMode = true
|
||||
controller.get()?.notifyTaskbarDesktopModeListenersForEntry(transitionDuration)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onExitDesktopModeTransitionStarted(transitionDuration: Int) {
|
||||
MAIN_EXECUTOR.execute {
|
||||
Log.d(
|
||||
TAG,
|
||||
("DesktopTaskListenerImpl: onExitDesktopModeTransitionStarted with " +
|
||||
"duration= " +
|
||||
transitionDuration),
|
||||
)
|
||||
controller.get()?.isInDesktopMode = false
|
||||
controller.get()?.notifyTaskbarDesktopModeListenersForExit(transitionDuration)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCanCreateDesksChanged(canCreateDesks: Boolean) {
|
||||
MAIN_EXECUTOR.execute { controller.get()?.onCanCreateDesksChanged(canCreateDesks) }
|
||||
}
|
||||
|
||||
override fun onDeskAdded(displayId: Int, deskId: Int) {
|
||||
Executors.MAIN_EXECUTOR.execute { controller.get()?.onDeskAdded(displayId, deskId) }
|
||||
MAIN_EXECUTOR.execute { controller.get()?.onDeskAdded(displayId, deskId) }
|
||||
}
|
||||
|
||||
override fun onDeskRemoved(displayId: Int, deskId: Int) {
|
||||
Executors.MAIN_EXECUTOR.execute { controller.get()?.onDeskRemoved(displayId, deskId) }
|
||||
MAIN_EXECUTOR.execute { controller.get()?.onDeskRemoved(displayId, deskId) }
|
||||
}
|
||||
|
||||
override fun onActiveDeskChanged(displayId: Int, newActiveDesk: Int, oldActiveDesk: Int) {
|
||||
Executors.MAIN_EXECUTOR.execute {
|
||||
MAIN_EXECUTOR.execute {
|
||||
controller.get()?.onActiveDeskChanged(displayId, newActiveDesk, oldActiveDesk)
|
||||
}
|
||||
}
|
||||
@@ -619,7 +694,21 @@ constructor(
|
||||
*
|
||||
* @param doesAnyTaskRequireTaskbarRounding whether task requires taskbar corner roundness.
|
||||
*/
|
||||
fun onTaskbarCornerRoundingUpdate(doesAnyTaskRequireTaskbarRounding: Boolean)
|
||||
fun onTaskbarCornerRoundingUpdate(doesAnyTaskRequireTaskbarRounding: Boolean) {}
|
||||
|
||||
/**
|
||||
* Callback for when user is exiting desktop mode.
|
||||
*
|
||||
* @param duration for exit transition
|
||||
*/
|
||||
fun onExitDesktopMode(duration: Int) {}
|
||||
|
||||
/**
|
||||
* Callback for when user is entering desktop mode.
|
||||
*
|
||||
* @param duration for enter transition
|
||||
*/
|
||||
fun onEnterDesktopMode(duration: Int) {}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -27,6 +27,7 @@ import static android.window.SplashScreen.SPLASH_SCREEN_STYLE_UNDEFINED;
|
||||
|
||||
import static androidx.annotation.VisibleForTesting.PACKAGE_PRIVATE;
|
||||
|
||||
import static com.android.app.animation.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
|
||||
import static com.android.launcher3.AbstractFloatingView.TYPE_ON_BOARD_POPUP;
|
||||
import static com.android.launcher3.AbstractFloatingView.TYPE_REBIND_SAFE;
|
||||
@@ -449,14 +450,25 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
|
||||
mControllers.taskbarViewController.adjustTaskbarForBubbleBar();
|
||||
}
|
||||
|
||||
public void init(@NonNull TaskbarSharedState sharedState) {
|
||||
/**
|
||||
* Init of taskbar activity context.
|
||||
* @param duration If duration is greater than 0, it will be used to create an animation
|
||||
* for the taskbar create/recreate process.
|
||||
*/
|
||||
public void init(@NonNull TaskbarSharedState sharedState, int duration) {
|
||||
mImeDrawsImeNavBar = getBoolByName(IME_DRAWS_IME_NAV_BAR_RES_NAME, getResources(), false);
|
||||
mLastRequestedNonFullscreenSize = getDefaultTaskbarWindowSize();
|
||||
mWindowLayoutParams = createAllWindowParams();
|
||||
mLastUpdatedLayoutParams = new WindowManager.LayoutParams();
|
||||
|
||||
|
||||
AnimatorSet recreateAnim = null;
|
||||
if (duration > 0) {
|
||||
recreateAnim = onRecreateAnimation(duration);
|
||||
}
|
||||
|
||||
// Initialize controllers after all are constructed.
|
||||
mControllers.init(sharedState);
|
||||
mControllers.init(sharedState, recreateAnim);
|
||||
// This may not be necessary and can be reverted once we move towards recreating all
|
||||
// controllers without re-creating the window
|
||||
mControllers.rotationButtonController.onNavigationModeChanged(mNavMode.resValue);
|
||||
@@ -484,6 +496,33 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
|
||||
} else {
|
||||
notifyUpdateLayoutParams();
|
||||
}
|
||||
|
||||
|
||||
if (recreateAnim != null) {
|
||||
recreateAnim.start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create AnimatorSet for taskbar create/recreate animation. Further used in init
|
||||
*/
|
||||
public AnimatorSet onRecreateAnimation(int duration) {
|
||||
AnimatorSet animatorSet = new AnimatorSet();
|
||||
animatorSet.setDuration(duration);
|
||||
return animatorSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when we want destroy current taskbar with animation as part of recreate process.
|
||||
*/
|
||||
public AnimatorSet onDestroyAnimation(int duration) {
|
||||
mIsDestroyed = true;
|
||||
AnimatorSet animatorSet = new AnimatorSet();
|
||||
mControllers.taskbarViewController.onDestroyAnimation(animatorSet);
|
||||
mControllers.taskbarDragLayerController.onDestroyAnimation(animatorSet);
|
||||
animatorSet.setInterpolator(LINEAR);
|
||||
animatorSet.setDuration(duration);
|
||||
return animatorSet;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1983,6 +2022,10 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
|
||||
return mControllers.taskbarStashController.isInApp();
|
||||
}
|
||||
|
||||
public boolean isInOverview() {
|
||||
return mControllers.taskbarStashController.isInOverview();
|
||||
}
|
||||
|
||||
public boolean isInStashedLauncherState() {
|
||||
return mControllers.taskbarStashController.isInStashedLauncherState();
|
||||
}
|
||||
|
||||
@@ -50,6 +50,8 @@ class TaskbarBackgroundRenderer(private val context: TaskbarActivityContext) {
|
||||
}
|
||||
|
||||
var isAnimatingPinning = false
|
||||
var isAnimatingPersistentTaskbar = false
|
||||
var isAnimatingTransientTaskbar = false
|
||||
|
||||
val paint = Paint()
|
||||
private val strokePaint = Paint()
|
||||
@@ -144,7 +146,7 @@ class TaskbarBackgroundRenderer(private val context: TaskbarActivityContext) {
|
||||
/** Draws the background with the given paint and height, on the provided canvas. */
|
||||
fun draw(canvas: Canvas) {
|
||||
if (isInSetup) return
|
||||
val isTransientTaskbar = backgroundProgress == 0f
|
||||
val isTransientTaskbar = DisplayController.isTransientTaskbar(context)
|
||||
canvas.save()
|
||||
if (!isTransientTaskbar || transientBackgroundBounds.isEmpty || isAnimatingPinning) {
|
||||
drawPersistentBackground(canvas)
|
||||
@@ -158,7 +160,7 @@ class TaskbarBackgroundRenderer(private val context: TaskbarActivityContext) {
|
||||
}
|
||||
|
||||
private fun drawPersistentBackground(canvas: Canvas) {
|
||||
if (isAnimatingPinning) {
|
||||
if (isAnimatingPinning || isAnimatingPersistentTaskbar) {
|
||||
val persistentTaskbarHeight = maxPersistentTaskbarHeight * backgroundProgress
|
||||
canvas.translate(0f, canvas.height - persistentTaskbarHeight)
|
||||
// Draw the background behind taskbar content.
|
||||
@@ -181,12 +183,13 @@ class TaskbarBackgroundRenderer(private val context: TaskbarActivityContext) {
|
||||
private fun drawTransientBackground(canvas: Canvas) {
|
||||
val res = context.resources
|
||||
val transientTaskbarHeight = maxTransientTaskbarHeight * (1f - backgroundProgress)
|
||||
val isAnimating = isAnimatingPinning || isAnimatingTransientTaskbar
|
||||
val heightProgressWhileAnimating =
|
||||
if (isAnimatingPinning) transientTaskbarHeight else backgroundHeight
|
||||
if (isAnimating) transientTaskbarHeight else backgroundHeight
|
||||
|
||||
var progress = heightProgressWhileAnimating / maxTransientTaskbarHeight
|
||||
progress = Math.round(progress * 100f) / 100f
|
||||
if (isAnimatingPinning) {
|
||||
if (isAnimating) {
|
||||
var scale = transientTaskbarHeight / maxTransientTaskbarHeight
|
||||
scale = Math.round(scale * 100f) / 100f
|
||||
bottomMargin =
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.android.launcher3.taskbar;
|
||||
|
||||
import android.animation.AnimatorSet;
|
||||
import android.content.pm.ActivityInfo.Config;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@@ -149,15 +150,15 @@ public class TaskbarControllers {
|
||||
* TaskbarControllers instance, but should be careful to only access things that were created
|
||||
* in constructors for now, as some controllers may still be waiting for init().
|
||||
*/
|
||||
public void init(@NonNull TaskbarSharedState sharedState) {
|
||||
public void init(@NonNull TaskbarSharedState sharedState, AnimatorSet startAnimation) {
|
||||
mAreAllControllersInitialized = false;
|
||||
mSharedState = sharedState;
|
||||
|
||||
taskbarDragController.init(this);
|
||||
navbarButtonsViewController.init(this);
|
||||
rotationButtonController.init();
|
||||
taskbarDragLayerController.init(this);
|
||||
taskbarViewController.init(this);
|
||||
taskbarDragLayerController.init(this, startAnimation);
|
||||
taskbarViewController.init(this, startAnimation);
|
||||
taskbarScrimViewController.init(this);
|
||||
taskbarUnfoldAnimationController.init(this);
|
||||
taskbarKeyguardController.init(navbarButtonsViewController);
|
||||
|
||||
@@ -30,6 +30,9 @@ class TaskbarDesktopModeController(
|
||||
private lateinit var taskbarControllers: TaskbarControllers
|
||||
private lateinit var taskbarSharedState: TaskbarSharedState
|
||||
|
||||
val isInDesktopMode: Boolean
|
||||
get() = desktopVisibilityController.isInDesktopMode
|
||||
|
||||
fun init(controllers: TaskbarControllers, sharedState: TaskbarSharedState) {
|
||||
taskbarControllers = controllers
|
||||
taskbarSharedState = sharedState
|
||||
@@ -42,6 +45,7 @@ class TaskbarDesktopModeController(
|
||||
desktopVisibilityController.isInDesktopModeAndNotInOverview(displayId)
|
||||
|
||||
override fun onTaskbarCornerRoundingUpdate(doesAnyTaskRequireTaskbarRounding: Boolean) {
|
||||
if (taskbarControllers.taskbarActivityContext.isDestroyed) return
|
||||
taskbarSharedState.showCornerRadiusInDesktopMode = doesAnyTaskRequireTaskbarRounding
|
||||
val cornerRadius = getTaskbarCornerRoundness(doesAnyTaskRequireTaskbarRounding)
|
||||
taskbarControllers.taskbarCornerRoundness.animateToValue(cornerRadius).start()
|
||||
|
||||
@@ -186,6 +186,7 @@ public class TaskbarDragLayer extends BaseDragLayer<TaskbarActivityContext> {
|
||||
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
if (mContainer.isDestroyed()) return;
|
||||
float backgroundHeight = mControllerCallbacks.getTaskbarBackgroundHeight()
|
||||
* (1f - mTaskbarBackgroundOffset);
|
||||
mBackgroundRenderer.setBackgroundHeight(backgroundHeight);
|
||||
@@ -285,6 +286,21 @@ public class TaskbarDragLayer extends BaseDragLayer<TaskbarActivityContext> {
|
||||
return super.dispatchKeyEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets animation boolean when only animating persistent taskbar.
|
||||
*/
|
||||
public void setIsAnimatingPersistentTaskbarBackground(boolean animatingPersistentTaskbarBg) {
|
||||
mBackgroundRenderer.setAnimatingPersistentTaskbar(animatingPersistentTaskbarBg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets animation boolean when only animating transient taskbar.
|
||||
*/
|
||||
public void setIsAnimatingTransientTaskbarBackground(boolean animatingTransientTaskbarBg) {
|
||||
mBackgroundRenderer.setAnimatingTransientTaskbar(animatingTransientTaskbarBg);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the width percentage to inset the transient taskbar's background from the left and from
|
||||
* the right.
|
||||
|
||||
@@ -15,9 +15,12 @@
|
||||
*/
|
||||
package com.android.launcher3.taskbar;
|
||||
|
||||
import static com.android.app.animation.Interpolators.EMPHASIZED;
|
||||
import static com.android.launcher3.taskbar.TaskbarPinningController.PINNING_PERSISTENT;
|
||||
import static com.android.launcher3.taskbar.TaskbarPinningController.PINNING_TRANSIENT;
|
||||
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Point;
|
||||
@@ -29,6 +32,7 @@ import android.view.ViewTreeObserver;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.anim.AnimatedFloat;
|
||||
import com.android.launcher3.anim.AnimatorListeners;
|
||||
import com.android.launcher3.util.DimensionUtils;
|
||||
import com.android.launcher3.util.DisplayController;
|
||||
import com.android.launcher3.util.MultiPropertyFactory.MultiProperty;
|
||||
@@ -58,6 +62,8 @@ public class TaskbarDragLayerController implements TaskbarControllers.LoggableTa
|
||||
private final AnimatedFloat mImeBgTaskbar = new AnimatedFloat(this::updateBackgroundAlpha);
|
||||
private final AnimatedFloat mAssistantBgTaskbar = new AnimatedFloat(
|
||||
this::updateBackgroundAlpha);
|
||||
private final AnimatedFloat mBgTaskbarRecreate = new AnimatedFloat(
|
||||
this::updateBackgroundAlpha);
|
||||
// Used to hide our background color when someone else (e.g. ScrimView) is handling it.
|
||||
private final AnimatedFloat mBgOverride = new AnimatedFloat(this::updateBackgroundAlpha);
|
||||
|
||||
@@ -88,7 +94,10 @@ public class TaskbarDragLayerController implements TaskbarControllers.LoggableTa
|
||||
mFolderMargin = resources.getDimensionPixelSize(R.dimen.taskbar_folder_margin);
|
||||
}
|
||||
|
||||
public void init(TaskbarControllers controllers) {
|
||||
/**
|
||||
* Init of taskbar drag layer controller
|
||||
*/
|
||||
public void init(TaskbarControllers controllers, AnimatorSet startAnimation) {
|
||||
mControllers = controllers;
|
||||
mTaskbarStashViaTouchController = new TaskbarStashViaTouchController(mControllers);
|
||||
mTaskbarDragLayer.init(new TaskbarDragLayerCallbacks());
|
||||
@@ -96,15 +105,45 @@ public class TaskbarDragLayerController implements TaskbarControllers.LoggableTa
|
||||
mOnBackgroundNavButtonColorIntensity = mControllers.navbarButtonsViewController
|
||||
.getOnTaskbarBackgroundNavButtonColorOverride();
|
||||
|
||||
mTaskbarBackgroundProgress.updateValue(DisplayController.isTransientTaskbar(mActivity)
|
||||
? PINNING_TRANSIENT
|
||||
: PINNING_PERSISTENT);
|
||||
|
||||
if (startAnimation != null) {
|
||||
// set taskbar background render animation boolean
|
||||
if (DisplayController.isTransientTaskbar(mActivity)) {
|
||||
mTaskbarDragLayer.setIsAnimatingTransientTaskbarBackground(true);
|
||||
} else {
|
||||
mTaskbarDragLayer.setIsAnimatingPersistentTaskbarBackground(true);
|
||||
}
|
||||
|
||||
float desiredValue = DisplayController.isTransientTaskbar(mActivity)
|
||||
? PINNING_TRANSIENT
|
||||
: PINNING_PERSISTENT;
|
||||
|
||||
float nonDesiredvalue = !DisplayController.isTransientTaskbar(mActivity)
|
||||
? PINNING_TRANSIENT
|
||||
: PINNING_PERSISTENT;
|
||||
|
||||
ObjectAnimator objectAnimator = mTaskbarBackgroundProgress.animateToValue(
|
||||
nonDesiredvalue, desiredValue);
|
||||
objectAnimator.setInterpolator(EMPHASIZED);
|
||||
startAnimation.play(objectAnimator);
|
||||
startAnimation.addListener(AnimatorListeners.forEndCallback(()-> {
|
||||
// reset taskbar background render animation boolean
|
||||
mTaskbarDragLayer.setIsAnimatingPersistentTaskbarBackground(false);
|
||||
mTaskbarDragLayer.setIsAnimatingTransientTaskbarBackground(false);
|
||||
}));
|
||||
|
||||
} else {
|
||||
mTaskbarBackgroundProgress.updateValue(DisplayController.isTransientTaskbar(mActivity)
|
||||
? PINNING_TRANSIENT
|
||||
: PINNING_PERSISTENT);
|
||||
}
|
||||
|
||||
mBgTaskbar.value = 1;
|
||||
mKeyguardBgTaskbar.value = 1;
|
||||
mNotificationShadeBgTaskbar.value = 1;
|
||||
mImeBgTaskbar.value = 1;
|
||||
mAssistantBgTaskbar.value = 1;
|
||||
mBgTaskbarRecreate.value = 1;
|
||||
mBgOverride.value = 1;
|
||||
updateBackgroundAlpha();
|
||||
|
||||
@@ -112,6 +151,13 @@ public class TaskbarDragLayerController implements TaskbarControllers.LoggableTa
|
||||
updateTaskbarAlpha();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when destroying Taskbar with animation.
|
||||
*/
|
||||
public void onDestroyAnimation(AnimatorSet animatorSet) {
|
||||
animatorSet.play(mBgTaskbarRecreate.animateToValue(0f));
|
||||
}
|
||||
|
||||
public void onDestroy() {
|
||||
mTaskbarDragLayer.onDestroy();
|
||||
}
|
||||
@@ -172,14 +218,14 @@ public class TaskbarDragLayerController implements TaskbarControllers.LoggableTa
|
||||
}
|
||||
|
||||
private void updateBackgroundAlpha() {
|
||||
if (mActivity.isPhoneMode()) {
|
||||
if (mActivity.isPhoneMode() || mActivity.isDestroyed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final float bgNavbar = mBgNavbar.value;
|
||||
final float bgTaskbar = mBgTaskbar.value * mKeyguardBgTaskbar.value
|
||||
* mNotificationShadeBgTaskbar.value * mImeBgTaskbar.value
|
||||
* mAssistantBgTaskbar.value;
|
||||
* mAssistantBgTaskbar.value * mBgTaskbarRecreate.value;
|
||||
mLastSetBackgroundAlpha = mBgOverride.value * Math.max(bgNavbar, bgTaskbar);
|
||||
mBackgroundRendererAlpha.setValue(mLastSetBackgroundAlpha);
|
||||
|
||||
@@ -266,6 +312,7 @@ public class TaskbarDragLayerController implements TaskbarControllers.LoggableTa
|
||||
pw.println(prefix + "\t\tmNotificationShadeBgTaskbar=" + mNotificationShadeBgTaskbar.value);
|
||||
pw.println(prefix + "\t\tmImeBgTaskbar=" + mImeBgTaskbar.value);
|
||||
pw.println(prefix + "\t\tmAssistantBgTaskbar=" + mAssistantBgTaskbar.value);
|
||||
pw.println(prefix + "\t\tmBgTaskbarRecreate=" + mBgTaskbarRecreate.value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -223,9 +223,13 @@ public class TaskbarLauncherStateController {
|
||||
updateStateForFlag(FLAG_LAUNCHER_IN_STATE_TRANSITION, true);
|
||||
if (!mShouldDelayLauncherStateAnim) {
|
||||
if (toState == LauncherState.NORMAL) {
|
||||
applyState(QuickstepTransitionManager.getTaskbarToHomeDuration(
|
||||
boolean isPinnedTaskbarAndNotInDesktopMode =
|
||||
DisplayController.isPinnedTaskbar(
|
||||
mControllers.taskbarActivityContext)));
|
||||
mControllers.taskbarActivityContext)
|
||||
&& !DisplayController.isInDesktopMode(
|
||||
mControllers.taskbarActivityContext);
|
||||
applyState(QuickstepTransitionManager.getTaskbarToHomeDuration(
|
||||
isPinnedTaskbarAndNotInDesktopMode));
|
||||
} else {
|
||||
applyState();
|
||||
}
|
||||
@@ -680,8 +684,11 @@ public class TaskbarLauncherStateController {
|
||||
} else if (mIconAlignment.isAnimatingToValue(toAlignment)
|
||||
|| mIconAlignment.isSettledOnValue(toAlignment)) {
|
||||
// Already at desired value, but make sure we run the callback at the end.
|
||||
animatorSet.addListener(AnimatorListeners.forEndCallback(
|
||||
this::onIconAlignmentRatioChanged));
|
||||
animatorSet.addListener(AnimatorListeners.forEndCallback(() -> {
|
||||
if (!mIconAlignment.isAnimating()) {
|
||||
onIconAlignmentRatioChanged();
|
||||
}
|
||||
}));
|
||||
} else {
|
||||
mIconAlignment.cancelAnimation();
|
||||
ObjectAnimator iconAlignAnim = mIconAlignment
|
||||
|
||||
@@ -26,6 +26,7 @@ import static com.android.launcher3.config.FeatureFlags.enableTaskbarNoRecreate;
|
||||
import static com.android.launcher3.util.DisplayController.CHANGE_DENSITY;
|
||||
import static com.android.launcher3.util.DisplayController.CHANGE_DESKTOP_MODE;
|
||||
import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
|
||||
import static com.android.launcher3.util.DisplayController.CHANGE_SHOW_LOCKED_TASKBAR;
|
||||
import static com.android.launcher3.util.DisplayController.CHANGE_TASKBAR_PINNING;
|
||||
import static com.android.launcher3.util.DisplayController.TASKBAR_NOT_DESTROYED_TAG;
|
||||
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
|
||||
@@ -33,6 +34,7 @@ import static com.android.launcher3.util.FlagDebugUtils.formatFlagChange;
|
||||
import static com.android.quickstep.util.SystemActionConstants.ACTION_SHOW_TASKBAR;
|
||||
import static com.android.quickstep.util.SystemActionConstants.SYSTEM_ACTION_ID_TASKBAR;
|
||||
|
||||
import android.animation.AnimatorSet;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.ComponentCallbacks;
|
||||
@@ -62,7 +64,9 @@ import androidx.annotation.VisibleForTesting;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.anim.AnimatorListeners;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.statehandlers.DesktopVisibilityController;
|
||||
import com.android.launcher3.statemanager.StatefulActivity;
|
||||
import com.android.launcher3.taskbar.TaskbarNavButtonController.TaskbarNavButtonCallbacks;
|
||||
import com.android.launcher3.taskbar.unfold.NonDestroyableScopedUnfoldTransitionProgressProvider;
|
||||
@@ -101,6 +105,7 @@ public class TaskbarManager {
|
||||
// TODO(b/382378283) remove all logs with this tag
|
||||
public static final String NULL_TASKBAR_ROOT_LAYOUT_TAG = "b/382378283";
|
||||
public static final String ILLEGAL_ARGUMENT_WM_ADD_VIEW = "b/391653300";
|
||||
private static final int TASKBAR_DESTROY_DURATION = 100;
|
||||
|
||||
/**
|
||||
* All the configurations which do not initiate taskbar recreation.
|
||||
@@ -189,13 +194,28 @@ public class TaskbarManager {
|
||||
}
|
||||
|
||||
if ((flags & (CHANGE_DENSITY | CHANGE_NAVIGATION_MODE | CHANGE_DESKTOP_MODE
|
||||
| CHANGE_TASKBAR_PINNING)) != 0) {
|
||||
| CHANGE_TASKBAR_PINNING | CHANGE_SHOW_LOCKED_TASKBAR)) != 0) {
|
||||
debugTaskbarManager("onDisplayInfoChanged - Recreating Taskbar!",
|
||||
context.getDisplayId());
|
||||
recreateTaskbar();
|
||||
TaskbarActivityContext taskbarActivityContext = getCurrentActivityContext();
|
||||
if ((flags & CHANGE_SHOW_LOCKED_TASKBAR) != 0) {
|
||||
recreateTaskbar();
|
||||
} else if ((flags & CHANGE_DESKTOP_MODE) != 0) {
|
||||
// Only Handles Special Exit Cases for Desktop Mode Taskbar Recreation.
|
||||
if (taskbarActivityContext != null
|
||||
&& !DesktopVisibilityController.INSTANCE.get(taskbarActivityContext)
|
||||
.isInDesktopMode()
|
||||
&& !DisplayController.showLockedTaskbarOnHome(context)) {
|
||||
recreateTaskbar();
|
||||
}
|
||||
} else {
|
||||
recreateTaskbar();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final SettingsCache.OnChangeListener mOnSettingsChangeListener = c -> {
|
||||
debugTaskbarManager("Settings changed! Recreating Taskbar!");
|
||||
recreateTaskbar();
|
||||
@@ -258,7 +278,52 @@ public class TaskbarManager {
|
||||
public void onTaskRemoved(int taskId) {
|
||||
mPerceptibleTasks.remove(taskId);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
private final DesktopVisibilityController.TaskbarDesktopModeListener
|
||||
mTaskbarDesktopModeListener =
|
||||
new DesktopVisibilityController.TaskbarDesktopModeListener() {
|
||||
@Override
|
||||
public void onExitDesktopMode(int duration) {
|
||||
for (int taskbarIndex = 0; taskbarIndex < mTaskbars.size(); taskbarIndex++) {
|
||||
int displayId = mTaskbars.keyAt(taskbarIndex);
|
||||
TaskbarActivityContext taskbarActivityContext = getTaskbarForDisplay(
|
||||
displayId);
|
||||
if (taskbarActivityContext != null
|
||||
&& !taskbarActivityContext.isInOverview()) {
|
||||
AnimatorSet animatorSet = taskbarActivityContext.onDestroyAnimation(
|
||||
TASKBAR_DESTROY_DURATION);
|
||||
animatorSet.addListener(AnimatorListeners.forEndCallback(
|
||||
() -> recreateTaskbarForDisplay(getDefaultDisplayId(),
|
||||
duration)));
|
||||
animatorSet.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnterDesktopMode(int duration) {
|
||||
for (int taskbarIndex = 0; taskbarIndex < mTaskbars.size(); taskbarIndex++) {
|
||||
int displayId = mTaskbars.keyAt(taskbarIndex);
|
||||
TaskbarActivityContext taskbarActivityContext = getTaskbarForDisplay(
|
||||
displayId);
|
||||
AnimatorSet animatorSet = taskbarActivityContext.onDestroyAnimation(
|
||||
TASKBAR_DESTROY_DURATION);
|
||||
animatorSet.addListener(AnimatorListeners.forEndCallback(
|
||||
() -> recreateTaskbarForDisplay(getDefaultDisplayId(), duration)));
|
||||
animatorSet.start();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTaskbarCornerRoundingUpdate(
|
||||
boolean doesAnyTaskRequireTaskbarRounding) {
|
||||
//NO-OP
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private boolean mUserUnlocked = false;
|
||||
|
||||
@@ -337,6 +402,9 @@ public class TaskbarManager {
|
||||
debugTaskbarManager("TaskbarManager constructor", primaryDisplayId);
|
||||
mPrimaryWindowContext = createWindowContext(primaryDisplayId);
|
||||
mPrimaryWindowManager = mPrimaryWindowContext.getSystemService(WindowManager.class);
|
||||
DesktopVisibilityController.INSTANCE.get(
|
||||
mPrimaryWindowContext).registerTaskbarDesktopModeListener(
|
||||
mTaskbarDesktopModeListener);
|
||||
createTaskbarRootLayout(primaryDisplayId);
|
||||
createNavButtonController(primaryDisplayId);
|
||||
createAndRegisterComponentCallbacks(primaryDisplayId);
|
||||
@@ -550,13 +618,13 @@ public class TaskbarManager {
|
||||
public synchronized void recreateTaskbar() {
|
||||
// Handles initial creation case.
|
||||
if (mTaskbars.size() == 0) {
|
||||
recreateTaskbarForDisplay(getDefaultDisplayId());
|
||||
recreateTaskbarForDisplay(getDefaultDisplayId(), 0);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < mTaskbars.size(); i++) {
|
||||
int displayId = mTaskbars.keyAt(i);
|
||||
recreateTaskbarForDisplay(displayId);
|
||||
recreateTaskbarForDisplay(displayId, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -565,7 +633,7 @@ public class TaskbarManager {
|
||||
* we fully want to destroy an existing taskbar for a specified display and create a new one.
|
||||
* In other case (folding/unfolding) we don't need to remove and add window.
|
||||
*/
|
||||
private void recreateTaskbarForDisplay(int displayId) {
|
||||
private void recreateTaskbarForDisplay(int displayId, int duration) {
|
||||
Trace.beginSection("recreateTaskbarForDisplay");
|
||||
try {
|
||||
Log.d(ILLEGAL_ARGUMENT_WM_ADD_VIEW, "recreateTaskbarForDisplay: " + displayId);
|
||||
@@ -582,13 +650,13 @@ public class TaskbarManager {
|
||||
boolean displayExists = getDisplay(displayId) != null;
|
||||
boolean isTaskbarEnabled = dp != null && isTaskbarEnabled(dp);
|
||||
debugTaskbarManager("recreateTaskbarForDisplay: isTaskbarEnabled=" + isTaskbarEnabled
|
||||
+ " [dp != null (i.e. mUserUnlocked)]=" + (dp != null)
|
||||
+ " FLAG_HIDE_NAVBAR_WINDOW=" + ENABLE_TASKBAR_NAVBAR_UNIFICATION
|
||||
+ " [dp != null (i.e. mUserUnlocked)]=" + (dp != null)
|
||||
+ " FLAG_HIDE_NAVBAR_WINDOW=" + ENABLE_TASKBAR_NAVBAR_UNIFICATION
|
||||
+ " dp.isTaskbarPresent=" + (dp == null ? "null" : dp.isTaskbarPresent)
|
||||
+ " displayExists=" + displayExists);
|
||||
if (!isTaskbarEnabled || !isLargeScreenTaskbar || !displayExists) {
|
||||
SystemUiProxy.INSTANCE.get(mBaseContext)
|
||||
.notifyTaskbarStatus(/* visible */ false, /* stashed */ false);
|
||||
.notifyTaskbarStatus(/* visible */ false, /* stashed */ false);
|
||||
if (!isTaskbarEnabled || !displayExists) {
|
||||
return;
|
||||
}
|
||||
@@ -608,7 +676,7 @@ public class TaskbarManager {
|
||||
mSharedState.startTaskbarVariantIsTransient =
|
||||
DisplayController.isTransientTaskbar(taskbar);
|
||||
mSharedState.allAppsVisible = mSharedState.allAppsVisible && isLargeScreenTaskbar;
|
||||
taskbar.init(mSharedState);
|
||||
taskbar.init(mSharedState, duration);
|
||||
|
||||
// Non default displays should not use LauncherTaskbarUIController as they shouldn't
|
||||
// have access to the Launcher activity.
|
||||
@@ -792,7 +860,7 @@ public class TaskbarManager {
|
||||
createTaskbarRootLayout(displayId);
|
||||
createNavButtonController(displayId);
|
||||
createAndRegisterComponentCallbacks(displayId);
|
||||
recreateTaskbarForDisplay(displayId);
|
||||
recreateTaskbarForDisplay(displayId, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -845,6 +913,9 @@ public class TaskbarManager {
|
||||
public void destroy() {
|
||||
mRecentsViewContainer = null;
|
||||
debugTaskbarManager("TaskbarManager#destroy()");
|
||||
DesktopVisibilityController.INSTANCE.get(
|
||||
mPrimaryWindowContext).unregisterTaskbarDesktopModeListener(
|
||||
mTaskbarDesktopModeListener);
|
||||
removeActivityCallbacksAndListeners();
|
||||
mTaskbarBroadcastReceiver.unregisterReceiverSafely();
|
||||
|
||||
@@ -860,7 +931,7 @@ public class TaskbarManager {
|
||||
removeAndUnregisterComponentCallbacks(getDefaultDisplayId());
|
||||
mShutdownReceiver.unregisterReceiverSafely();
|
||||
if (ActivityManagerWrapper.usePerceptibleTasks(getPrimaryWindowContext())) {
|
||||
for (Integer taskId: mTaskStackListener.mPerceptibleTasks) {
|
||||
for (Integer taskId : mTaskStackListener.mPerceptibleTasks) {
|
||||
ActivityManagerWrapper.getInstance().setTaskIsPerceptible(taskId, false);
|
||||
}
|
||||
}
|
||||
@@ -940,7 +1011,7 @@ public class TaskbarManager {
|
||||
*
|
||||
* @param displayId The ID of the display to retrieve the taskbar for.
|
||||
* @return The {@link TaskbarUIController} for the specified display, or
|
||||
* {@code null} if no taskbar is associated with that display.
|
||||
* {@code null} if no taskbar is associated with that display.
|
||||
*/
|
||||
@Nullable
|
||||
public TaskbarUIController getUIControllerForDisplay(int displayId) {
|
||||
@@ -967,7 +1038,7 @@ public class TaskbarManager {
|
||||
*
|
||||
* @param displayId The ID of the display to retrieve the taskbar for.
|
||||
* @return The {@link TaskbarActivityContext} for the specified display, or
|
||||
* {@code null} if no taskbar is associated with that display.
|
||||
* {@code null} if no taskbar is associated with that display.
|
||||
*/
|
||||
private TaskbarActivityContext getTaskbarForDisplay(int displayId) {
|
||||
return mTaskbars.get(displayId);
|
||||
@@ -976,7 +1047,8 @@ public class TaskbarManager {
|
||||
|
||||
/**
|
||||
* Creates a {@link TaskbarActivityContext} for the given display and adds it to the map.
|
||||
* @param dp The {@link DeviceProfile} for the display.
|
||||
*
|
||||
* @param dp The {@link DeviceProfile} for the display.
|
||||
* @param displayId The ID of the display.
|
||||
*/
|
||||
private @Nullable TaskbarActivityContext createTaskbarActivityContext(DeviceProfile dp,
|
||||
@@ -1008,6 +1080,7 @@ public class TaskbarManager {
|
||||
/**
|
||||
* Create {@link ComponentCallbacks} for the given display and register it to the relevant
|
||||
* WindowContext. For external displays, populate maps.
|
||||
*
|
||||
* @param displayId The ID of the display.
|
||||
*/
|
||||
private void createAndRegisterComponentCallbacks(int displayId) {
|
||||
@@ -1065,7 +1138,8 @@ public class TaskbarManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() { }
|
||||
public void onLowMemory() {
|
||||
}
|
||||
};
|
||||
if (isDefaultDisplay(displayId)
|
||||
|| !DesktopExperienceFlags.ENABLE_TASKBAR_CONNECTED_DISPLAYS.isTrue()) {
|
||||
@@ -1080,6 +1154,7 @@ public class TaskbarManager {
|
||||
/**
|
||||
* Unregister {@link ComponentCallbacks} for the given display from its WindowContext. For
|
||||
* external displays, remove from the map.
|
||||
*
|
||||
* @param displayId The ID of the display.
|
||||
*/
|
||||
private void removeAndUnregisterComponentCallbacks(int displayId) {
|
||||
@@ -1096,6 +1171,7 @@ public class TaskbarManager {
|
||||
/**
|
||||
* Creates a {@link TaskbarNavButtonController} for the given display and adds it to the map
|
||||
* if it doesn't already exist.
|
||||
*
|
||||
* @param displayId The ID of the display
|
||||
*/
|
||||
private void createNavButtonController(int displayId) {
|
||||
@@ -1137,7 +1213,7 @@ public class TaskbarManager {
|
||||
* Adds the {@link TaskbarActivityContext} associated with the given display ID to taskbar
|
||||
* map if there is not already a taskbar mapped to that displayId.
|
||||
*
|
||||
* @param displayId The ID of the display to retrieve the taskbar for.
|
||||
* @param displayId The ID of the display to retrieve the taskbar for.
|
||||
* @param newTaskbar The new {@link TaskbarActivityContext} to add to the map.
|
||||
*/
|
||||
private void addTaskbarToMap(int displayId, TaskbarActivityContext newTaskbar) {
|
||||
@@ -1157,6 +1233,7 @@ public class TaskbarManager {
|
||||
|
||||
/**
|
||||
* Creates {@link FrameLayout} for the taskbar on the specified display and adds it to map.
|
||||
*
|
||||
* @param displayId The ID of the display for which to create the taskbar root layout.
|
||||
*/
|
||||
private void createTaskbarRootLayout(int displayId) {
|
||||
@@ -1206,7 +1283,7 @@ public class TaskbarManager {
|
||||
/**
|
||||
* Adds the taskbar root layout {@link FrameLayout} to taskbar map, mapped to display ID.
|
||||
*
|
||||
* @param displayId The ID of the display to associate with the taskbar root layout.
|
||||
* @param displayId The ID of the display to associate with the taskbar root layout.
|
||||
* @param rootLayout The taskbar root layout {@link FrameLayout} to add to the map.
|
||||
*/
|
||||
private void addTaskbarRootLayoutToMap(int displayId, FrameLayout rootLayout) {
|
||||
@@ -1233,6 +1310,7 @@ public class TaskbarManager {
|
||||
|
||||
/**
|
||||
* Creates {@link Context} for the taskbar on the specified display.
|
||||
*
|
||||
* @param displayId The ID of the display for which to create the window context.
|
||||
*/
|
||||
private @Nullable Context createWindowContext(int displayId) {
|
||||
@@ -1312,7 +1390,7 @@ public class TaskbarManager {
|
||||
/**
|
||||
* Adds the window context {@link Context} to taskbar map, mapped to display ID.
|
||||
*
|
||||
* @param displayId The ID of the display to associate with the taskbar root layout.
|
||||
* @param displayId The ID of the display to associate with the taskbar root layout.
|
||||
* @param windowContext The window context {@link Context} to add to the map.
|
||||
*/
|
||||
private void addWindowContextToMap(int displayId, @NonNull Context windowContext) {
|
||||
|
||||
@@ -392,6 +392,7 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar
|
||||
|
||||
/** Inflates/binds the hotseat items and recent tasks to the view. */
|
||||
protected void updateItems(ItemInfo[] hotseatItemInfos, List<GroupTask> recentTasks) {
|
||||
if (mActivityContext.isDestroyed()) return;
|
||||
// Filter out unsupported items.
|
||||
hotseatItemInfos = Arrays.stream(hotseatItemInfos)
|
||||
.filter(Objects::nonNull)
|
||||
|
||||
@@ -121,9 +121,10 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
|
||||
public static final int ALPHA_INDEX_NOTIFICATION_EXPANDED = 4;
|
||||
public static final int ALPHA_INDEX_ASSISTANT_INVOKED = 5;
|
||||
public static final int ALPHA_INDEX_SMALL_SCREEN = 6;
|
||||
|
||||
public static final int ALPHA_INDEX_BUBBLE_BAR = 7;
|
||||
private static final int NUM_ALPHA_CHANNELS = 8;
|
||||
public static final int ALPHA_INDEX_RECREATE = 8;
|
||||
|
||||
private static final int NUM_ALPHA_CHANNELS = 9;
|
||||
|
||||
/** Only used for animation purposes, to position the divider between two item indices. */
|
||||
public static final float DIVIDER_VIEW_POSITION_OFFSET = 0.5f;
|
||||
@@ -238,9 +239,22 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
|
||||
R.dimen.transient_taskbar_padding);
|
||||
}
|
||||
|
||||
public void init(TaskbarControllers controllers) {
|
||||
/**
|
||||
* Init of taskbar view controller.
|
||||
*/
|
||||
public void init(TaskbarControllers controllers, AnimatorSet startAnimation) {
|
||||
mControllers = controllers;
|
||||
controllers.bubbleControllers.ifPresent(bc -> mBubbleControllers = bc);
|
||||
|
||||
if (startAnimation != null) {
|
||||
MultiPropertyFactory<View>.MultiProperty multiProperty =
|
||||
mTaskbarIconAlpha.get(ALPHA_INDEX_RECREATE);
|
||||
multiProperty.setValue(0f);
|
||||
Animator animator = multiProperty.animateToValue(1f);
|
||||
animator.setInterpolator(EMPHASIZED);
|
||||
startAnimation.play(animator);
|
||||
}
|
||||
|
||||
mTaskbarView.init(TaskbarViewCallbacksFactory.newInstance(mActivity).create(
|
||||
mActivity, mControllers, mTaskbarView));
|
||||
mTaskbarView.getLayoutParams().height = mActivity.isPhoneMode()
|
||||
@@ -362,6 +376,15 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
|
||||
mTaskbarView.announceAccessibilityChanges();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called with destroying Taskbar with animation.
|
||||
*/
|
||||
public void onDestroyAnimation(AnimatorSet animatorSet) {
|
||||
animatorSet.play(
|
||||
mTaskbarIconAlpha.get(TaskbarViewController.ALPHA_INDEX_RECREATE).animateToValue(
|
||||
0f));
|
||||
}
|
||||
|
||||
public void onDestroy() {
|
||||
if (enableTaskbarPinning()) {
|
||||
mTaskbarView.removeOnLayoutChangeListener(mTaskbarViewLayoutChangeListener);
|
||||
@@ -1299,7 +1322,7 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
|
||||
ObjectAnimator animator = mIconsTranslationXForNavbar.animateToValue(translationX);
|
||||
animator.setStartDelay(FADE_OUT_ANIM_POSITION_DURATION_MS);
|
||||
animator.setDuration(FADE_IN_ANIM_ALPHA_DURATION_MS);
|
||||
animator.setInterpolator(Interpolators.EMPHASIZED);
|
||||
animator.setInterpolator(EMPHASIZED);
|
||||
return animator;
|
||||
}
|
||||
}
|
||||
|
||||
+6
-2
@@ -109,8 +109,11 @@ public class QuickstepAtomicAnimationFactory extends
|
||||
|
||||
// We sync the scrim fade with the taskbar animation duration to avoid any flickers for
|
||||
// taskbar icons disappearing before hotseat icons show up.
|
||||
boolean isPinnedTaskbarAndNotInDesktopMode =
|
||||
isPinnedTaskbar && !DisplayController.isInDesktopMode(mContainer);
|
||||
float scrimUpperBoundFromSplit =
|
||||
QuickstepTransitionManager.getTaskbarToHomeDuration(isPinnedTaskbar)
|
||||
QuickstepTransitionManager.getTaskbarToHomeDuration(
|
||||
isPinnedTaskbarAndNotInDesktopMode)
|
||||
/ (float) config.duration;
|
||||
scrimUpperBoundFromSplit = Math.min(scrimUpperBoundFromSplit, 1f);
|
||||
config.setInterpolator(ANIM_OVERVIEW_ACTIONS_FADE, clampToProgress(LINEAR, 0, 0.25f));
|
||||
@@ -142,7 +145,8 @@ public class QuickstepAtomicAnimationFactory extends
|
||||
if (mContainer.getDeviceProfile().isTaskbarPresent) {
|
||||
config.duration = Math.min(
|
||||
config.duration,
|
||||
QuickstepTransitionManager.getTaskbarToHomeDuration(isPinnedTaskbar));
|
||||
QuickstepTransitionManager.getTaskbarToHomeDuration(
|
||||
isPinnedTaskbarAndNotInDesktopMode));
|
||||
}
|
||||
overview.snapToPage(DEFAULT_PAGE, Math.toIntExact(config.duration));
|
||||
} else {
|
||||
|
||||
@@ -120,6 +120,7 @@ import com.android.launcher3.compat.AccessibilityManagerCompat;
|
||||
import com.android.launcher3.dragndrop.DragView;
|
||||
import com.android.launcher3.logging.StatsLogManager;
|
||||
import com.android.launcher3.logging.StatsLogManager.StatsLogger;
|
||||
import com.android.launcher3.statehandlers.DesktopVisibilityController;
|
||||
import com.android.launcher3.statemanager.BaseState;
|
||||
import com.android.launcher3.statemanager.StatefulContainer;
|
||||
import com.android.launcher3.taskbar.TaskbarThresholdUtils;
|
||||
@@ -1421,8 +1422,10 @@ public abstract class AbsSwipeUpHandler<
|
||||
}
|
||||
if (endTarget == HOME) {
|
||||
boolean isPinnedTaskbar = DisplayController.isPinnedTaskbar(mContext);
|
||||
boolean isNotInDesktop = !DisplayController.isInDesktopMode(mContext);
|
||||
duration = mContainer != null && mContainer.getDeviceProfile().isTaskbarPresent
|
||||
? QuickstepTransitionManager.getTaskbarToHomeDuration(isPinnedTaskbar)
|
||||
? QuickstepTransitionManager.getTaskbarToHomeDuration(
|
||||
isPinnedTaskbar && isNotInDesktop)
|
||||
: StaggeredWorkspaceAnim.DURATION_MS;
|
||||
SystemUiProxy.INSTANCE.get(mContext).updateContextualEduStats(
|
||||
mGestureState.isTrackpadGesture(), GestureType.HOME);
|
||||
@@ -1601,10 +1604,28 @@ public abstract class AbsSwipeUpHandler<
|
||||
mTaskAnimationManager.getCurrentCallbacks());
|
||||
if (mParallelRunningAnim != null) {
|
||||
mParallelRunningAnim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
if (DisplayController.isInDesktopMode(mContext)
|
||||
&& mGestureState.getEndTarget() == HOME) {
|
||||
// Set launcher animation started, so we don't notify from
|
||||
// desktop visibility controller
|
||||
DesktopVisibilityController.INSTANCE.get(
|
||||
mContext).setLauncherAnimationRunning(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
mParallelRunningAnim = null;
|
||||
mStateCallback.setStateOnUiThread(STATE_PARALLEL_ANIM_FINISHED);
|
||||
// Swipe to home animation finished, notify DesktopVisibilityController
|
||||
// to recreate Taskbar
|
||||
if (DisplayController.isInDesktopMode(mContext)
|
||||
&& mGestureState.getEndTarget() == HOME) {
|
||||
DesktopVisibilityController.INSTANCE.get(
|
||||
mContext).onLauncherAnimationFromDesktopEnd();
|
||||
}
|
||||
}
|
||||
});
|
||||
mParallelRunningAnim.start();
|
||||
@@ -1691,7 +1712,6 @@ public abstract class AbsSwipeUpHandler<
|
||||
if (mHandOffAnimationToHome) {
|
||||
handOffAnimation(velocityPxPerMs);
|
||||
}
|
||||
|
||||
windowAnim[0].addAnimatorListener(new AnimationSuccessListener() {
|
||||
@Override
|
||||
public void onAnimationSuccess(Animator animator) {
|
||||
|
||||
@@ -81,8 +81,10 @@ public class StaggeredWorkspaceAnim {
|
||||
|
||||
public StaggeredWorkspaceAnim(QuickstepLauncher launcher, float velocity,
|
||||
boolean animateOverviewScrim, @Nullable View ignoredView, boolean staggerWorkspace) {
|
||||
boolean isPinnedTaskbarAndNotInDesktopMode = DisplayController.isPinnedTaskbar(launcher)
|
||||
&& !DisplayController.isInDesktopMode(launcher);
|
||||
mTaskbarDurationInMs = QuickstepTransitionManager.getTaskbarToHomeDuration(
|
||||
DisplayController.isPinnedTaskbar(launcher));
|
||||
isPinnedTaskbarAndNotInDesktopMode);
|
||||
prepareToAnimate(launcher, animateOverviewScrim);
|
||||
|
||||
mIgnoredView = ignoredView;
|
||||
|
||||
+6
-4
@@ -333,10 +333,12 @@ class TaskbarOverflowTest {
|
||||
Task(Task.TaskKey(it, 0, Intent(), ComponentName("", ""), 0, 2000))
|
||||
}
|
||||
recentsModel.updateRecentTasks(listOf(DesktopTask(deskId = 0, tasks)))
|
||||
desktopTaskListener?.onTasksVisibilityChanged(
|
||||
context.virtualDisplay.display.displayId,
|
||||
tasksToAdd,
|
||||
)
|
||||
for (task in 1..tasksToAdd) {
|
||||
desktopTaskListener?.onTasksVisibilityChanged(
|
||||
context.virtualDisplay.display.displayId,
|
||||
task,
|
||||
)
|
||||
}
|
||||
runOnMainSync { recentsModel.resolvePendingTaskRequests() }
|
||||
}
|
||||
|
||||
|
||||
+2
@@ -959,6 +959,8 @@ class TaskbarRecentAppsControllerTest : TaskbarBaseTestCase() {
|
||||
private fun setInDesktopMode(inDesktopMode: Boolean) {
|
||||
whenever(taskbarControllers.taskbarDesktopModeController.shouldShowDesktopTasksInTaskbar())
|
||||
.thenReturn(inDesktopMode)
|
||||
whenever(taskbarControllers.taskbarDesktopModeController.isInDesktopMode)
|
||||
.thenReturn(inDesktopMode)
|
||||
}
|
||||
|
||||
private fun createItemInfo(
|
||||
|
||||
@@ -99,10 +99,11 @@ public class DisplayController implements ComponentCallbacks,
|
||||
public static final int CHANGE_NAVIGATION_MODE = 1 << 4;
|
||||
public static final int CHANGE_TASKBAR_PINNING = 1 << 5;
|
||||
public static final int CHANGE_DESKTOP_MODE = 1 << 6;
|
||||
public static final int CHANGE_SHOW_LOCKED_TASKBAR = 1 << 7;
|
||||
|
||||
public static final int CHANGE_ALL = CHANGE_ACTIVE_SCREEN | CHANGE_ROTATION
|
||||
| CHANGE_DENSITY | CHANGE_SUPPORTED_BOUNDS | CHANGE_NAVIGATION_MODE
|
||||
| CHANGE_TASKBAR_PINNING | CHANGE_DESKTOP_MODE;
|
||||
| CHANGE_TASKBAR_PINNING | CHANGE_DESKTOP_MODE | CHANGE_SHOW_LOCKED_TASKBAR;
|
||||
|
||||
private static final String ACTION_OVERLAY_CHANGED = "android.intent.action.OVERLAY_CHANGED";
|
||||
private static final String TARGET_OVERLAY_PACKAGE = "android";
|
||||
@@ -211,6 +212,13 @@ public class DisplayController implements ComponentCallbacks,
|
||||
return INSTANCE.get(context).getInfo().isPinnedTaskbar();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the taskbar is pinned in gesture navigation mode.
|
||||
*/
|
||||
public static boolean isInDesktopMode(Context context) {
|
||||
return INSTANCE.get(context).getInfo().isInDesktopMode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the taskbar is forced to be pinned when home is visible.
|
||||
*/
|
||||
@@ -335,6 +343,9 @@ public class DisplayController implements ComponentCallbacks,
|
||||
if (newInfo.mIsInDesktopMode != oldInfo.mIsInDesktopMode) {
|
||||
change |= CHANGE_DESKTOP_MODE;
|
||||
}
|
||||
if (newInfo.mShowLockedTaskbarOnHome != oldInfo.mShowLockedTaskbarOnHome) {
|
||||
change |= CHANGE_SHOW_LOCKED_TASKBAR;
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "handleInfoChange - change: " + getChangeFlagsString(change));
|
||||
@@ -493,6 +504,13 @@ public class DisplayController implements ComponentCallbacks,
|
||||
return navigationMode == NavigationMode.NO_BUTTON && !isTransientTaskbar();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the taskbar is in desktop mode.
|
||||
*/
|
||||
public boolean isInDesktopMode() {
|
||||
return mIsInDesktopMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the bounds represent a tablet.
|
||||
*/
|
||||
@@ -575,6 +593,7 @@ public class DisplayController implements ComponentCallbacks,
|
||||
appendFlag(result, change, CHANGE_NAVIGATION_MODE, "CHANGE_NAVIGATION_MODE");
|
||||
appendFlag(result, change, CHANGE_TASKBAR_PINNING, "CHANGE_TASKBAR_VARIANT");
|
||||
appendFlag(result, change, CHANGE_DESKTOP_MODE, "CHANGE_DESKTOP_MODE");
|
||||
appendFlag(result, change, CHANGE_SHOW_LOCKED_TASKBAR, "CHANGE_SHOW_LOCKED_TASKBAR");
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
@@ -592,6 +611,7 @@ public class DisplayController implements ComponentCallbacks,
|
||||
pw.println(" isTaskbarPinned=" + info.mIsTaskbarPinned);
|
||||
pw.println(" isTaskbarPinnedInDesktopMode=" + info.mIsTaskbarPinnedInDesktopMode);
|
||||
pw.println(" isInDesktopMode=" + info.mIsInDesktopMode);
|
||||
pw.println(" showLockedTaskbarOnHome=" + info.showLockedTaskbarOnHome());
|
||||
pw.println(" currentSize=" + info.currentSize);
|
||||
info.mPerDisplayBounds.forEach((key, value) -> pw.println(
|
||||
" perDisplayBounds - " + key + ": " + value));
|
||||
|
||||
@@ -34,6 +34,7 @@ import com.android.launcher3.dagger.LauncherAppSingleton
|
||||
import com.android.launcher3.util.DisplayController.CHANGE_DENSITY
|
||||
import com.android.launcher3.util.DisplayController.CHANGE_DESKTOP_MODE
|
||||
import com.android.launcher3.util.DisplayController.CHANGE_ROTATION
|
||||
import com.android.launcher3.util.DisplayController.CHANGE_SHOW_LOCKED_TASKBAR
|
||||
import com.android.launcher3.util.DisplayController.CHANGE_TASKBAR_PINNING
|
||||
import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener
|
||||
import com.android.launcher3.util.LauncherModelHelper.SandboxModelContext
|
||||
@@ -209,8 +210,13 @@ class DisplayControllerTest {
|
||||
|
||||
assertTrue(displayController.getInfo().isTransientTaskbar())
|
||||
displayController.notifyConfigChange()
|
||||
|
||||
verify(displayInfoChangeListener)
|
||||
.onDisplayInfoChanged(any(), any(), eq(CHANGE_TASKBAR_PINNING))
|
||||
.onDisplayInfoChanged(
|
||||
any(),
|
||||
any(),
|
||||
eq(CHANGE_TASKBAR_PINNING or CHANGE_SHOW_LOCKED_TASKBAR),
|
||||
)
|
||||
assertFalse(displayController.getInfo().isTransientTaskbar())
|
||||
}
|
||||
|
||||
@@ -227,7 +233,11 @@ class DisplayControllerTest {
|
||||
displayController.onConfigurationChanged(configuration)
|
||||
|
||||
verify(displayInfoChangeListener)
|
||||
.onDisplayInfoChanged(any(), any(), eq(CHANGE_TASKBAR_PINNING))
|
||||
.onDisplayInfoChanged(
|
||||
any(),
|
||||
any(),
|
||||
eq(CHANGE_TASKBAR_PINNING or CHANGE_SHOW_LOCKED_TASKBAR),
|
||||
)
|
||||
assertFalse(displayController.getInfo().isTransientTaskbar())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user