diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt index abd467d8a4..a948fb37e7 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt @@ -44,8 +44,12 @@ class TaskbarBackgroundRenderer(context: TaskbarActivityContext) { private var keyShadowDistance = 0f private var bottomMargin = 0 - private val leftCornerRadius = context.leftCornerRadius.toFloat() - private val rightCornerRadius = context.rightCornerRadius.toFloat() + private val fullLeftCornerRadius = context.leftCornerRadius.toFloat() + private val fullRightCornerRadius = context.rightCornerRadius.toFloat() + private var leftCornerRadius = fullLeftCornerRadius + private var rightCornerRadius = fullRightCornerRadius + private val square: Path = Path() + private val circle: Path = Path() private val invertedLeftCornerPath: Path = Path() private val invertedRightCornerPath: Path = Path() @@ -63,13 +67,29 @@ class TaskbarBackgroundRenderer(context: TaskbarActivityContext) { keyShadowDistance = res.getDimension(R.dimen.transient_taskbar_key_shadow_distance) } + setCornerRoundness(DEFAULT_ROUNDNESS) + } + + /** + * Sets the roundness of the round corner above Taskbar. No effect on transient Taskkbar. + * @param cornerRoundness 0 has no round corner, 1 has complete round corner. + */ + fun setCornerRoundness(cornerRoundness: Float) { + if (isTransientTaskbar && !transientBackgroundBounds.isEmpty) { + return + } + + leftCornerRadius = fullLeftCornerRadius * cornerRoundness + rightCornerRadius = fullRightCornerRadius * cornerRoundness + // Create the paths for the inverted rounded corners above the taskbar. Start with a filled // square, and then subtract out a circle from the appropriate corner. - val square = Path() + square.reset() square.addRect(0f, 0f, leftCornerRadius, leftCornerRadius, Path.Direction.CW) - val circle = Path() + circle.reset() circle.addCircle(leftCornerRadius, 0f, leftCornerRadius, Path.Direction.CW) invertedLeftCornerPath.op(square, circle, Path.Op.DIFFERENCE) + square.reset() square.addRect(0f, 0f, rightCornerRadius, rightCornerRadius, Path.Direction.CW) circle.reset() @@ -121,4 +141,8 @@ class TaskbarBackgroundRenderer(context: TaskbarActivityContext) { canvas.restore() } + + companion object { + const val DEFAULT_ROUNDNESS = 1f + } } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java index 9c2d21ef8c..fc20753c54 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java @@ -23,6 +23,7 @@ import androidx.annotation.VisibleForTesting; import com.android.launcher3.taskbar.allapps.TaskbarAllAppsController; import com.android.launcher3.taskbar.overlay.TaskbarOverlayController; +import com.android.quickstep.AnimatedFloat; import com.android.systemui.shared.rotation.RotationButtonController; import java.io.PrintWriter; @@ -58,6 +59,7 @@ public class TaskbarControllers { public final TaskbarOverlayController taskbarOverlayController; @Nullable private LoggableTaskbarController[] mControllersToLog = null; + @Nullable private BackgroundRendererController[] mBackgroundRendererControllers = null; /** Do not store this controller, as it may change at runtime. */ @NonNull public TaskbarUIController uiController = TaskbarUIController.DEFAULT; @@ -67,6 +69,9 @@ public class TaskbarControllers { @Nullable private TaskbarSharedState mSharedState = null; + // Roundness property for round corner above taskbar . + private final AnimatedFloat mCornerRoundness = new AnimatedFloat(this::updateCornerRoundness); + public TaskbarControllers(TaskbarActivityContext taskbarActivityContext, TaskbarDragController taskbarDragController, TaskbarNavButtonController navButtonController, @@ -148,6 +153,11 @@ public class TaskbarControllers { taskbarAutohideSuspendController, taskbarPopupController, taskbarInsetsController, voiceInteractionWindowController }; + mBackgroundRendererControllers = new BackgroundRendererController[] { + taskbarDragLayerController, taskbarScrimViewController, + voiceInteractionWindowController + }; + mCornerRoundness.updateValue(TaskbarBackgroundRenderer.DEFAULT_ROUNDNESS); mAreAllControllersInitialized = true; for (Runnable postInitCallback : mPostInitCallbacks) { @@ -191,6 +201,7 @@ public class TaskbarControllers { taskbarRecentAppsController.onDestroy(); mControllersToLog = null; + mBackgroundRendererControllers = null; } /** @@ -224,6 +235,23 @@ public class TaskbarControllers { rotationButtonController.dumpLogs(prefix + "\t", pw); } + /** + * Returns a float property that animates roundness of the round corner above Taskbar. + */ + public AnimatedFloat getTaskbarCornerRoundness() { + return mCornerRoundness; + } + + private void updateCornerRoundness() { + if (mBackgroundRendererControllers == null) { + return; + } + + for (BackgroundRendererController controller : mBackgroundRendererControllers) { + controller.setCornerRoundness(mCornerRoundness.value); + } + } + @VisibleForTesting TaskbarActivityContext getTaskbarActivityContext() { // Used to mock @@ -233,4 +261,12 @@ public class TaskbarControllers { protected interface LoggableTaskbarController { void dumpLogs(String prefix, PrintWriter pw); } + + protected interface BackgroundRendererController { + /** + * Sets the roundness of the round corner above Taskbar. + * @param cornerRoundness 0 has no round corner, 1 has complete round corner. + */ + void setCornerRoundness(float cornerRoundness); + } } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java index 7c9a13c5dc..41f39653c3 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java @@ -158,6 +158,15 @@ public class TaskbarDragLayer extends BaseDragLayer { invalidate(); } + /** + * Sets the roundness of the round corner above Taskbar. + * @param cornerRoundness 0 has no round corner, 1 has complete round corner. + */ + protected void setCornerRoundness(float cornerRoundness) { + mBackgroundRenderer.setCornerRoundness(cornerRoundness); + invalidate(); + } + @Override public boolean dispatchTouchEvent(MotionEvent ev) { TestLogging.recordMotionEvent(TestProtocol.SEQUENCE_MAIN, "Touch event", ev); diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java index 13ecf81a7d..9765a41b7d 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java @@ -32,7 +32,8 @@ import java.io.PrintWriter; /** * Handles properties/data collection, then passes the results to TaskbarDragLayer to render. */ -public class TaskbarDragLayerController implements TaskbarControllers.LoggableTaskbarController { +public class TaskbarDragLayerController implements TaskbarControllers.LoggableTaskbarController, + TaskbarControllers.BackgroundRendererController { private final TaskbarActivityContext mActivity; private final TaskbarDragLayer mTaskbarDragLayer; @@ -138,6 +139,11 @@ public class TaskbarDragLayerController implements TaskbarControllers.LoggableTa updateNavBarDarkIntensityMultiplier(); } + @Override + public void setCornerRoundness(float cornerRoundness) { + mTaskbarDragLayer.setCornerRoundness(cornerRoundness); + } + private void updateNavBarDarkIntensityMultiplier() { // Zero out the app-requested dark intensity when we're drawing our own background. float effectiveBgAlpha = mLastSetBackgroundAlpha * (1 - mBgOffset.value); diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java index 723e21400e..fc26f5fe7f 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java @@ -73,6 +73,7 @@ import java.util.StringJoiner; private TaskbarControllers mControllers; private AnimatedFloat mTaskbarBackgroundAlpha; + private AnimatedFloat mTaskbarCornerRoundness; private MultiProperty mIconAlphaForHome; private QuickstepLauncher mLauncher; @@ -133,6 +134,7 @@ import java.util.StringJoiner; mTaskbarBackgroundAlpha = mControllers.taskbarDragLayerController .getTaskbarBackgroundAlpha(); + mTaskbarCornerRoundness = mControllers.getTaskbarCornerRoundness(); mIconAlphaForHome = mControllers.taskbarViewController .getTaskbarIconAlpha().get(ALPHA_INDEX_HOME); @@ -316,6 +318,19 @@ import java.util.StringJoiner; .setDuration(duration)); } + float cornerRoundness = goingToLauncher ? 0 : 1; + // Don't animate if corner roundness has reached desired value. + if (mTaskbarCornerRoundness.isAnimating() + || mTaskbarCornerRoundness.value != cornerRoundness) { + mTaskbarCornerRoundness.cancelAnimation(); + if (DEBUG) { + Log.d(TAG, "onStateChangeApplied - taskbarCornerRoundness - " + + mTaskbarCornerRoundness.value + + " -> " + cornerRoundness + ": " + duration); + } + animatorSet.play(mTaskbarCornerRoundness.animateToValue(cornerRoundness)); + } + if (mIconAlignment.isAnimatingToValue(toAlignment) || mIconAlignment.isSettledOnValue(toAlignment)) { // Already at desired value, but make sure we run the callback at the end. @@ -333,6 +348,7 @@ import java.util.StringJoiner; } animatorSet.play(iconAlignAnim); } + animatorSet.setInterpolator(EMPHASIZED); if (start) { diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimView.java index 1d3757fca2..cdc6d59bf1 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimView.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimView.java @@ -69,4 +69,13 @@ public class TaskbarScrimView extends View { mRenderer.getPaint().setAlpha((int) (alpha * 255)); invalidate(); } + + /** + * Sets the roundness of the round corner above Taskbar. + * @param cornerRoundness 0 has no round corner, 1 has complete round corner. + */ + protected void setCornerRoundness(float cornerRoundness) { + mRenderer.setCornerRoundness(cornerRoundness); + invalidate(); + } } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java index c3b0f57c2d..ce191b78de 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java @@ -30,7 +30,8 @@ import java.io.PrintWriter; /** * Handles properties/data collection, and passes the results to {@link TaskbarScrimView} to render. */ -public class TaskbarScrimViewController implements TaskbarControllers.LoggableTaskbarController { +public class TaskbarScrimViewController implements TaskbarControllers.LoggableTaskbarController, + TaskbarControllers.BackgroundRendererController { private static final float SCRIM_ALPHA = 0.6f; @@ -94,6 +95,11 @@ public class TaskbarScrimViewController implements TaskbarControllers.LoggableTa SystemUiProxy.INSTANCE.get(mActivity).onBackPressed(); } + @Override + public void setCornerRoundness(float cornerRoundness) { + mScrimView.setCornerRoundness(cornerRoundness); + } + @Override public void dumpLogs(String prefix, PrintWriter pw) { pw.println(prefix + "TaskbarScrimViewController:"); diff --git a/quickstep/src/com/android/launcher3/taskbar/VoiceInteractionWindowController.kt b/quickstep/src/com/android/launcher3/taskbar/VoiceInteractionWindowController.kt index 837af589bd..a033507b8e 100644 --- a/quickstep/src/com/android/launcher3/taskbar/VoiceInteractionWindowController.kt +++ b/quickstep/src/com/android/launcher3/taskbar/VoiceInteractionWindowController.kt @@ -14,7 +14,8 @@ private const val STASHED_HANDLE_FADE_DURATION = 180L * Controls Taskbar behavior while Voice Interaction Window (assistant) is showing. */ class VoiceInteractionWindowController(val context: TaskbarActivityContext) - : TaskbarControllers.LoggableTaskbarController { + : TaskbarControllers.LoggableTaskbarController, + TaskbarControllers.BackgroundRendererController { private val taskbarBackgroundRenderer = TaskbarBackgroundRenderer(context) @@ -111,6 +112,11 @@ class VoiceInteractionWindowController(val context: TaskbarActivityContext) } } + override fun setCornerRoundness(cornerRoundness: Float) { + taskbarBackgroundRenderer.setCornerRoundness(cornerRoundness) + separateWindowForTaskbarBackground.invalidate() + } + override fun dumpLogs(prefix: String, pw: PrintWriter) { pw.println(prefix + "VoiceInteractionWindowController:") pw.println("$prefix\tisVoiceInteractionWindowVisible=$isVoiceInteractionWindowVisible")