From dd7a418335c791b5fa2d615dad14ddc22dbdaa09 Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Fri, 13 Aug 2021 17:03:55 -0700 Subject: [PATCH] Draw rounded corners above the taskbar - Increase height of taskbar window, but not contentInsets - Draw the inverted corners as part of TaskbarDragLayer#dispatchDraw() (which handles the background already) Test: visual Bug: 196257194 Fixes: 197129604 Change-Id: I517949a4c2b97c92e3bb43408776db6deb1379b4 --- .../taskbar/TaskbarActivityContext.java | 28 ++++++++++++- .../launcher3/taskbar/TaskbarDragLayer.java | 42 ++++++++++++++++++- .../taskbar/TaskbarDragLayerController.java | 6 ++- .../taskbar/TaskbarViewController.java | 5 ++- 4 files changed, 73 insertions(+), 8 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index ca574e6a8c..8d7a6dc602 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -36,12 +36,14 @@ import android.view.ContextThemeWrapper; import android.view.Display; import android.view.Gravity; import android.view.LayoutInflater; +import android.view.RoundedCorner; import android.view.View; import android.view.WindowManager; import android.widget.FrameLayout; import android.widget.Toast; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.DeviceProfile; @@ -83,6 +85,7 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ private final TaskbarControllers mControllers; private final WindowManager mWindowManager; + private final @Nullable RoundedCorner mLeftCorner, mRightCorner; private WindowManager.LayoutParams mWindowLayoutParams; private boolean mIsFullscreen; // The size we should return to when we call setTaskbarWindowFullscreen(false) @@ -136,10 +139,12 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ ? windowContext.getApplicationContext() : windowContext.getApplicationContext().createDisplayContext(display); mWindowManager = c.getSystemService(WindowManager.class); + mLeftCorner = display.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_LEFT); + mRightCorner = display.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_RIGHT); } public void init() { - mLastRequestedNonFullscreenHeight = mDeviceProfile.taskbarSize; + mLastRequestedNonFullscreenHeight = getDefaultTaskbarWindowHeight(); mWindowLayoutParams = new WindowManager.LayoutParams( MATCH_PARENT, mLastRequestedNonFullscreenHeight, @@ -169,6 +174,14 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ return mNavMode == Mode.THREE_BUTTONS; } + public int getLeftCornerRadius() { + return mLeftCorner == null ? 0 : mLeftCorner.getRadius(); + } + + public int getRightCornerRadius() { + return mRightCorner == null ? 0 : mRightCorner.getRadius(); + } + @Override public LayoutInflater getLayoutInflater() { return mLayoutInflater; @@ -249,8 +262,12 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ setTaskbarWindowHeight(fullscreen ? MATCH_PARENT : mLastRequestedNonFullscreenHeight); } + public boolean isTaskbarWindowFullscreen() { + return mIsFullscreen; + } + /** - * Updates the TaskbarContainer height (pass deviceProfile.taskbarSize to reset). + * Updates the TaskbarContainer height (pass {@link #getDefaultTaskbarWindowHeight()} to reset). */ public void setTaskbarWindowHeight(int height) { if (mWindowLayoutParams.height == height || mIsDestroyed) { @@ -270,6 +287,13 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams); } + /** + * Returns the default height of the window, including the static corner radii above taskbar. + */ + public int getDefaultTaskbarWindowHeight() { + return mDeviceProfile.taskbarSize + Math.max(getLeftCornerRadius(), getRightCornerRadius()); + } + protected void onTaskbarIconClicked(View view) { Object tag = view.getTag(); if (tag instanceof Task) { diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java index cd1baf726d..b42a60ceea 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java @@ -18,6 +18,7 @@ package com.android.launcher3.taskbar; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; +import android.graphics.Path; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; @@ -40,9 +41,12 @@ import com.android.systemui.shared.system.ViewTreeObserverWrapper.OnComputeInset public class TaskbarDragLayer extends BaseDragLayer { private final Paint mTaskbarBackgroundPaint; + private final Path mInvertedLeftCornerPath, mInvertedRightCornerPath; private final OnComputeInsetsListener mTaskbarInsetsComputer = this::onComputeTaskbarInsets; + // Initialized in init. private TaskbarDragLayerController.TaskbarDragLayerCallbacks mControllerCallbacks; + private float mLeftCornerRadius, mRightCornerRadius; private float mTaskbarBackgroundOffset; @@ -65,10 +69,32 @@ public class TaskbarDragLayer extends BaseDragLayer { mTaskbarBackgroundPaint = new Paint(); mTaskbarBackgroundPaint.setColor(getResources().getColor(R.color.taskbar_background)); mTaskbarBackgroundPaint.setAlpha(0); + mTaskbarBackgroundPaint.setFlags(Paint.ANTI_ALIAS_FLAG); + mTaskbarBackgroundPaint.setStyle(Paint.Style.FILL); + + // Will be set in init(), but this ensures they are always non-null. + mInvertedLeftCornerPath = new Path(); + mInvertedRightCornerPath = new Path(); } public void init(TaskbarDragLayerController.TaskbarDragLayerCallbacks callbacks) { mControllerCallbacks = callbacks; + + // Create the paths for the inverted rounded corners above the taskbar. Start with a filled + // square, and then subtracting out a circle from the appropriate corner. + mLeftCornerRadius = mActivity.getLeftCornerRadius(); + mRightCornerRadius = mActivity.getRightCornerRadius(); + Path square = new Path(); + square.addRect(0, 0, mLeftCornerRadius, mLeftCornerRadius, Path.Direction.CW); + Path circle = new Path(); + circle.addCircle(mLeftCornerRadius, 0, mLeftCornerRadius, Path.Direction.CW); + mInvertedLeftCornerPath.op(square, circle, Path.Op.DIFFERENCE); + square.reset(); + square.addRect(0, 0, mRightCornerRadius, mRightCornerRadius, Path.Direction.CW); + circle.reset(); + circle.addCircle(0, 0, mRightCornerRadius, Path.Direction.CW); + mInvertedRightCornerPath.op(square, circle, Path.Op.DIFFERENCE); + recreateControllers(); } @@ -121,8 +147,20 @@ public class TaskbarDragLayer extends BaseDragLayer { protected void dispatchDraw(Canvas canvas) { float backgroundHeight = mControllerCallbacks.getTaskbarBackgroundHeight() * (1f - mTaskbarBackgroundOffset); - canvas.drawRect(0, canvas.getHeight() - backgroundHeight, canvas.getWidth(), - canvas.getHeight(), mTaskbarBackgroundPaint); + canvas.save(); + canvas.translate(0, canvas.getHeight() - backgroundHeight); + + // Draw the background behind taskbar content. + canvas.drawRect(0, 0, canvas.getWidth(), backgroundHeight, mTaskbarBackgroundPaint); + + // Draw the inverted rounded corners above the taskbar. + canvas.translate(0, -mLeftCornerRadius); + canvas.drawPath(mInvertedLeftCornerPath, mTaskbarBackgroundPaint); + canvas.translate(0, mLeftCornerRadius); + canvas.translate(canvas.getWidth() - mRightCornerRadius, -mRightCornerRadius); + canvas.drawPath(mInvertedRightCornerPath, mTaskbarBackgroundPaint); + + canvas.restore(); super.dispatchDraw(canvas); } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java index 14150b9e25..0afa480667 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java @@ -16,6 +16,7 @@ package com.android.launcher3.taskbar; import static com.android.launcher3.AbstractFloatingView.TYPE_ALL; +import static com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo.TOUCHABLE_INSETS_CONTENT; import static com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo.TOUCHABLE_INSETS_FRAME; import static com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo.TOUCHABLE_INSETS_REGION; @@ -132,13 +133,14 @@ public class TaskbarDragLayerController { // Let touches pass through us. insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION); } else if (mControllers.navbarButtonsViewController.isImeVisible()) { - insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_FRAME); + insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_CONTENT); } else if (!mControllers.uiController.isTaskbarTouchable()) { // Let touches pass through us. insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION); } else if (mControllers.taskbarViewController.areIconsVisible()) { // Buttons are visible, take over the full taskbar area - insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_FRAME); + insetsInfo.setTouchableInsets(mActivity.isTaskbarWindowFullscreen() + ? TOUCHABLE_INSETS_FRAME : TOUCHABLE_INSETS_CONTENT); } else { insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION); } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java index 6b95f08090..1882762a67 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java @@ -165,8 +165,9 @@ public class TaskbarViewController { int offsetY = launcherDp.getTaskbarOffsetY(); setter.setFloat(mTaskbarIconTranslationYForHome, VALUE, -offsetY, LINEAR); - int collapsedHeight = mActivity.getDeviceProfile().taskbarSize; - int expandedHeight = collapsedHeight + offsetY; + int collapsedHeight = mActivity.getDefaultTaskbarWindowHeight(); + int expandedHeight = Math.max(collapsedHeight, + mActivity.getDeviceProfile().taskbarSize + offsetY); setter.addOnFrameListener(anim -> mActivity.setTaskbarWindowHeight( anim.getAnimatedFraction() > 0 ? expandedHeight : collapsedHeight));