From 25137534a1e7194cc317c368d02b615caca07a20 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Mon, 18 Apr 2022 15:29:45 -0700 Subject: [PATCH 1/6] Fixing potential NullPointer exceptions when Launcher is created before TouchInteractionService is initialized SystemUiProxy is a wrapper opject which holds the state information until the actual proxy is initialized. It is safe to be initialized lazily. Bug: 221961069 Test: Verified on device Change-Id: I1a621cad52e5b8384439ef02de6b95c6452bcb06 --- .../launcher3/QuickstepTransitionManager.java | 6 +++--- .../android/quickstep/AbsSwipeUpHandler.java | 2 +- .../LauncherBackAnimationController.java | 21 ++++--------------- .../quickstep/RecentsAnimationController.java | 13 +++++------- .../quickstep/TaskAnimationManager.java | 5 ++--- .../android/quickstep/views/RecentsView.java | 5 +---- .../com/android/quickstep/views/TaskView.java | 6 +----- 7 files changed, 17 insertions(+), 41 deletions(-) diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java index 5b912ade65..097609f2d9 100644 --- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java @@ -1161,7 +1161,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener new LauncherAnimationRunner(mHandler, mWallpaperOpenTransitionRunner, false /* startAtFrontOfQueue */), mLauncher.getIApplicationThread()); mLauncherOpenTransition.addHomeOpenCheck(mLauncher.getComponentName()); - SystemUiProxy.INSTANCE.getNoCreate().registerRemoteTransition(mLauncherOpenTransition); + SystemUiProxy.INSTANCE.get(mLauncher).registerRemoteTransition(mLauncherOpenTransition); } if (mBackAnimationController != null) { mBackAnimationController.registerBackCallbacks(mHandler); @@ -1172,7 +1172,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener unregisterRemoteAnimations(); unregisterRemoteTransitions(); mStartingWindowListener.setTransitionManager(null); - SystemUiProxy.INSTANCE.getNoCreate().setStartingWindowListener(null); + SystemUiProxy.INSTANCE.get(mLauncher).setStartingWindowListener(null); } private void unregisterRemoteAnimations() { @@ -1196,7 +1196,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener } if (hasControlRemoteAppTransitionPermission()) { if (mLauncherOpenTransition == null) return; - SystemUiProxy.INSTANCE.getNoCreate().unregisterRemoteTransition( + SystemUiProxy.INSTANCE.get(mLauncher).unregisterRemoteTransition( mLauncherOpenTransition); mLauncherOpenTransition = null; mWallpaperOpenTransitionRunner = null; diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index 2ae0646ed0..2e581feded 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -770,7 +770,7 @@ public abstract class AbsSwipeUpHandler, // We will handle the sysui flags based on the centermost task view. mRecentsAnimationController.setUseLauncherSystemBarFlags(swipeUpThresholdPassed || (quickswitchThresholdPassed && centermostTaskFlags != 0)); - mRecentsAnimationController.setSplitScreenMinimized(swipeUpThresholdPassed); + mRecentsAnimationController.setSplitScreenMinimized(mContext, swipeUpThresholdPassed); // Provide a hint to WM the direction that we will be settling in case the animation // needs to be canceled mRecentsAnimationController.setWillFinishToHome(swipeUpThresholdPassed); diff --git a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java index cc79f4a1d8..921674a2d4 100644 --- a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java +++ b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java @@ -29,7 +29,6 @@ import android.graphics.PointF; import android.graphics.Rect; import android.graphics.RectF; import android.os.Handler; -import android.util.Log; import android.util.MathUtils; import android.util.Pair; import android.view.RemoteAnimationTarget; @@ -55,7 +54,7 @@ import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat; * the app window and plays the rest of app close transitions in one go. * * This animation is used only for apps that enable back dispatching via - * {@link android.view.OnBackInvokedDispatcher}. The controller registers + * {@link android.window.OnBackInvokedDispatcher}. The controller registers * an {@link IOnBackInvokedCallback} with WM Shell and receives back dispatches when a back * navigation to launcher starts. * @@ -66,7 +65,6 @@ import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat; public class LauncherBackAnimationController { private static final int CANCEL_TRANSITION_DURATION = 233; private static final float MIN_WINDOW_SCALE = 0.7f; - private static final String TAG = "LauncherBackAnimationController"; private final QuickstepTransitionManager mQuickstepTransitionManager; private final Matrix mTransformMatrix = new Matrix(); /** The window position at the beginning of the back animation. */ @@ -115,12 +113,7 @@ public class LauncherBackAnimationController { * @param handler Handler to the thread to run the animations on. */ public void registerBackCallbacks(Handler handler) { - SystemUiProxy systemUiProxy = SystemUiProxy.INSTANCE.getNoCreate(); - if (systemUiProxy == null) { - Log.e(TAG, "SystemUiProxy is null. Skip registering back invocation callbacks"); - return; - } - systemUiProxy.setBackToLauncherCallback( + SystemUiProxy.INSTANCE.get(mLauncher).setBackToLauncherCallback( new IOnBackInvokedCallback.Stub() { @Override public void onBackCancelled() { @@ -170,10 +163,7 @@ public class LauncherBackAnimationController { /** Unregisters the back to launcher callback in shell. */ public void unregisterBackCallbacks() { - SystemUiProxy systemUiProxy = SystemUiProxy.INSTANCE.getNoCreate(); - if (systemUiProxy != null) { - systemUiProxy.clearBackToLauncherCallback(); - } + SystemUiProxy.INSTANCE.get(mLauncher).clearBackToLauncherCallback(); } private void startBack(BackEvent backEvent) { @@ -298,10 +288,7 @@ public class LauncherBackAnimationController { mInitialTouchPos.set(0, 0); mAnimatorSetInProgress = false; mSpringAnimationInProgress = false; - SystemUiProxy systemUiProxy = SystemUiProxy.INSTANCE.getNoCreate(); - if (systemUiProxy != null) { - SystemUiProxy.INSTANCE.getNoCreate().onBackToLauncherAnimationFinished(); - } + SystemUiProxy.INSTANCE.get(mLauncher).onBackToLauncherAnimationFinished(); } private void startTransitionAnimations(RectFSpringAnim springAnim, AnimatorSet anim) { diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationController.java b/quickstep/src/com/android/quickstep/RecentsAnimationController.java index c120b32543..2007ee1ebd 100644 --- a/quickstep/src/com/android/quickstep/RecentsAnimationController.java +++ b/quickstep/src/com/android/quickstep/RecentsAnimationController.java @@ -19,6 +19,7 @@ import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import static com.android.quickstep.TaskAnimationManager.ENABLE_SHELL_TRANSITIONS; +import android.content.Context; import android.os.RemoteException; import android.util.Log; import android.view.IRecentsAnimationController; @@ -97,24 +98,20 @@ public class RecentsAnimationController { * Indicates that the gesture has crossed the window boundary threshold and we should minimize * if we are in splitscreen. */ - public void setSplitScreenMinimized(boolean splitScreenMinimized) { + public void setSplitScreenMinimized(Context context, boolean splitScreenMinimized) { if (!mAllowMinimizeSplitScreen) { return; } if (mSplitScreenMinimized != splitScreenMinimized) { mSplitScreenMinimized = splitScreenMinimized; - UI_HELPER_EXECUTOR.execute(() -> { - SystemUiProxy p = SystemUiProxy.INSTANCE.getNoCreate(); - if (p != null) { - p.setSplitScreenMinimized(splitScreenMinimized); - } - }); + UI_HELPER_EXECUTOR.execute(() -> SystemUiProxy.INSTANCE.get(context) + .setSplitScreenMinimized(splitScreenMinimized)); } } /** * Remove task remote animation target from - * {@link RecentsAnimationCallbacks#onTaskAppeared(RemoteAnimationTargetCompat)}}. + * {@link RecentsAnimationCallbacks#onTasksAppeared}}. */ @UiThread public void removeTaskTarget(@NonNull RemoteAnimationTargetCompat target) { diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java index b8334a9ae8..f094d712a1 100644 --- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java +++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java @@ -177,9 +177,8 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn ((RecentsActivity) activityInterface.getCreatedActivity()).startHome(); return; } - RemoteAnimationTarget[] nonAppTargets = - SystemUiProxy.INSTANCE.getNoCreate() - .onGoingToRecentsLegacy(false, nonHomeApps); + RemoteAnimationTarget[] nonAppTargets = SystemUiProxy.INSTANCE.get(mCtx) + .onGoingToRecentsLegacy(false, nonHomeApps); if (ENABLE_QUICKSTEP_LIVE_TILE.get() && activityInterface.isInLiveTileMode() && activityInterface.getCreatedActivity() != null) { diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index aff9df6f35..50fb9df773 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -4486,10 +4486,7 @@ public abstract class RecentsView Date: Tue, 19 Apr 2022 15:47:13 +0800 Subject: [PATCH 2/6] Add jank instrument support for split screen Add jank instrument support for split screen of anter animation. Bug: 203439850 Test: build passed Test: verified with systrace dump Change-Id: I128fe829b36198e1a437d27427b54ebdc67e5f52 --- .../quickstep/views/GroupedTaskView.java | 9 ++++++++- .../android/quickstep/views/RecentsView.java | 18 +++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java index 955fffcdb4..244a794562 100644 --- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java +++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java @@ -26,6 +26,7 @@ import com.android.quickstep.util.CancellableTask; import com.android.quickstep.util.RecentsOrientedState; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.recents.model.ThumbnailData; +import com.android.systemui.shared.system.InteractionJankMonitorWrapper; import java.util.HashMap; import java.util.function.Consumer; @@ -171,8 +172,14 @@ public class GroupedTaskView extends TaskView { RunnableList endCallback = new RunnableList(); RecentsView recentsView = getRecentsView(); // Callbacks run from remote animation when recents animation not currently running + InteractionJankMonitorWrapper.begin(this, + InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER, "Enter form GroupedTaskView"); recentsView.getSplitPlaceholder().launchTasks(this /*groupedTaskView*/, - success -> endCallback.executeAllAndDestroy(), + success -> { + endCallback.executeAllAndDestroy(); + InteractionJankMonitorWrapper.end( + InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER); + }, false /* freezeTaskList */); // Callbacks get run from recentsView for case when recents animation already running diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index aff9df6f35..6f49989396 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -175,6 +175,7 @@ import com.android.systemui.plugins.ResourceProvider; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.ActivityManagerWrapper; +import com.android.systemui.shared.system.InteractionJankMonitorWrapper; import com.android.systemui.shared.system.PackageManagerWrapper; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams; @@ -2744,9 +2745,16 @@ public abstract class RecentsView { if (success) { mSplitToast.show(); + InteractionJankMonitorWrapper.end( + InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER); + } else { + InteractionJankMonitorWrapper.cancel( + InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER); } }); } @@ -4040,9 +4048,11 @@ public abstract class RecentsView - mSplitSelectStateController.launchSplitTasks( - aBoolean1 -> RecentsView.this.resetFromSplitSelectionState())); + pendingAnimation.addEndListener(aBoolean -> { + mSplitSelectStateController.launchSplitTasks( + aBoolean1 -> RecentsView.this.resetFromSplitSelectionState()); + InteractionJankMonitorWrapper.end(InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER); + }); if (containerTaskView.containsMultipleTasks()) { // If we are launching from a child task, then only hide the thumbnail itself mSecondSplitHiddenView = thumbnailView; @@ -4050,6 +4060,8 @@ public abstract class RecentsView Date: Mon, 11 Apr 2022 07:57:18 +0000 Subject: [PATCH 3/6] Refactor code to be used in LauncherLily features Refactor add to workspace code to be used in Lily Launcher. Also utilising code swap feature to swap out functionality of sorting items on workspaces and finding next vacant space. Bug: b/218186705 Test: Manually tested Launcher3 works. Change-Id: I42a44eabeb307e1d23ef333e0a169437f9062bb6 --- Android.bp | 4 +- .../launcher3/util/AbsGridOccupancy.java | 56 +++++++++++++++++++ src/com/android/launcher3/Launcher.java | 4 +- .../graphics/LauncherPreviewRenderer.java | 3 - .../launcher3/model/BaseLoaderResults.java | 41 +++++++++++++- .../android/launcher3/model/ModelUtils.java | 38 ------------- .../android/launcher3/util/GridOccupancy.java | 21 +------ .../launcher3/util/AbsGridOccupancy.java | 55 ++++++++++++++++++ 8 files changed, 155 insertions(+), 67 deletions(-) create mode 100644 go/src/com/android/launcher3/util/AbsGridOccupancy.java create mode 100644 src_shortcuts_overrides/com/android/launcher3/util/AbsGridOccupancy.java diff --git a/Android.bp b/Android.bp index b3027bc440..0a55675d43 100644 --- a/Android.bp +++ b/Android.bp @@ -228,7 +228,7 @@ filegroup { ], } -// Common source files used to build go launcher +// Common source files used to build go launcher except go/src files filegroup { name: "launcher-go-src-no-build-config", srcs: [ @@ -236,8 +236,6 @@ filegroup { "src/**/*.kt", "quickstep/src/**/*.java", "quickstep/src/**/*.kt", - "go/src/**/*.java", - "go/src/**/*.kt", "go/quickstep/src/**/*.java", "go/quickstep/src/**/*.kt", ], diff --git a/go/src/com/android/launcher3/util/AbsGridOccupancy.java b/go/src/com/android/launcher3/util/AbsGridOccupancy.java new file mode 100644 index 0000000000..4a46bd193f --- /dev/null +++ b/go/src/com/android/launcher3/util/AbsGridOccupancy.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3.util; + +/** + * Defines method to find the next vacant cell on a grid. + * This uses the default top-down, left-right approach and can be over-written through + * code swaps in different launchers. + */ +public abstract class AbsGridOccupancy { + + /** + * Find the first vacant cell, if there is one. + * + * @param vacantOut Holds the x and y coordinate of the vacant cell + * @param spanX Horizontal cell span. + * @param spanY Vertical cell span. + * + * @return true if a vacant cell was found + */ + protected boolean findVacantCell(int[] vacantOut, boolean[][] cells, int countX, int countY, + int spanX, int spanY) { + for (int y = 0; (y + spanY) <= countY; y++) { + for (int x = 0; (x + spanX) <= countX; x++) { + boolean available = !cells[x][y]; + out: + for (int i = x; i < x + spanX; i++) { + for (int j = y; j < y + spanY; j++) { + available = available && !cells[i][j]; + if (!available) break out; + } + } + if (available) { + vacantOut[0] = x; + vacantOut[1] = y; + return true; + } + } + } + return false; + } +} diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 923e6144f7..eda834e464 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -3234,12 +3234,12 @@ public class Launcher extends StatefulActivity /** Pauses view updates that should not be run during the app launch animation. */ public void pauseExpensiveViewUpdates() { // Pause page indicator animations as they lead to layer trashing. - mWorkspace.getPageIndicator().pauseAnimations(); + getWorkspace().getPageIndicator().pauseAnimations(); } /** Resumes view updates at the end of the app launch animation. */ public void resumeExpensiveViewUpdates() { - mWorkspace.getPageIndicator().skipAnimationsToEnd(); + getWorkspace().getPageIndicator().skipAnimationsToEnd(); } } diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java index 3dfece7660..a11bd4fdad 100644 --- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java +++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java @@ -23,7 +23,6 @@ import static android.view.View.VISIBLE; import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION; import static com.android.launcher3.model.ModelUtils.filterCurrentWorkspaceItems; import static com.android.launcher3.model.ModelUtils.getMissingHotseatRanks; -import static com.android.launcher3.model.ModelUtils.sortWorkspaceItemsSpatially; import android.annotation.TargetApi; import android.app.Fragment; @@ -420,8 +419,6 @@ public class LauncherPreviewRenderer extends ContextWrapper currentWorkspaceItems, otherWorkspaceItems); filterCurrentWorkspaceItems(currentScreenIds, dataModel.appWidgets, currentAppWidgets, otherAppWidgets); - - sortWorkspaceItemsSpatially(mIdp, currentWorkspaceItems); for (ItemInfo itemInfo : currentWorkspaceItems) { switch (itemInfo.itemType) { case Favorites.ITEM_TYPE_APPLICATION: diff --git a/src/com/android/launcher3/model/BaseLoaderResults.java b/src/com/android/launcher3/model/BaseLoaderResults.java index 5b278ab4cf..6c4cfb9068 100644 --- a/src/com/android/launcher3/model/BaseLoaderResults.java +++ b/src/com/android/launcher3/model/BaseLoaderResults.java @@ -18,7 +18,6 @@ package com.android.launcher3.model; import static com.android.launcher3.model.ItemInstallQueue.FLAG_LOADER_RUNNING; import static com.android.launcher3.model.ModelUtils.filterCurrentWorkspaceItems; -import static com.android.launcher3.model.ModelUtils.sortWorkspaceItemsSpatially; import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; import android.os.Process; @@ -27,6 +26,8 @@ import android.util.Log; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherModel.CallbackTask; +import com.android.launcher3.LauncherSettings; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.model.BgDataModel.Callbacks; import com.android.launcher3.model.BgDataModel.FixedContainerItems; import com.android.launcher3.model.data.AppInfo; @@ -110,6 +111,42 @@ public abstract class BaseLoaderResults { public abstract void bindWidgets(); + /** + * Sorts the set of items by hotseat, workspace (spatially from top to bottom, left to right) + */ + protected void sortWorkspaceItemsSpatially(InvariantDeviceProfile profile, + ArrayList workspaceItems) { + final int screenCols = profile.numColumns; + final int screenCellCount = profile.numColumns * profile.numRows; + Collections.sort(workspaceItems, (lhs, rhs) -> { + if (lhs.container == rhs.container) { + // Within containers, order by their spatial position in that container + switch (lhs.container) { + case LauncherSettings.Favorites.CONTAINER_DESKTOP: { + int lr = (lhs.screenId * screenCellCount + lhs.cellY * screenCols + + lhs.cellX); + int rr = (rhs.screenId * screenCellCount + +rhs.cellY * screenCols + + rhs.cellX); + return Integer.compare(lr, rr); + } + case LauncherSettings.Favorites.CONTAINER_HOTSEAT: { + // We currently use the screen id as the rank + return Integer.compare(lhs.screenId, rhs.screenId); + } + default: + if (FeatureFlags.IS_STUDIO_BUILD) { + throw new RuntimeException( + "Unexpected container type when sorting workspace items."); + } + return 0; + } + } else { + // Between containers, order by hotseat, desktop + return Integer.compare(lhs.container, rhs.container); + } + }); + } + protected void executeCallbacksTask(CallbackTask task, Executor executor) { executor.execute(() -> { if (mMyBindingId != mBgDataModel.lastBindId) { @@ -131,7 +168,7 @@ public abstract class BaseLoaderResults { return idleLock; } - private static class WorkspaceBinder { + private class WorkspaceBinder { private final Executor mUiExecutor; private final Callbacks mCallbacks; diff --git a/src/com/android/launcher3/model/ModelUtils.java b/src/com/android/launcher3/model/ModelUtils.java index ef5eef1e43..df6768d582 100644 --- a/src/com/android/launcher3/model/ModelUtils.java +++ b/src/com/android/launcher3/model/ModelUtils.java @@ -23,10 +23,8 @@ import android.graphics.Bitmap; import android.os.Process; import android.util.Log; -import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.LauncherSettings; import com.android.launcher3.Utilities; -import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.icons.BitmapInfo; import com.android.launcher3.icons.LauncherIcons; import com.android.launcher3.model.data.ItemInfo; @@ -91,42 +89,6 @@ public class ModelUtils { } } - /** - * Sorts the set of items by hotseat, workspace (spatially from top to bottom, left to right) - */ - public static void sortWorkspaceItemsSpatially(InvariantDeviceProfile profile, - ArrayList workspaceItems) { - final int screenCols = profile.numColumns; - final int screenCellCount = profile.numColumns * profile.numRows; - Collections.sort(workspaceItems, (lhs, rhs) -> { - if (lhs.container == rhs.container) { - // Within containers, order by their spatial position in that container - switch (lhs.container) { - case LauncherSettings.Favorites.CONTAINER_DESKTOP: { - int lr = (lhs.screenId * screenCellCount + lhs.cellY * screenCols - + lhs.cellX); - int rr = (rhs.screenId * screenCellCount + +rhs.cellY * screenCols - + rhs.cellX); - return Integer.compare(lr, rr); - } - case LauncherSettings.Favorites.CONTAINER_HOTSEAT: { - // We currently use the screen id as the rank - return Integer.compare(lhs.screenId, rhs.screenId); - } - default: - if (FeatureFlags.IS_STUDIO_BUILD) { - throw new RuntimeException( - "Unexpected container type when sorting workspace items."); - } - return 0; - } - } else { - // Between containers, order by hotseat, desktop - return Integer.compare(lhs.container, rhs.container); - } - }); - } - /** * Iterates though current workspace items and returns available hotseat ranks for prediction. */ diff --git a/src/com/android/launcher3/util/GridOccupancy.java b/src/com/android/launcher3/util/GridOccupancy.java index 9c752a7043..13014608c4 100644 --- a/src/com/android/launcher3/util/GridOccupancy.java +++ b/src/com/android/launcher3/util/GridOccupancy.java @@ -7,7 +7,7 @@ import com.android.launcher3.model.data.ItemInfo; /** * Utility object to manage the occupancy in a grid. */ -public class GridOccupancy { +public class GridOccupancy extends AbsGridOccupancy { private final int mCountX; private final int mCountY; @@ -30,24 +30,7 @@ public class GridOccupancy { * @return true if a vacant cell was found */ public boolean findVacantCell(int[] vacantOut, int spanX, int spanY) { - for (int y = 0; (y + spanY) <= mCountY; y++) { - for (int x = 0; (x + spanX) <= mCountX; x++) { - boolean available = !cells[x][y]; - out: - for (int i = x; i < x + spanX; i++) { - for (int j = y; j < y + spanY; j++) { - available = available && !cells[i][j]; - if (!available) break out; - } - } - if (available) { - vacantOut[0] = x; - vacantOut[1] = y; - return true; - } - } - } - return false; + return super.findVacantCell(vacantOut, cells, mCountX, mCountY, spanX, spanY); } public void copyTo(GridOccupancy dest) { diff --git a/src_shortcuts_overrides/com/android/launcher3/util/AbsGridOccupancy.java b/src_shortcuts_overrides/com/android/launcher3/util/AbsGridOccupancy.java new file mode 100644 index 0000000000..968b281787 --- /dev/null +++ b/src_shortcuts_overrides/com/android/launcher3/util/AbsGridOccupancy.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3.util; + +/** + * Defines method to find the next vacant cell on a grid. + * This uses the default top-down, left-right approach and can be over-written through + * code swaps in different launchers. + */ +public abstract class AbsGridOccupancy { + /** + * Find the first vacant cell, if there is one. + * + * @param vacantOut Holds the x and y coordinate of the vacant cell + * @param spanX Horizontal cell span. + * @param spanY Vertical cell span. + * + * @return true if a vacant cell was found + */ + protected boolean findVacantCell(int[] vacantOut, boolean[][] cells, int countX, int countY, + int spanX, int spanY) { + for (int y = 0; (y + spanY) <= countY; y++) { + for (int x = 0; (x + spanX) <= countX; x++) { + boolean available = !cells[x][y]; + out: + for (int i = x; i < x + spanX; i++) { + for (int j = y; j < y + spanY; j++) { + available = available && !cells[i][j]; + if (!available) break out; + } + } + if (available) { + vacantOut[0] = x; + vacantOut[1] = y; + return true; + } + } + } + return false; + } +} From 36c9d888d857bb218c50a64895fa8c4916170655 Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Thu, 14 Apr 2022 16:15:58 -0700 Subject: [PATCH 4/6] Move taskbar insets logic to TaskbarInsetsController Test: TaplTestsTaskbar; manually stash/unstash taskbar, open IME Bug: 215411414 Change-Id: I73622dc020c4f8c8b3d317fcb1dd072bcfc3d274 Merged-In: I73622dc020c4f8c8b3d317fcb1dd072bcfc3d274 --- .../taskbar/NavbarButtonsViewController.java | 2 +- .../taskbar/TaskbarActivityContext.java | 46 +------ .../launcher3/taskbar/TaskbarControllers.java | 8 +- .../taskbar/TaskbarDragLayerController.java | 40 +----- .../taskbar/TaskbarInsetsController.kt | 128 ++++++++++++++++++ quickstep/src/com/android/quickstep/KtR.java | 1 + 6 files changed, 144 insertions(+), 81 deletions(-) create mode 100644 quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java index 175a1d92b2..f65b907668 100644 --- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java @@ -210,7 +210,7 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT 0, 1)); // Center nav buttons in new height for IME. float transForIme = (mContext.getDeviceProfile().taskbarSize - - mContext.getTaskbarHeightForIme()) / 2f; + - mControllers.taskbarInsetsController.getTaskbarHeightForIme()) / 2f; // For gesture nav, nav buttons only show for IME anyway so keep them translated down. float defaultButtonTransY = alwaysShowButtons ? 0 : transForIme; mPropertyHolders.add(new StatePropertyHolder(mTaskbarNavButtonTranslationYForIme, diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index a22398d7e3..711d49a176 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -27,9 +27,6 @@ import static com.android.launcher3.ResourceUtils.getBoolByName; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_OPEN; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED; -import static com.android.systemui.shared.system.WindowManagerWrapper.ITYPE_BOTTOM_TAPPABLE_ELEMENT; -import static com.android.systemui.shared.system.WindowManagerWrapper.ITYPE_EXTRA_NAVIGATION_BAR; -import static com.android.systemui.shared.system.WindowManagerWrapper.ITYPE_SIZE; import android.animation.AnimatorSet; import android.app.ActivityOptions; @@ -39,7 +36,6 @@ import android.content.Intent; import android.content.pm.ActivityInfo.Config; import android.content.pm.LauncherApps; import android.content.res.Resources; -import android.graphics.Insets; import android.graphics.PixelFormat; import android.graphics.Rect; import android.os.Process; @@ -88,7 +84,6 @@ import com.android.launcher3.views.ActivityContext; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.rotation.RotationButtonController; import com.android.systemui.shared.system.ActivityManagerWrapper; -import com.android.systemui.shared.system.WindowManagerWrapper; import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider; import java.io.PrintWriter; @@ -113,7 +108,6 @@ public class TaskbarActivityContext extends BaseTaskbarContext { private final WindowManager mWindowManager; private final @Nullable RoundedCorner mLeftCorner, mRightCorner; - private final int mTaskbarHeightForIme; private WindowManager.LayoutParams mWindowLayoutParams; private boolean mIsFullscreen; // The size we should return to when we call setTaskbarWindowFullscreen(false) @@ -154,7 +148,6 @@ public class TaskbarActivityContext extends BaseTaskbarContext { Settings.Secure.getUriFor(Settings.Secure.NAV_BAR_KIDS_MODE), 0); updateIconSize(resources); - mTaskbarHeightForIme = resources.getDimensionPixelSize(R.dimen.taskbar_ime_size); // Inflate views. mDragLayer = (TaskbarDragLayer) mLayoutInflater.inflate( @@ -201,29 +194,14 @@ public class TaskbarActivityContext extends BaseTaskbarContext { new TaskbarAutohideSuspendController(this), new TaskbarPopupController(this), new TaskbarForceVisibleImmersiveController(this), - new TaskbarAllAppsController(this)); + new TaskbarAllAppsController(this), + new TaskbarInsetsController(this)); } public void init(TaskbarSharedState sharedState) { mLastRequestedNonFullscreenHeight = getDefaultTaskbarWindowHeight(); mWindowLayoutParams = createDefaultWindowLayoutParams(); - WindowManagerWrapper wmWrapper = WindowManagerWrapper.getInstance(); - wmWrapper.setProvidesInsetsTypes( - mWindowLayoutParams, - new int[] { ITYPE_EXTRA_NAVIGATION_BAR, ITYPE_BOTTOM_TAPPABLE_ELEMENT } - ); - // Adjust the frame by the rounded corners (ie. leaving just the bar as the inset) when - // the IME is showing - mWindowLayoutParams.providedInternalImeInsets = new Insets[ITYPE_SIZE]; - final Insets reducingSize = Insets.of(0, - getDefaultTaskbarWindowHeight() - mTaskbarHeightForIme, 0, 0); - mWindowLayoutParams.providedInternalImeInsets[ITYPE_EXTRA_NAVIGATION_BAR] = reducingSize; - mWindowLayoutParams.providedInternalImeInsets[ITYPE_BOTTOM_TAPPABLE_ELEMENT] = - reducingSize; - - mWindowLayoutParams.insetsRoundedCornerFrame = true; - // Initialize controllers after all are constructed. mControllers.init(sharedState); updateSysuiStateFlags(sharedState.sysuiStateFlags, true /* fromInit */); @@ -303,6 +281,10 @@ public class TaskbarActivityContext extends BaseTaskbarContext { return mRightCorner == null ? 0 : mRightCorner.getRadius(); } + public WindowManager.LayoutParams getWindowLayoutParams() { + return mWindowLayoutParams; + } + @Override public TaskbarDragLayer getDragLayer() { return mDragLayer; @@ -568,14 +550,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext { } } mWindowLayoutParams.height = height; - final Insets reducingSize = - Insets.of(0, height - mTaskbarHeightForIme, 0, 0); - if (mWindowLayoutParams.providedInternalImeInsets == null) { - mWindowLayoutParams.providedInternalImeInsets = new Insets[ITYPE_SIZE]; - } - mWindowLayoutParams.providedInternalImeInsets[ITYPE_EXTRA_NAVIGATION_BAR] = reducingSize; - mWindowLayoutParams.providedInternalImeInsets[ITYPE_BOTTOM_TAPPABLE_ELEMENT] = - reducingSize; + mControllers.taskbarInsetsController.onTaskbarWindowHeightChanged(); mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams); } @@ -586,13 +561,6 @@ public class TaskbarActivityContext extends BaseTaskbarContext { return mDeviceProfile.taskbarSize + Math.max(getLeftCornerRadius(), getRightCornerRadius()); } - /** - * Returns the bottom insets taskbar provides to the IME when IME is visible. - */ - public int getTaskbarHeightForIme() { - return mTaskbarHeightForIme; - } - /** * Either adds or removes {@link WindowManager.LayoutParams#FLAG_NOT_FOCUSABLE} on the taskbar * window. diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java index a3586396ea..5d3a1520fc 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java @@ -51,6 +51,7 @@ public class TaskbarControllers { public final TaskbarPopupController taskbarPopupController; public final TaskbarForceVisibleImmersiveController taskbarForceVisibleImmersiveController; public final TaskbarAllAppsController taskbarAllAppsController; + public final TaskbarInsetsController taskbarInsetsController; @Nullable private LoggableTaskbarController[] mControllersToLog = null; @@ -76,7 +77,8 @@ public class TaskbarControllers { TaskbarAutohideSuspendController taskbarAutoHideSuspendController, TaskbarPopupController taskbarPopupController, TaskbarForceVisibleImmersiveController taskbarForceVisibleImmersiveController, - TaskbarAllAppsController taskbarAllAppsController) { + TaskbarAllAppsController taskbarAllAppsController, + TaskbarInsetsController taskbarInsetsController) { this.taskbarActivityContext = taskbarActivityContext; this.taskbarDragController = taskbarDragController; this.navButtonController = navButtonController; @@ -94,6 +96,7 @@ public class TaskbarControllers { this.taskbarPopupController = taskbarPopupController; this.taskbarForceVisibleImmersiveController = taskbarForceVisibleImmersiveController; this.taskbarAllAppsController = taskbarAllAppsController; + this.taskbarInsetsController = taskbarInsetsController; } /** @@ -119,13 +122,14 @@ public class TaskbarControllers { taskbarForceVisibleImmersiveController.init(this); taskbarAllAppsController.init(this, sharedState); navButtonController.init(this); + taskbarInsetsController.init(this); mControllersToLog = new LoggableTaskbarController[] { taskbarDragController, navButtonController, navbarButtonsViewController, taskbarDragLayerController, taskbarScrimViewController, taskbarViewController, taskbarUnfoldAnimationController, taskbarKeyguardController, stashedHandleViewController, taskbarStashController, taskbarEduController, - taskbarAutohideSuspendController, taskbarPopupController + taskbarAutohideSuspendController, taskbarPopupController, taskbarInsetsController }; mAreAllControllersInitialized = true; diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java index c7330d365c..307f674ee6 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java @@ -15,18 +15,10 @@ */ package com.android.launcher3.taskbar; -import static com.android.launcher3.AbstractFloatingView.TYPE_ALL; -import static com.android.launcher3.AbstractFloatingView.TYPE_TASKBAR_ALL_APPS; -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; - import android.content.res.Resources; import android.graphics.Rect; -import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.R; -import com.android.launcher3.anim.AlphaUpdateListener; import com.android.launcher3.util.TouchController; import com.android.quickstep.AnimatedFloat; import com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo; @@ -168,37 +160,7 @@ public class TaskbarDragLayerController implements TaskbarControllers.LoggableTa * @see InsetsInfo#setTouchableInsets(int) */ public void updateInsetsTouchability(InsetsInfo insetsInfo) { - insetsInfo.touchableRegion.setEmpty(); - // Always have nav buttons be touchable - mControllers.navbarButtonsViewController.addVisibleButtonsRegion( - mTaskbarDragLayer, insetsInfo.touchableRegion); - boolean insetsIsTouchableRegion = true; - - if (mTaskbarDragLayer.getAlpha() < AlphaUpdateListener.ALPHA_CUTOFF_THRESHOLD) { - // Let touches pass through us. - insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION); - } else if (mControllers.navbarButtonsViewController.isImeVisible()) { - insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION); - } else if (!mControllers.uiController.isTaskbarTouchable()) { - // Let touches pass through us. - insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION); - } else if (mControllers.taskbarDragController.isSystemDragInProgress()) { - // Let touches pass through us. - insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION); - } else if (AbstractFloatingView.getOpenView(mActivity, TYPE_TASKBAR_ALL_APPS) != null) { - // Let touches pass through us. - insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION); - } else if (mControllers.taskbarViewController.areIconsVisible() - || AbstractFloatingView.getOpenView(mActivity, TYPE_ALL) != null - || mActivity.isNavBarKidsModeActive()) { - // Taskbar has some touchable elements, take over the full taskbar area - insetsInfo.setTouchableInsets(mActivity.isTaskbarWindowFullscreen() - ? TOUCHABLE_INSETS_FRAME : TOUCHABLE_INSETS_CONTENT); - insetsIsTouchableRegion = false; - } else { - insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION); - } - mActivity.excludeFromMagnificationRegion(insetsIsTouchableRegion); + mControllers.taskbarInsetsController.updateInsetsTouchability(insetsInfo); } /** diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt new file mode 100644 index 0000000000..a2ff7806f7 --- /dev/null +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.launcher3.taskbar + +import android.graphics.Insets +import android.view.WindowManager +import com.android.launcher3.AbstractFloatingView +import com.android.launcher3.R +import com.android.launcher3.anim.AlphaUpdateListener +import com.android.launcher3.taskbar.TaskbarControllers.LoggableTaskbarController +import com.android.quickstep.KtR +import com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo +import com.android.systemui.shared.system.WindowManagerWrapper +import com.android.systemui.shared.system.WindowManagerWrapper.* +import java.io.PrintWriter + +/** + * Handles the insets that Taskbar provides to underlying apps and the IME. + */ +class TaskbarInsetsController(val context: TaskbarActivityContext): LoggableTaskbarController { + + /** The bottom insets taskbar provides to the IME when IME is visible. */ + val taskbarHeightForIme: Int = context.resources.getDimensionPixelSize( + KtR.dimen.taskbar_ime_size) + + // Initialized in init. + private lateinit var controllers: TaskbarControllers + private lateinit var windowLayoutParams: WindowManager.LayoutParams + + fun init(controllers: TaskbarControllers) { + this.controllers = controllers + windowLayoutParams = context.windowLayoutParams + + val wmWrapper: WindowManagerWrapper = getInstance() + wmWrapper.setProvidesInsetsTypes( + windowLayoutParams, + intArrayOf( + ITYPE_EXTRA_NAVIGATION_BAR, + ITYPE_BOTTOM_TAPPABLE_ELEMENT + ) + ) + + windowLayoutParams.providedInternalImeInsets = arrayOfNulls(ITYPE_SIZE) + + onTaskbarWindowHeightChanged() + + windowLayoutParams.insetsRoundedCornerFrame = true + } + + fun onTaskbarWindowHeightChanged() { + val reducingSize = Insets.of(0, windowLayoutParams.height - taskbarHeightForIme, 0, 0) + windowLayoutParams.providedInternalImeInsets[ITYPE_EXTRA_NAVIGATION_BAR] = reducingSize + windowLayoutParams.providedInternalImeInsets[ITYPE_BOTTOM_TAPPABLE_ELEMENT] = reducingSize + } + + /** + * Called to update the touchable insets. + * @see InsetsInfo.setTouchableInsets + */ + fun updateInsetsTouchability(insetsInfo: InsetsInfo) { + insetsInfo.touchableRegion.setEmpty() + // Always have nav buttons be touchable + controllers.navbarButtonsViewController.addVisibleButtonsRegion( + context.dragLayer, insetsInfo.touchableRegion + ) + var insetsIsTouchableRegion = true + if (context.dragLayer.alpha < AlphaUpdateListener.ALPHA_CUTOFF_THRESHOLD) { + // Let touches pass through us. + insetsInfo.setTouchableInsets(InsetsInfo.TOUCHABLE_INSETS_REGION) + } else if (controllers.navbarButtonsViewController.isImeVisible) { + insetsInfo.setTouchableInsets(InsetsInfo.TOUCHABLE_INSETS_REGION) + } else if (!controllers.uiController.isTaskbarTouchable) { + // Let touches pass through us. + insetsInfo.setTouchableInsets(InsetsInfo.TOUCHABLE_INSETS_REGION) + } else if (controllers.taskbarDragController.isSystemDragInProgress) { + // Let touches pass through us. + insetsInfo.setTouchableInsets(InsetsInfo.TOUCHABLE_INSETS_REGION) + } else if (AbstractFloatingView.getOpenView( + context, + AbstractFloatingView.TYPE_TASKBAR_ALL_APPS + ) != null + ) { + // Let touches pass through us. + insetsInfo.setTouchableInsets(InsetsInfo.TOUCHABLE_INSETS_REGION) + } else if (controllers.taskbarViewController.areIconsVisible() + || AbstractFloatingView.getOpenView( + context, + AbstractFloatingView.TYPE_ALL + ) != null + || context.isNavBarKidsModeActive + ) { + // Taskbar has some touchable elements, take over the full taskbar area + insetsInfo.setTouchableInsets( + if (context.isTaskbarWindowFullscreen) { + InsetsInfo.TOUCHABLE_INSETS_FRAME + } else { + InsetsInfo.TOUCHABLE_INSETS_CONTENT + } + ) + insetsIsTouchableRegion = false + } else { + insetsInfo.setTouchableInsets(InsetsInfo.TOUCHABLE_INSETS_REGION) + } + context.excludeFromMagnificationRegion(insetsIsTouchableRegion) + } + + override fun dumpLogs(prefix: String, pw: PrintWriter) { + pw.println(prefix + "TaskbarInsetsController:") + pw.println("$prefix\twindowHeight=${windowLayoutParams.height}") + pw.println("$prefix\tprovidedInternalImeInsets[ITYPE_EXTRA_NAVIGATION_BAR]=" + + "${windowLayoutParams.providedInternalImeInsets[ITYPE_EXTRA_NAVIGATION_BAR]}") + pw.println("$prefix\tprovidedInternalImeInsets[ITYPE_BOTTOM_TAPPABLE_ELEMENT]=" + + "${windowLayoutParams.providedInternalImeInsets[ITYPE_BOTTOM_TAPPABLE_ELEMENT]}") + } +} \ No newline at end of file diff --git a/quickstep/src/com/android/quickstep/KtR.java b/quickstep/src/com/android/quickstep/KtR.java index a768ef5253..758c6e08ef 100644 --- a/quickstep/src/com/android/quickstep/KtR.java +++ b/quickstep/src/com/android/quickstep/KtR.java @@ -31,6 +31,7 @@ public class KtR { public static final class dimen { public static int task_menu_spacing = R.dimen.task_menu_spacing; public static int task_menu_horizontal_padding = R.dimen.task_menu_horizontal_padding; + public static int taskbar_ime_size = R.dimen.taskbar_ime_size; } public static final class layout { From 81bff9becd24a027e0a346dab6adb6b265bd2989 Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Wed, 20 Apr 2022 13:58:53 -0700 Subject: [PATCH 5/6] Disallow long press below taskbar icons Test: long press below icons, doesn't stash; can still swipe up Fixes: 201239461 Change-Id: Ifdf355138d7958c0442814d968f0722f54e12ae1 --- quickstep/src/com/android/launcher3/taskbar/TaskbarView.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java index 8291475f5d..7548398be2 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java @@ -312,8 +312,8 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar if (!mTouchEnabled) { return true; } - if (mIconLayoutBounds.contains((int) event.getX(), (int) event.getY())) { - // Don't allow long pressing between icons. + if (mIconLayoutBounds.left <= event.getX() && event.getX() <= mIconLayoutBounds.right) { + // Don't allow long pressing between icons, or above/below them. return true; } if (mControllerCallbacks.onTouchEvent(event)) { From 26aa8c2496c59ae7bdeb65618e1259ff8d18a238 Mon Sep 17 00:00:00 2001 From: Thales Lima Date: Tue, 12 Apr 2022 16:18:36 +0100 Subject: [PATCH 6/6] Making tablet grid scalable and tuning size Bug: 227344807 Test: manual and HSV Change-Id: I739cd814ecb8f693b4873cd78f2e8c182538be3b --- res/xml/device_profiles.xml | 25 ++++++++++-- res/xml/paddings_6x5.xml | 76 +++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 4 deletions(-) create mode 100644 res/xml/paddings_6x5.xml diff --git a/res/xml/device_profiles.xml b/res/xml/device_profiles.xml index dd201e556f..07ce59862b 100644 --- a/res/xml/device_profiles.xml +++ b/res/xml/device_profiles.xml @@ -145,6 +145,8 @@ launcher:numFolderColumns="3" launcher:numHotseatIcons="6" launcher:numAllAppsColumns="6" + launcher:isScalable="true" + launcher:devicePaddingId="@xml/paddings_6x5" launcher:dbFile="launcher_6_by_5.db" launcher:defaultLayoutId="@xml/default_workspace_6x5" launcher:deviceCategory="tablet" > @@ -153,14 +155,29 @@ launcher:name="Tablet" launcher:minWidthDps="900" launcher:minHeightDps="820" - launcher:minCellHeight="104" - launcher:minCellWidth="80" + launcher:minCellHeight="120" + launcher:minCellWidth="102" + launcher:minCellHeightLandscape="104" + launcher:minCellWidthLandscape="120" launcher:iconImageSize="60" launcher:iconTextSize="14" - launcher:borderSpace="16" + launcher:borderSpaceHorizontal="16" + launcher:borderSpaceVertical="64" + launcher:borderSpaceLandscapeHorizontal="64" + launcher:borderSpaceLandscapeVertical="16" + launcher:horizontalMargin="54" + launcher:horizontalMarginLandscape="120" + launcher:allAppsCellWidth="96" + launcher:allAppsCellHeight="142" + launcher:allAppsCellWidthLandscape="126" + launcher:allAppsCellHeightLandscape="126" launcher:allAppsIconSize="60" launcher:allAppsIconTextSize="14" - launcher:allAppsBorderSpace="16" + launcher:allAppsBorderSpaceHorizontal="8" + launcher:allAppsBorderSpaceVertical="16" + launcher:allAppsBorderSpaceLandscape="16" + launcher:hotseatBorderSpace="58" + launcher:hotseatBorderSpaceLandscape="50.4" launcher:canBeDefault="true" /> diff --git a/res/xml/paddings_6x5.xml b/res/xml/paddings_6x5.xml new file mode 100644 index 0000000000..a958ec7b55 --- /dev/null +++ b/res/xml/paddings_6x5.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file