From 15883891ea145784d8ba02e7d3c367f34969b43d Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Fri, 12 Feb 2021 11:24:40 -0800 Subject: [PATCH 1/2] Subtract taskbar size from DeviceProfile#availableHeight Normally availableHeight excludes system insets, but taskbar is added after availableHeight is calculated. This discrepency causes some bad calculations such as TaskView size. Test: touch nav bar when in an app with taskbar present, ensure the task doesn't jump due to incorrect calculation Fixes: 179478728 Bug: 171917176 Change-Id: I16d39d3e1d9708e2a64c81b1ac24466f9567d1b9 --- .../launcher3/BaseQuickstepLauncher.java | 2 +- .../launcher3/taskbar/TaskbarController.java | 3 +- res/values/dimens.xml | 3 ++ src/com/android/launcher3/DeviceProfile.java | 28 +++++++++++++++++-- .../launcher3/util/DisplayController.java | 4 +++ 5 files changed, 35 insertions(+), 5 deletions(-) diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java index d1fa2fd3ef..5b301433c3 100644 --- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java @@ -222,7 +222,7 @@ public abstract class BaseQuickstepLauncher extends Launcher mTaskbarController.cleanup(); mTaskbarController = null; } - if (FeatureFlags.ENABLE_TASKBAR.get() && mDeviceProfile.isTablet) { + if (mDeviceProfile.isTaskbarPresent) { TaskbarActivityContext taskbarActivityContext = new TaskbarActivityContext(this); mTaskbarController = new TaskbarController(this, taskbarActivityContext.getTaskbarContainerView()); diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java index ab05fbf036..d01de657d8 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java @@ -89,8 +89,7 @@ public class TaskbarController { mTaskbarView = mTaskbarContainerView.findViewById(R.id.taskbar_view); mTaskbarView.construct(createTaskbarViewCallbacks()); mWindowManager = mLauncher.getWindowManager(); - mTaskbarSize = new Point(MATCH_PARENT, - mLauncher.getResources().getDimensionPixelSize(R.dimen.taskbar_size)); + mTaskbarSize = new Point(MATCH_PARENT, mLauncher.getDeviceProfile().taskbarSize); mTaskbarStateHandler = mLauncher.getTaskbarStateHandler(); mTaskbarVisibilityController = new TaskbarVisibilityController(mLauncher, createTaskbarVisibilityControllerCallbacks()); diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 1ce7840ae5..beb4b7c7b0 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -259,4 +259,7 @@ 16dp 4dp + + 0dp + diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index 83a7d77601..f2b4638018 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -25,9 +25,12 @@ import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.view.Surface; +import android.view.WindowInsets; +import android.view.WindowManager; import com.android.launcher3.CellLayout.ContainerType; import com.android.launcher3.DevicePaddings.DevicePadding; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.graphics.IconShape; import com.android.launcher3.icons.DotRenderer; import com.android.launcher3.icons.IconNormalizer; @@ -149,6 +152,10 @@ public class DeviceProfile { public DotRenderer mDotRendererWorkSpace; public DotRenderer mDotRendererAllApps; + // Taskbar + public boolean isTaskbarPresent; + public int taskbarSize; + DeviceProfile(Context context, InvariantDeviceProfile inv, Info info, Point minSize, Point maxSize, int width, int height, boolean isLandscape, boolean isMultiWindowMode, boolean transposeLayoutWithOrientation, @@ -163,12 +170,13 @@ public class DeviceProfile { // Determine sizes. widthPx = width; heightPx = height; + int nonFinalAvailableHeightPx; if (isLandscape) { availableWidthPx = maxSize.x; - availableHeightPx = minSize.y; + nonFinalAvailableHeightPx = minSize.y; } else { availableWidthPx = minSize.x; - availableHeightPx = maxSize.y; + nonFinalAvailableHeightPx = maxSize.y; } mInfo = info; @@ -192,6 +200,22 @@ public class DeviceProfile { : Configuration.ORIENTATION_PORTRAIT); final Resources res = context.getResources(); + isTaskbarPresent = isTablet && FeatureFlags.ENABLE_TASKBAR.get(); + if (isTaskbarPresent) { + // Taskbar will be added later, but provides bottom insets that we should subtract + // from availableHeightPx. + taskbarSize = res.getDimensionPixelSize(R.dimen.taskbar_size); + WindowInsets windowInsets = DisplayController.INSTANCE.get(context).getHolder(mInfo.id) + .getDisplayContext().getSystemService(WindowManager.class) + .getCurrentWindowMetrics().getWindowInsets(); + int nonOverlappingTaskbarInset = + taskbarSize - windowInsets.getSystemWindowInsetBottom(); + if (nonOverlappingTaskbarInset > 0) { + nonFinalAvailableHeightPx -= nonOverlappingTaskbarInset; + } + } + availableHeightPx = nonFinalAvailableHeightPx; + edgeMarginPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_edge_margin); desiredWorkspaceLeftRightMarginPx = isVerticalBarLayout() ? 0 : edgeMarginPx; diff --git a/src/com/android/launcher3/util/DisplayController.java b/src/com/android/launcher3/util/DisplayController.java index 3b7bcc285a..e787342346 100644 --- a/src/com/android/launcher3/util/DisplayController.java +++ b/src/com/android/launcher3/util/DisplayController.java @@ -193,6 +193,10 @@ public class DisplayController implements DisplayListener { : new Info(context, display); } + public Context getDisplayContext() { + return mDisplayContext; + } + protected void handleOnChange() { Info oldInfo = mInfo; Info newInfo = createInfoForContext(mDisplayContext); From 786dd93f2ba9b50a2b6b88670f96a7491983fb2a Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Wed, 17 Feb 2021 15:20:31 -0800 Subject: [PATCH 2/2] Fix a couple of crashes when taskbar isn't yet attached - Handle back to back addTaskbarIfNecessary(). Specifically, handle cleanup() before the previous add was attached. This is already handled on WM side, just had to remove isAttachedToWindow() check. - Add isAttachedToWindow() check to isViewInTaskbar() Test: call addTaskbarIfNecessary() three times back to back, ensure no crash. Fixes: 180509238 Bug: 171917176 Change-Id: Id68b6c376029eb5c651f47afa56666391c516aef --- .../com/android/launcher3/taskbar/TaskbarController.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java index d01de657d8..5dddaf3ed0 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java @@ -232,14 +232,10 @@ public class TaskbarController { } private void removeFromWindowManager() { - if (mTaskbarContainerView.isAttachedToWindow()) { - mWindowManager.removeViewImmediate(mTaskbarContainerView); - } + mWindowManager.removeViewImmediate(mTaskbarContainerView); } private void addToWindowManager() { - removeFromWindowManager(); - final int gravity = Gravity.BOTTOM; mWindowLayoutParams = new WindowManager.LayoutParams( @@ -377,7 +373,8 @@ public class TaskbarController { * @return Whether the given View is in the same window as Taskbar. */ public boolean isViewInTaskbar(View v) { - return mTaskbarContainerView.getWindowId().equals(v.getWindowId()); + return mTaskbarContainerView.isAttachedToWindow() + && mTaskbarContainerView.getWindowId().equals(v.getWindowId()); } /**