Merge "Disable split pair long press smart actions" into tm-qpr-dev
diff --git a/quickstep/src/com/android/launcher3/appprediction/AppsDividerView.java b/quickstep/src/com/android/launcher3/appprediction/AppsDividerView.java
index f42b39f..e8374b8 100644
--- a/quickstep/src/com/android/launcher3/appprediction/AppsDividerView.java
+++ b/quickstep/src/com/android/launcher3/appprediction/AppsDividerView.java
@@ -35,6 +35,7 @@
 import com.android.launcher3.R;
 import com.android.launcher3.allapps.FloatingHeaderRow;
 import com.android.launcher3.allapps.FloatingHeaderView;
+import com.android.launcher3.util.OnboardingPrefs;
 import com.android.launcher3.util.Themes;
 import com.android.launcher3.views.ActivityContext;
 
@@ -92,8 +93,10 @@
                 ? R.color.all_apps_label_text_dark
                 : R.color.all_apps_label_text);
 
-        mShowAllAppsLabel = !ActivityContext.lookupContext(
-                getContext()).getOnboardingPrefs().hasReachedMaxCount(ALL_APPS_VISITED_COUNT);
+        OnboardingPrefs<?> onboardingPrefs = ActivityContext.lookupContext(
+                getContext()).getOnboardingPrefs();
+        mShowAllAppsLabel = onboardingPrefs == null || !onboardingPrefs.hasReachedMaxCount(
+                ALL_APPS_VISITED_COUNT);
     }
 
     public void setup(FloatingHeaderView parent, FloatingHeaderRow[] rows, boolean tabsHidden) {
@@ -216,8 +219,8 @@
 
             CharSequence allAppsLabelText = getResources().getText(R.string.all_apps_label);
             mAllAppsLabelLayout = StaticLayout.Builder.obtain(
-                    allAppsLabelText, 0, allAppsLabelText.length(), mPaint,
-                    Math.round(mPaint.measureText(allAppsLabelText.toString())))
+                            allAppsLabelText, 0, allAppsLabelText.length(), mPaint,
+                            Math.round(mPaint.measureText(allAppsLabelText.toString())))
                     .setAlignment(Layout.Alignment.ALIGN_CENTER)
                     .setMaxLines(1)
                     .setIncludePad(true)
diff --git a/quickstep/src/com/android/launcher3/statehandlers/BackButtonAlphaHandler.java b/quickstep/src/com/android/launcher3/statehandlers/BackButtonAlphaHandler.java
index 8c11081..d33859b 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/BackButtonAlphaHandler.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/BackButtonAlphaHandler.java
@@ -17,7 +17,7 @@
 package com.android.launcher3.statehandlers;
 
 import static com.android.launcher3.anim.Interpolators.LINEAR;
-import static com.android.launcher3.util.DisplayController.NavigationMode.TWO_BUTTONS;
+import static com.android.launcher3.util.NavigationMode.TWO_BUTTONS;
 import static com.android.quickstep.AnimatedFloat.VALUE;
 
 import com.android.launcher3.LauncherState;
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 3b1e677..8697b69 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -80,7 +80,7 @@
 import com.android.launcher3.testing.shared.TestProtocol;
 import com.android.launcher3.touch.ItemClickHandler;
 import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.NavigationMode;
+import com.android.launcher3.util.NavigationMode;
 import com.android.launcher3.util.PackageManagerHelper;
 import com.android.launcher3.util.SettingsCache;
 import com.android.launcher3.util.TraceHelper;
@@ -868,6 +868,10 @@
         btv.post(() -> mControllers.taskbarPopupController.showForIcon(btv));
     }
 
+    public boolean isInApp() {
+        return mControllers.taskbarStashController.isInApp();
+    }
+
     protected void dumpLogs(String prefix, PrintWriter pw) {
         pw.println(prefix + "TaskbarActivityContext:");
 
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
index 80b3c1d..bc69088 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
@@ -45,6 +45,7 @@
 import com.android.launcher3.taskbar.unfold.NonDestroyableScopedUnfoldTransitionProgressProvider;
 import com.android.launcher3.uioverrides.QuickstepLauncher;
 import com.android.launcher3.util.DisplayController;
+import com.android.launcher3.util.NavigationMode;
 import com.android.launcher3.util.SettingsCache;
 import com.android.launcher3.util.SimpleBroadcastReceiver;
 import com.android.quickstep.RecentsActivity;
@@ -83,7 +84,7 @@
     // It's destruction/creation will be managed by the activity.
     private final ScopedUnfoldTransitionProgressProvider mUnfoldProgressProvider =
             new NonDestroyableScopedUnfoldTransitionProgressProvider();
-    private DisplayController.NavigationMode mNavMode;
+    private NavigationMode mNavMode;
 
     private TaskbarActivityContext mTaskbarActivityContext;
     private StatefulActivity mActivity;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index c9bc260..0a99204 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -45,9 +45,9 @@
 import static com.android.launcher3.testing.shared.TestProtocol.QUICK_SWITCH_STATE_ORDINAL;
 import static com.android.launcher3.util.DisplayController.CHANGE_ACTIVE_SCREEN;
 import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
-import static com.android.launcher3.util.DisplayController.NavigationMode.TWO_BUTTONS;
 import static com.android.launcher3.util.Executors.THREAD_POOL_EXECUTOR;
 import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+import static com.android.launcher3.util.NavigationMode.TWO_BUTTONS;
 import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY;
 
 import android.animation.AnimatorSet;
@@ -114,16 +114,18 @@
 import com.android.launcher3.uioverrides.touchcontrollers.TwoButtonNavbarTouchController;
 import com.android.launcher3.util.ActivityOptionsWrapper;
 import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.NavigationMode;
 import com.android.launcher3.util.IntSet;
+import com.android.launcher3.util.NavigationMode;
 import com.android.launcher3.util.ObjectWrapper;
 import com.android.launcher3.util.PendingRequestArgs;
 import com.android.launcher3.util.PendingSplitSelectInfo;
 import com.android.launcher3.util.RunnableList;
+import com.android.launcher3.util.SafeCloseable;
 import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
 import com.android.launcher3.util.TouchController;
 import com.android.launcher3.util.UiThreadHelper;
 import com.android.launcher3.util.UiThreadHelper.AsyncCommand;
+import com.android.launcher3.util.ViewCapture;
 import com.android.launcher3.widget.LauncherAppWidgetHost;
 import com.android.quickstep.OverviewCommandHelper;
 import com.android.quickstep.RecentsModel;
@@ -195,6 +197,8 @@
      */
     private PendingSplitSelectInfo mPendingSplitSelectInfo = null;
 
+    private SafeCloseable mViewCapture;
+
     @Override
     protected void setupViews() {
         super.setupViews();
@@ -410,6 +414,7 @@
 
         super.onDestroy();
         mHotseatPredictionController.destroy();
+        mViewCapture.close();
     }
 
     @Override
@@ -509,6 +514,7 @@
         }
         addMultiWindowModeChangedListener(mDepthController);
         initUnfoldTransitionProgressProvider();
+        mViewCapture = ViewCapture.INSTANCE.get(this).startCapture(getWindow());
     }
 
     @Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
index e5cd53a..56ac4c5 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
@@ -45,7 +45,7 @@
 import com.android.launcher3.touch.AbstractStateChangeTouchController;
 import com.android.launcher3.touch.SingleAxisSwipeDetector;
 import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.NavigationMode;
+import com.android.launcher3.util.NavigationMode;
 import com.android.quickstep.SystemUiProxy;
 import com.android.quickstep.TaskUtils;
 import com.android.quickstep.views.RecentsView;
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 1f7b7de..81a5c1c 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -334,6 +334,14 @@
             return ActiveGestureErrorDetector.GestureEvent.STATE_GESTURE_COMPLETED;
         } else if (stateFlag == STATE_GESTURE_CANCELLED) {
             return ActiveGestureErrorDetector.GestureEvent.STATE_GESTURE_CANCELLED;
+        } else if (stateFlag == STATE_SCREENSHOT_CAPTURED) {
+            return ActiveGestureErrorDetector.GestureEvent.STATE_SCREENSHOT_CAPTURED;
+        } else if (stateFlag == STATE_CAPTURE_SCREENSHOT) {
+            return ActiveGestureErrorDetector.GestureEvent.STATE_CAPTURE_SCREENSHOT;
+        } else if (stateFlag == STATE_HANDLER_INVALIDATED) {
+            return ActiveGestureErrorDetector.GestureEvent.STATE_HANDLER_INVALIDATED;
+        } else if (stateFlag == STATE_LAUNCHER_DRAWN) {
+            return ActiveGestureErrorDetector.GestureEvent.STATE_LAUNCHER_DRAWN;
         }
         return null;
     }
@@ -1222,6 +1230,8 @@
         // Let RecentsView handle the scrolling to the task, which we launch in startNewTask()
         // or resumeLastTask().
         if (mRecentsView != null) {
+            ActiveGestureLog.INSTANCE.trackEvent(ActiveGestureErrorDetector.GestureEvent
+                    .SET_ON_PAGE_TRANSITION_END_CALLBACK);
             mRecentsView.setOnPageTransitionEndCallback(
                     () -> mGestureState.setState(STATE_RECENTS_SCROLLING_FINISHED));
         } else {
@@ -1535,7 +1545,7 @@
         Rect keepClearArea;
         if (!ENABLE_PIP_KEEP_CLEAR_ALGORITHM) {
             // make the height equal to hotseatBarSizePx only
-            keepClearArea = new Rect(0, 0, mDp.hotseatBarSizePx, 0);
+            keepClearArea = new Rect(0, 0, 0, mDp.hotseatBarSizePx);
             return keepClearArea;
         }
         // the keep clear area in global screen coordinates, in pixels
@@ -1699,6 +1709,9 @@
      * handler (in case of quick switch).
      */
     private void cancelCurrentAnimation() {
+        ActiveGestureLog.INSTANCE.addLog(
+                "AbsSwipeUpHandler.cancelCurrentAnimation",
+                ActiveGestureErrorDetector.GestureEvent.CANCEL_CURRENT_ANIMATION);
         mCanceled = true;
         mCurrentShift.cancelAnimation();
 
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index 6354282..315a91e 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -55,7 +55,7 @@
 import com.android.launcher3.taskbar.TaskbarUIController;
 import com.android.launcher3.touch.PagedOrientationHandler;
 import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.NavigationMode;
+import com.android.launcher3.util.NavigationMode;
 import com.android.launcher3.views.ScrimView;
 import com.android.quickstep.util.ActivityInitListener;
 import com.android.quickstep.util.AnimatorControllerWithResistance;
diff --git a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
index ba61574..466abbe 100644
--- a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
@@ -16,7 +16,7 @@
 package com.android.quickstep;
 
 import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
-import static com.android.launcher3.util.DisplayController.NavigationMode.NO_BUTTON;
+import static com.android.launcher3.util.NavigationMode.NO_BUTTON;
 import static com.android.quickstep.fallback.RecentsState.BACKGROUND_APP;
 import static com.android.quickstep.fallback.RecentsState.DEFAULT;
 import static com.android.quickstep.fallback.RecentsState.HOME;
diff --git a/quickstep/src/com/android/quickstep/GestureState.java b/quickstep/src/com/android/quickstep/GestureState.java
index bc2f551..38bf1fd 100644
--- a/quickstep/src/com/android/quickstep/GestureState.java
+++ b/quickstep/src/com/android/quickstep/GestureState.java
@@ -189,6 +189,8 @@
             return ActiveGestureErrorDetector.GestureEvent.STATE_END_TARGET_ANIMATION_FINISHED;
         } else if (stateFlag == STATE_RECENTS_SCROLLING_FINISHED) {
             return ActiveGestureErrorDetector.GestureEvent.STATE_RECENTS_SCROLLING_FINISHED;
+        } else if (stateFlag == STATE_RECENTS_ANIMATION_CANCELED) {
+            return ActiveGestureErrorDetector.GestureEvent.STATE_RECENTS_ANIMATION_CANCELED;
         }
         return null;
     }
diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
index 4ceafeb..1127e2c 100644
--- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
@@ -45,7 +45,7 @@
 import com.android.launcher3.touch.PagedOrientationHandler;
 import com.android.launcher3.uioverrides.QuickstepLauncher;
 import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.NavigationMode;
+import com.android.launcher3.util.NavigationMode;
 import com.android.quickstep.GestureState.GestureEndTarget;
 import com.android.quickstep.util.ActivityInitListener;
 import com.android.quickstep.util.AnimatorControllerWithResistance;
diff --git a/quickstep/src/com/android/quickstep/MultiStateCallback.java b/quickstep/src/com/android/quickstep/MultiStateCallback.java
index 56e7fb5..a68bea2 100644
--- a/quickstep/src/com/android/quickstep/MultiStateCallback.java
+++ b/quickstep/src/com/android/quickstep/MultiStateCallback.java
@@ -116,7 +116,13 @@
             if (gestureEvent == null) {
                 continue;
             }
-            ActiveGestureLog.INSTANCE.trackEvent(gestureEvent);
+            if (gestureEvent.mLogEvent && gestureEvent.mTrackEvent) {
+                ActiveGestureLog.INSTANCE.addLog(gestureEvent.name(), gestureEvent);
+            } else if (gestureEvent.mLogEvent) {
+                ActiveGestureLog.INSTANCE.addLog(gestureEvent.name());
+            } else if (gestureEvent.mTrackEvent) {
+                ActiveGestureLog.INSTANCE.trackEvent(gestureEvent);
+            }
         }
     }
 
diff --git a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
index 47c5dd0..1b05fd2 100644
--- a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
+++ b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
@@ -34,7 +34,7 @@
 import com.android.launcher3.R;
 import com.android.launcher3.testing.shared.ResourceUtils;
 import com.android.launcher3.util.DisplayController.Info;
-import com.android.launcher3.util.DisplayController.NavigationMode;
+import com.android.launcher3.util.NavigationMode;
 import com.android.launcher3.util.window.CachedDisplayInfo;
 
 import java.io.PrintWriter;
diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java
index 813e687..5a9862c 100644
--- a/quickstep/src/com/android/quickstep/RecentTasksList.java
+++ b/quickstep/src/com/android/quickstep/RecentTasksList.java
@@ -27,9 +27,9 @@
 
 import androidx.annotation.VisibleForTesting;
 
-import com.android.quickstep.util.GroupTask;
 import com.android.launcher3.util.LooperExecutor;
 import com.android.launcher3.util.SplitConfigurationOptions;
+import com.android.quickstep.util.GroupTask;
 import com.android.systemui.shared.recents.model.Task;
 import com.android.systemui.shared.system.KeyguardManagerCompat;
 import com.android.wm.shell.recents.IRecentTasksListener;
@@ -254,8 +254,12 @@
 
         TaskLoadResult allTasks = new TaskLoadResult(requestId, loadKeysOnly, rawTasks.size());
         for (GroupedRecentTaskInfo rawTask : rawTasks) {
-            ActivityManager.RecentTaskInfo taskInfo1 = rawTask.mTaskInfo1;
-            ActivityManager.RecentTaskInfo taskInfo2 = rawTask.mTaskInfo2;
+            if (rawTask.getType() == GroupedRecentTaskInfo.TYPE_FREEFORM) {
+                // TODO: add entry for freeform tasks
+                continue;
+            }
+            ActivityManager.RecentTaskInfo taskInfo1 = rawTask.getTaskInfo1();
+            ActivityManager.RecentTaskInfo taskInfo2 = rawTask.getTaskInfo2();
             Task.TaskKey task1Key = new Task.TaskKey(taskInfo1);
             Task task1 = loadKeysOnly
                     ? new Task(task1Key)
@@ -272,7 +276,7 @@
                 task2.setLastSnapshotData(taskInfo2);
             }
             final SplitConfigurationOptions.SplitBounds launcherSplitBounds =
-                    convertSplitBounds(rawTask.mSplitBounds);
+                    convertSplitBounds(rawTask.getSplitBounds());
             allTasks.add(new GroupTask(task1, task2, launcherSplitBounds));
         }
 
@@ -310,8 +314,8 @@
                 mSysUiProxy.getRecentTasks(Integer.MAX_VALUE, currentUserId);
         writer.println(prefix + "  rawTasks=[");
         for (GroupedRecentTaskInfo task : rawTasks) {
-            writer.println(prefix + "    t1=" + task.mTaskInfo1.taskId
-                    + " t2=" + (task.mTaskInfo2 != null ? task.mTaskInfo2.taskId : "-1"));
+            writer.println(prefix + "    t1=" + task.getTaskInfo1().taskId
+                    + " t2=" + (task.getTaskInfo2() != null ? task.getTaskInfo2().taskId : "-1"));
         }
         writer.println(prefix + "  ]");
     }
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationController.java b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
index fefef2f..542c0d4 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationController.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
@@ -32,6 +32,8 @@
 
 import com.android.launcher3.util.Preconditions;
 import com.android.launcher3.util.RunnableList;
+import com.android.quickstep.util.ActiveGestureErrorDetector;
+import com.android.quickstep.util.ActiveGestureLog;
 import com.android.systemui.shared.recents.model.ThumbnailData;
 import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
 import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
@@ -172,7 +174,12 @@
      */
     @UiThread
     public void cleanupScreenshot() {
-        UI_HELPER_EXECUTOR.execute(() -> mController.cleanupScreenshot());
+        UI_HELPER_EXECUTOR.execute(() -> {
+            ActiveGestureLog.INSTANCE.addLog(
+                    "cleanupScreenshot",
+                    ActiveGestureErrorDetector.GestureEvent.CLEANUP_SCREENSHOT);
+            mController.cleanupScreenshot();
+        });
     }
 
     /**
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
index b6cfbb0..e87fdad 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -23,9 +23,9 @@
 import static com.android.launcher3.util.DisplayController.CHANGE_ALL;
 import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
 import static com.android.launcher3.util.DisplayController.CHANGE_ROTATION;
-import static com.android.launcher3.util.DisplayController.NavigationMode.NO_BUTTON;
-import static com.android.launcher3.util.DisplayController.NavigationMode.THREE_BUTTONS;
-import static com.android.launcher3.util.DisplayController.NavigationMode.TWO_BUTTONS;
+import static com.android.launcher3.util.NavigationMode.NO_BUTTON;
+import static com.android.launcher3.util.NavigationMode.THREE_BUTTONS;
+import static com.android.launcher3.util.NavigationMode.TWO_BUTTONS;
 import static com.android.launcher3.util.SettingsCache.ONE_HANDED_ENABLED;
 import static com.android.launcher3.util.SettingsCache.ONE_HANDED_SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
@@ -67,7 +67,7 @@
 import com.android.launcher3.util.DisplayController;
 import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener;
 import com.android.launcher3.util.DisplayController.Info;
-import com.android.launcher3.util.DisplayController.NavigationMode;
+import com.android.launcher3.util.NavigationMode;
 import com.android.launcher3.util.SettingsCache;
 import com.android.quickstep.TopTaskTracker.CachedTaskInfo;
 import com.android.quickstep.util.NavBarPosition;
diff --git a/quickstep/src/com/android/quickstep/RotationTouchHelper.java b/quickstep/src/com/android/quickstep/RotationTouchHelper.java
index 2186a3b..f8b6966 100644
--- a/quickstep/src/com/android/quickstep/RotationTouchHelper.java
+++ b/quickstep/src/com/android/quickstep/RotationTouchHelper.java
@@ -23,8 +23,8 @@
 import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
 import static com.android.launcher3.util.DisplayController.CHANGE_ROTATION;
 import static com.android.launcher3.util.DisplayController.CHANGE_SUPPORTED_BOUNDS;
-import static com.android.launcher3.util.DisplayController.NavigationMode.THREE_BUTTONS;
 import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+import static com.android.launcher3.util.NavigationMode.THREE_BUTTONS;
 
 import android.content.Context;
 import android.content.res.Resources;
@@ -35,8 +35,8 @@
 import com.android.launcher3.util.DisplayController;
 import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener;
 import com.android.launcher3.util.DisplayController.Info;
-import com.android.launcher3.util.DisplayController.NavigationMode;
 import com.android.launcher3.util.MainThreadInitializedObject;
+import com.android.launcher3.util.NavigationMode;
 import com.android.quickstep.util.RecentsOrientedState;
 import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.shared.system.TaskStackChangeListener;
diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
index 0314761..5fb806d 100644
--- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java
+++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
@@ -36,6 +36,8 @@
 import com.android.launcher3.Utilities;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.quickstep.TopTaskTracker.CachedTaskInfo;
+import com.android.quickstep.util.ActiveGestureErrorDetector;
+import com.android.quickstep.util.ActiveGestureLog;
 import com.android.quickstep.views.RecentsView;
 import com.android.systemui.shared.recents.model.ThumbnailData;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -136,6 +138,8 @@
                     // handling this call entirely
                     return;
                 }
+                ActiveGestureLog.INSTANCE.addLog("TaskAnimationManager.startRecentsAnimation",
+                        ActiveGestureErrorDetector.GestureEvent.START_RECENTS_ANIMATION);
                 mController = controller;
                 mTargets = targets;
                 mLastAppearedTaskTarget = mTargets.findTask(mLastGestureState.getRunningTaskId());
diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java
index 93170cb..556b99e 100644
--- a/quickstep/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java
@@ -43,7 +43,6 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
 import android.annotation.TargetApi;
 import android.app.PendingIntent;
@@ -198,8 +197,7 @@
         BaseActivity baseActivity = BaseActivity.fromContext(context);
         DeviceProfile dp = baseActivity.getDeviceProfile();
         boolean showAsGrid = dp.isTablet;
-        boolean parallaxCenterAndAdjacentTask =
-                taskIndex != recentsView.getCurrentPage() && !showAsGrid;
+        boolean parallaxCenterAndAdjacentTask = taskIndex != recentsView.getCurrentPage();
         int taskRectTranslationPrimary = recentsView.getScrollOffset(taskIndex);
         int taskRectTranslationSecondary = showAsGrid ? (int) v.getGridTranslationY() : 0;
 
@@ -603,11 +601,7 @@
             if (raController != null) {
                 raController.setWillFinishToHome(false);
             }
-            Context context = v.getContext();
-            DeviceProfile dp = BaseActivity.fromContext(context).getDeviceProfile();
-            launcherAnim = dp.isTablet
-                    ? ObjectAnimator.ofFloat(recentsView, RecentsView.CONTENT_ALPHA, 0)
-                    : recentsView.createAdjacentPageAnimForTaskLaunch(taskView);
+            launcherAnim = recentsView.createAdjacentPageAnimForTaskLaunch(taskView);
             launcherAnim.setInterpolator(Interpolators.TOUCH_RESPONSE_INTERPOLATOR);
             launcherAnim.setDuration(RECENTS_LAUNCH_DURATION);
 
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 82be3ec..040c55b 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -82,6 +82,7 @@
 import com.android.launcher3.util.DisplayController;
 import com.android.launcher3.util.OnboardingPrefs;
 import com.android.launcher3.util.TraceHelper;
+import com.android.launcher3.util.ViewCapture;
 import com.android.launcher3.util.WindowBounds;
 import com.android.quickstep.inputconsumers.AccessibilityInputConsumer;
 import com.android.quickstep.inputconsumers.AssistantInputConsumer;
@@ -461,7 +462,8 @@
         mOverviewComponentObserver = new OverviewComponentObserver(this, mDeviceState);
         mOverviewCommandHelper = new OverviewCommandHelper(this,
                 mOverviewComponentObserver, mTaskAnimationManager);
-        mResetGestureInputConsumer = new ResetGestureInputConsumer(mTaskAnimationManager);
+        mResetGestureInputConsumer = new ResetGestureInputConsumer(
+                mTaskAnimationManager, mTaskbarManager::getCurrentActivityContext);
         mInputConsumer = InputConsumerController.getRecentsAnimationInputConsumer();
         mInputConsumer.registerInputConsumer();
         onSystemUiFlagsChanged(mDeviceState.getSystemUiStateFlags());
@@ -721,8 +723,10 @@
             gestureState.updateRunningTask(taskInfo);
         }
         // Log initial state for the gesture.
-        ActiveGestureLog.INSTANCE.addLog(
-                "Current SystemUi state flags= " + mDeviceState.getSystemUiStateString());
+        ActiveGestureLog.INSTANCE.addLog(new CompoundString("Current running task package name=")
+                .append(taskInfo == null ? "no running task" : taskInfo.getPackageName()));
+        ActiveGestureLog.INSTANCE.addLog(new CompoundString("Current SystemUi state flags=")
+                .append(mDeviceState.getSystemUiStateString()));
         return gestureState;
     }
 
@@ -1024,12 +1028,27 @@
                             .append("activity == null, trying to use default input consumer"));
         }
 
-        if (activity.getRootView().hasWindowFocus()
-                || previousGestureState.isRunningAnimationToLauncher()
-                || (ASSISTANT_GIVES_LAUNCHER_FOCUS.get()
-                    && forceOverviewInputConsumer)
-                || (ENABLE_QUICKSTEP_LIVE_TILE.get()
-                && gestureState.getActivityInterface().isInLiveTileMode())) {
+        boolean hasWindowFocus = activity.getRootView().hasWindowFocus();
+        boolean isPreviousGestureAnimatingToLauncher =
+                previousGestureState.isRunningAnimationToLauncher();
+        boolean forcingOverviewInputConsumer =
+                ASSISTANT_GIVES_LAUNCHER_FOCUS.get() && forceOverviewInputConsumer;
+        boolean isInLiveTileMode = ENABLE_QUICKSTEP_LIVE_TILE.get()
+                && gestureState.getActivityInterface().isInLiveTileMode();
+        reasonString.append(SUBSTRING_PREFIX)
+                .append(hasWindowFocus
+                        ? "activity has window focus"
+                        : (isPreviousGestureAnimatingToLauncher
+                                ? "previous gesture is still animating to launcher"
+                                : (forcingOverviewInputConsumer
+                                        ? "assistant gives launcher focus and forcing focus"
+                                        : (isInLiveTileMode
+                                                ? "device is in live mode"
+                                                : "all overview focus conditions failed"))));
+        if (hasWindowFocus
+                || isPreviousGestureAnimatingToLauncher
+                || forcingOverviewInputConsumer
+                || isInLiveTileMode) {
             reasonString.append(SUBSTRING_PREFIX)
                     .append("overview should have focus, using OverviewInputConsumer");
             return new OverviewInputConsumer(gestureState, activity, mInputMonitorCompat,
@@ -1196,6 +1215,8 @@
                 createdOverviewActivity.getDeviceProfile().dump(this, "", pw);
             }
             mTaskbarManager.dumpLogs("", pw);
+
+            ViewCapture.INSTANCE.get(this).dump(pw, fd);
         }
     }
 
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java b/quickstep/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java
index 3e01ed0..8a87f63 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java
@@ -22,7 +22,7 @@
 
 import com.android.launcher3.Utilities;
 import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.NavigationMode;
+import com.android.launcher3.util.NavigationMode;
 import com.android.launcher3.util.TouchController;
 import com.android.quickstep.RecentsActivity;
 import com.android.quickstep.util.NavBarPosition;
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/ProgressDelegateInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/ProgressDelegateInputConsumer.java
index 2462394..b9b5e7c 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/ProgressDelegateInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/ProgressDelegateInputConsumer.java
@@ -28,6 +28,8 @@
 import android.graphics.Point;
 import android.view.MotionEvent;
 
+import androidx.annotation.Nullable;
+
 import com.android.launcher3.anim.AnimatorListeners;
 import com.android.launcher3.testing.TestLogging;
 import com.android.launcher3.testing.shared.TestProtocol;
@@ -41,6 +43,7 @@
 import com.android.quickstep.RecentsAnimationController;
 import com.android.quickstep.RecentsAnimationTargets;
 import com.android.quickstep.TaskAnimationManager;
+import com.android.quickstep.util.ActiveGestureErrorDetector;
 import com.android.systemui.shared.recents.model.ThumbnailData;
 import com.android.systemui.shared.system.InputMonitorCompat;
 
@@ -99,7 +102,8 @@
         mDisplaySize = DisplayController.INSTANCE.get(context).getInfo().currentSize;
 
         // Init states
-        mStateCallback = new MultiStateCallback(STATE_NAMES);
+        mStateCallback = new MultiStateCallback(
+                STATE_NAMES, ProgressDelegateInputConsumer::getTrackedEventForState);
         mStateCallback.runOnceAtState(STATE_TARGET_RECEIVED | STATE_HANDLER_INVALIDATED,
                 this::endRemoteAnimation);
         mStateCallback.runOnceAtState(STATE_TARGET_RECEIVED | STATE_FLING_FINISHED,
@@ -109,6 +113,14 @@
         mSwipeDetector.setDetectableScrollConditions(DIRECTION_POSITIVE, false);
     }
 
+    @Nullable
+    private static ActiveGestureErrorDetector.GestureEvent getTrackedEventForState(int stateFlag) {
+        if (stateFlag == STATE_HANDLER_INVALIDATED) {
+            return ActiveGestureErrorDetector.GestureEvent.STATE_HANDLER_INVALIDATED;
+        }
+        return null;
+    }
+
     @Override
     public int getType() {
         return TYPE_PROGRESS_DELEGATE;
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/ResetGestureInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/ResetGestureInputConsumer.java
index d34b40b..349f4d2 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/ResetGestureInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/ResetGestureInputConsumer.java
@@ -17,18 +17,25 @@
 
 import android.view.MotionEvent;
 
+import com.android.launcher3.taskbar.TaskbarActivityContext;
 import com.android.quickstep.InputConsumer;
 import com.android.quickstep.TaskAnimationManager;
 
+import java.util.function.Supplier;
+
 /**
  * A NO_OP input consumer which also resets any pending gesture
  */
 public class ResetGestureInputConsumer implements InputConsumer {
 
     private final TaskAnimationManager mTaskAnimationManager;
+    private final Supplier<TaskbarActivityContext> mActivityContextSupplier;
 
-    public ResetGestureInputConsumer(TaskAnimationManager taskAnimationManager) {
+    public ResetGestureInputConsumer(
+            TaskAnimationManager taskAnimationManager,
+            Supplier<TaskbarActivityContext> activityContextSupplier) {
         mTaskAnimationManager = taskAnimationManager;
+        mActivityContextSupplier = activityContextSupplier;
     }
 
     @Override
@@ -40,7 +47,9 @@
     public void onMotionEvent(MotionEvent ev) {
         if (ev.getAction() == MotionEvent.ACTION_DOWN
                 && mTaskAnimationManager.isRecentsAnimationRunning()) {
-            mTaskAnimationManager.finishRunningRecentsAnimation(false /* toHome */);
+            TaskbarActivityContext tac = mActivityContextSupplier.get();
+            mTaskAnimationManager.finishRunningRecentsAnimation(
+                    /* toHome= */ tac != null && !tac.isInApp());
         }
     }
 }
diff --git a/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java b/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java
index 4badf30..e7bf7e2 100644
--- a/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java
+++ b/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java
@@ -44,10 +44,10 @@
 import androidx.annotation.Nullable;
 
 import com.android.launcher3.R;
-import com.android.launcher3.testing.shared.ResourceUtils;
 import com.android.launcher3.anim.Interpolators;
+import com.android.launcher3.testing.shared.ResourceUtils;
 import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.NavigationMode;
+import com.android.launcher3.util.NavigationMode;
 import com.android.quickstep.util.MotionPauseDetector;
 import com.android.quickstep.util.NavBarPosition;
 import com.android.quickstep.util.TriggerSwipeUpTouchTracker;
diff --git a/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java b/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java
index 99553e8..2ccdfa3 100644
--- a/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java
+++ b/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java
@@ -46,8 +46,8 @@
 import com.android.launcher3.model.DeviceGridState;
 import com.android.launcher3.util.DisplayController;
 import com.android.launcher3.util.DisplayController.Info;
-import com.android.launcher3.util.DisplayController.NavigationMode;
 import com.android.launcher3.util.MainThreadInitializedObject;
+import com.android.launcher3.util.NavigationMode;
 import com.android.launcher3.util.SettingsCache;
 
 import org.xmlpull.v1.XmlPullParser;
diff --git a/quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java b/quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java
index 78075de..693ef10 100644
--- a/quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java
+++ b/quickstep/src/com/android/quickstep/util/ActiveGestureErrorDetector.java
@@ -29,11 +29,36 @@
  */
 public class ActiveGestureErrorDetector {
 
+    /**
+     * Enums associated to gesture navigation events.
+     */
     public enum GestureEvent {
         MOTION_DOWN, MOTION_UP, SET_END_TARGET, ON_SETTLED_ON_END_TARGET, START_RECENTS_ANIMATION,
-        FINISH_RECENTS_ANIMATION, CANCEL_RECENTS_ANIMATION, STATE_GESTURE_STARTED,
-        STATE_GESTURE_COMPLETED, STATE_GESTURE_CANCELLED, STATE_END_TARGET_ANIMATION_FINISHED,
-        STATE_RECENTS_SCROLLING_FINISHED
+        FINISH_RECENTS_ANIMATION, CANCEL_RECENTS_ANIMATION, SET_ON_PAGE_TRANSITION_END_CALLBACK,
+        CANCEL_CURRENT_ANIMATION, CLEANUP_SCREENSHOT,
+
+        /**
+         * These GestureEvents are specifically associated to state flags that get set in
+         * {@link com.android.quickstep.MultiStateCallback}. If a state flag needs to be tracked
+         * for error detection, an enum should be added here and that state flag-enum pair should
+         * be added to the state flag's container class' {@code getTrackedEventForState} method.
+         */
+        STATE_GESTURE_STARTED, STATE_GESTURE_COMPLETED, STATE_GESTURE_CANCELLED,
+        STATE_END_TARGET_ANIMATION_FINISHED, STATE_RECENTS_SCROLLING_FINISHED,
+        STATE_CAPTURE_SCREENSHOT, STATE_SCREENSHOT_CAPTURED, STATE_HANDLER_INVALIDATED,
+        STATE_RECENTS_ANIMATION_CANCELED, STATE_LAUNCHER_DRAWN(true, false);
+
+        public final boolean mLogEvent;
+        public final boolean mTrackEvent;
+
+        GestureEvent() {
+            this(false, true);
+        }
+
+        GestureEvent(boolean logEvent, boolean trackEvent) {
+            mLogEvent = logEvent;
+            mTrackEvent = trackEvent;
+        }
     }
 
     private ActiveGestureErrorDetector() {}
@@ -90,6 +115,14 @@
                                         + "before/without startRecentsAnimation.",
                                 writer);
                         break;
+                    case CLEANUP_SCREENSHOT:
+                        errorDetected |= printErrorIfTrue(
+                                !encounteredEvents.contains(GestureEvent.STATE_SCREENSHOT_CAPTURED),
+                                /* errorMessage= */ prefix + "\t\trecents activity screenshot was "
+                                        + "cleaned up before/without STATE_SCREENSHOT_CAPTURED "
+                                        + "being set.",
+                                writer);
+                        break;
                     case STATE_GESTURE_COMPLETED:
                         errorDetected |= printErrorIfTrue(
                                 !encounteredEvents.contains(GestureEvent.MOTION_UP),
@@ -114,12 +147,40 @@
                                         + "before/without STATE_GESTURE_STARTED.",
                                 writer);
                         break;
+                    case STATE_SCREENSHOT_CAPTURED:
+                        errorDetected |= printErrorIfTrue(
+                                !encounteredEvents.contains(GestureEvent.STATE_CAPTURE_SCREENSHOT),
+                                /* errorMessage= */ prefix + "\t\tSTATE_SCREENSHOT_CAPTURED set "
+                                        + "before/without STATE_CAPTURE_SCREENSHOT.",
+                                writer);
+                        break;
+                    case STATE_RECENTS_SCROLLING_FINISHED:
+                        errorDetected |= printErrorIfTrue(
+                                !encounteredEvents.contains(
+                                        GestureEvent.SET_ON_PAGE_TRANSITION_END_CALLBACK),
+                                /* errorMessage= */ prefix + "\t\tSTATE_RECENTS_SCROLLING_FINISHED "
+                                        + "set before/without calling "
+                                        + "setOnPageTransitionEndCallback.",
+                                writer);
+                        break;
+                    case STATE_RECENTS_ANIMATION_CANCELED:
+                        errorDetected |= printErrorIfTrue(
+                                !encounteredEvents.contains(
+                                        GestureEvent.START_RECENTS_ANIMATION),
+                                /* errorMessage= */ prefix + "\t\tSTATE_RECENTS_ANIMATION_CANCELED "
+                                        + "set before/without startRecentsAnimation.",
+                                writer);
+                        break;
                     case MOTION_DOWN:
                     case SET_END_TARGET:
                     case START_RECENTS_ANIMATION:
+                    case SET_ON_PAGE_TRANSITION_END_CALLBACK:
+                    case CANCEL_CURRENT_ANIMATION:
                     case STATE_GESTURE_STARTED:
                     case STATE_END_TARGET_ANIMATION_FINISHED:
-                    case STATE_RECENTS_SCROLLING_FINISHED:
+                    case STATE_CAPTURE_SCREENSHOT:
+                    case STATE_HANDLER_INVALIDATED:
+                    case STATE_LAUNCHER_DRAWN:
                     default:
                         // No-Op
                 }
@@ -183,6 +244,39 @@
                             + "STATE_GESTURE_COMPLETED and STATE_GESTURE_CANCELLED weren't.",
                     writer);
 
+            errorDetected |= printErrorIfTrue(
+                    /* condition= */ encounteredEvents.contains(
+                            GestureEvent.STATE_CAPTURE_SCREENSHOT)
+                            && !encounteredEvents.contains(GestureEvent.STATE_SCREENSHOT_CAPTURED),
+                    /* errorMessage= */ prefix + "\t\tSTATE_CAPTURE_SCREENSHOT was set, but "
+                            + "STATE_SCREENSHOT_CAPTURED wasn't.",
+                    writer);
+
+            errorDetected |= printErrorIfTrue(
+                    /* condition= */ encounteredEvents.contains(
+                            GestureEvent.SET_ON_PAGE_TRANSITION_END_CALLBACK)
+                            && !encounteredEvents.contains(
+                                    GestureEvent.STATE_RECENTS_SCROLLING_FINISHED),
+                    /* errorMessage= */ prefix + "\t\tsetOnPageTransitionEndCallback called, but "
+                            + "STATE_RECENTS_SCROLLING_FINISHED wasn't set.",
+                    writer);
+
+            errorDetected |= printErrorIfTrue(
+                    /* condition= */ !encounteredEvents.contains(
+                            GestureEvent.CANCEL_CURRENT_ANIMATION)
+                            && !encounteredEvents.contains(GestureEvent.STATE_HANDLER_INVALIDATED),
+                    /* errorMessage= */ prefix + "\t\tAbsSwipeUpHandler.cancelCurrentAnimation "
+                            + "wasn't called and STATE_HANDLER_INVALIDATED wasn't set.",
+                    writer);
+
+            errorDetected |= printErrorIfTrue(
+                    /* condition= */ encounteredEvents.contains(
+                            GestureEvent.STATE_RECENTS_ANIMATION_CANCELED)
+                            && !encounteredEvents.contains(GestureEvent.CLEANUP_SCREENSHOT),
+                    /* errorMessage= */ prefix + "\t\tSTATE_RECENTS_ANIMATION_CANCELED was set but "
+                            + "the task screenshot wasn't cleaned up.",
+                    writer);
+
             if (!errorDetected) {
                 writer.println(prefix + "\t\tNo errors detected.");
             }
diff --git a/quickstep/src/com/android/quickstep/util/ActiveGestureLog.java b/quickstep/src/com/android/quickstep/util/ActiveGestureLog.java
index 9f08010..40eb31b 100644
--- a/quickstep/src/com/android/quickstep/util/ActiveGestureLog.java
+++ b/quickstep/src/com/android/quickstep/util/ActiveGestureLog.java
@@ -138,14 +138,10 @@
         List<EventEntry> lastEventEntries = lastEventLog.eventEntries;
         EventEntry lastEntry = lastEventEntries.size() > 0
                 ? lastEventEntries.get(lastEventEntries.size() - 1) : null;
-        EventEntry secondLastEntry = lastEventEntries.size() > 1
-                ? lastEventEntries.get(lastEventEntries.size() - 2) : null;
 
         // Update the last EventEntry if it's a duplicate
-        if (isEntrySame(lastEntry, type, event, compoundString, gestureEvent)
-                && isEntrySame(secondLastEntry, type, event, compoundString, gestureEvent)) {
-            lastEntry.update(type, event, extras, compoundString, gestureEvent);
-            secondLastEntry.duplicateCount++;
+        if (isEntrySame(lastEntry, type, event, extras, compoundString, gestureEvent)) {
+            lastEntry.duplicateCount++;
             return;
         }
         EventEntry eventEntry = new EventEntry();
@@ -223,11 +219,13 @@
             EventEntry entry,
             int type,
             String event,
+            float extras,
             CompoundString compoundString,
             ActiveGestureErrorDetector.GestureEvent gestureEvent) {
         return entry != null
                 && entry.type == type
                 && entry.event.equals(event)
+                && Float.compare(entry.extras, extras) == 0
                 && entry.mCompoundString.equals(compoundString)
                 && entry.gestureEvent == gestureEvent;
     }
@@ -342,7 +340,7 @@
                 return false;
             }
             CompoundString other = (CompoundString) obj;
-            return mIsNoOp && other.mIsNoOp && Objects.equals(mSubstrings, other.mSubstrings);
+            return (mIsNoOp == other.mIsNoOp) && Objects.equals(mSubstrings, other.mSubstrings);
         }
     }
 }
diff --git a/quickstep/src/com/android/quickstep/util/LayoutUtils.java b/quickstep/src/com/android/quickstep/util/LayoutUtils.java
index d0856be..f7136a5 100644
--- a/quickstep/src/com/android/quickstep/util/LayoutUtils.java
+++ b/quickstep/src/com/android/quickstep/util/LayoutUtils.java
@@ -23,7 +23,7 @@
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.touch.PagedOrientationHandler;
 import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.NavigationMode;
+import com.android.launcher3.util.NavigationMode;
 import com.android.quickstep.LauncherActivityInterface;
 
 public class LayoutUtils {
diff --git a/quickstep/src/com/android/quickstep/util/NavBarPosition.java b/quickstep/src/com/android/quickstep/util/NavBarPosition.java
index 527a6d2..59c8263 100644
--- a/quickstep/src/com/android/quickstep/util/NavBarPosition.java
+++ b/quickstep/src/com/android/quickstep/util/NavBarPosition.java
@@ -15,12 +15,12 @@
  */
 package com.android.quickstep.util;
 
-import static com.android.launcher3.util.DisplayController.NavigationMode.NO_BUTTON;
+import static com.android.launcher3.util.NavigationMode.NO_BUTTON;
 
 import android.view.Surface;
 
 import com.android.launcher3.util.DisplayController.Info;
-import com.android.launcher3.util.DisplayController.NavigationMode;
+import com.android.launcher3.util.NavigationMode;
 
 /**
  * Utility class to check nav bar position.
diff --git a/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java b/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
index fc44b99..e928b27 100644
--- a/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
+++ b/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
@@ -21,7 +21,7 @@
 import static com.android.launcher3.LauncherState.HINT_STATE;
 import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.LauncherState.OVERVIEW;
-import static com.android.launcher3.util.DisplayController.NavigationMode.NO_BUTTON;
+import static com.android.launcher3.util.NavigationMode.NO_BUTTON;
 
 import android.content.SharedPreferences;
 
diff --git a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
index 62ec0ef..08a17c4 100644
--- a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
+++ b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
@@ -32,9 +32,9 @@
 import com.android.launcher3.Insettable;
 import com.android.launcher3.R;
 import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.NavigationMode;
 import com.android.launcher3.util.MultiValueAlpha;
 import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
+import com.android.launcher3.util.NavigationMode;
 import com.android.quickstep.TaskOverlayFactory.OverlayUICallbacks;
 import com.android.quickstep.util.LayoutUtils;
 
@@ -53,7 +53,9 @@
             HIDDEN_NON_ZERO_ROTATION,
             HIDDEN_NO_TASKS,
             HIDDEN_NO_RECENTS,
-            HIDDEN_SPLIT_SCREEN})
+            HIDDEN_SPLIT_SCREEN,
+            HIDDEN_SPLIT_SELECT_ACTIVE
+    })
     @Retention(RetentionPolicy.SOURCE)
     public @interface ActionsHiddenFlags { }
 
@@ -61,6 +63,7 @@
     public static final int HIDDEN_NO_TASKS = 1 << 1;
     public static final int HIDDEN_NO_RECENTS = 1 << 2;
     public static final int HIDDEN_SPLIT_SCREEN = 1 << 3;
+    public static final int HIDDEN_SPLIT_SELECT_ACTIVE = 1 << 4;
 
     @IntDef(flag = true, value = {
             DISABLED_SCROLLING,
@@ -79,6 +82,11 @@
     private static final int INDEX_HIDDEN_FLAGS_ALPHA = 3;
     private static final int INDEX_SHARE_TARGET_ALPHA = 4;
 
+    public @interface SplitButtonDisabledFlags { }
+
+    public static final int FLAG_IS_NOT_TABLET = 1 << 0;
+    public static final int FLAG_SINGLE_TASK = 1 << 1;
+
     private MultiValueAlpha mMultiValueAlpha;
     private Button mSplitButton;
 
@@ -88,6 +96,9 @@
     @ActionsDisabledFlags
     protected int mDisabledFlags;
 
+    @SplitButtonDisabledFlags
+    private int mSplitButtonDisabledFlags;
+
     @Nullable
     protected T mCallbacks;
 
@@ -182,6 +193,20 @@
         LayoutUtils.setViewEnabled(this, isEnabled);
     }
 
+    /**
+     * Updates the proper flags to indicate whether the "Split screen" button should be enabled.
+     *
+     * @param flag          The flag to update.
+     * @param enable        Whether to enable the disable flag: True will cause view to be disabled.
+     */
+    public void updateSplitButtonFlags(@SplitButtonDisabledFlags int flag, boolean enable) {
+        if (enable) {
+            mSplitButtonDisabledFlags |= flag;
+        } else {
+            mSplitButtonDisabledFlags &= ~flag;
+        }
+    }
+
     public AlphaProperty getContentAlpha() {
         return mMultiValueAlpha.getProperty(INDEX_CONTENT_ALPHA);
     }
@@ -263,12 +288,17 @@
                 0, 0, 0);
     }
 
-    public void setSplitButtonVisible(boolean visible) {
+    /**
+     * Shows/hides the "Split" button based on the status of mHiddenFlags.
+     */
+    public void updateSplitButtonVisibility() {
         if (mSplitButton == null) {
             return;
         }
-
-        mSplitButton.setVisibility(visible ? VISIBLE : GONE);
-        findViewById(R.id.action_split_space).setVisibility(visible ? VISIBLE : GONE);
+        boolean shouldBeVisible = mSplitButtonDisabledFlags == 0
+                // and neither of these flags are active
+                && (mHiddenFlags & (HIDDEN_SPLIT_SCREEN | HIDDEN_SPLIT_SELECT_ACTIVE)) == 0;
+        mSplitButton.setVisibility(shouldBeVisible ? VISIBLE : GONE);
+        findViewById(R.id.action_split_space).setVisibility(shouldBeVisible ? VISIBLE : GONE);
     }
 }
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index efaa644..f8bf3d8 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -52,10 +52,13 @@
 import static com.android.launcher3.util.SystemUiController.UI_STATE_FULLSCREEN_TASK;
 import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId;
 import static com.android.quickstep.views.ClearAllButton.DISMISS_ALPHA;
+import static com.android.quickstep.views.OverviewActionsView.FLAG_IS_NOT_TABLET;
+import static com.android.quickstep.views.OverviewActionsView.FLAG_SINGLE_TASK;
 import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NON_ZERO_ROTATION;
 import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_RECENTS;
 import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_TASKS;
 import static com.android.quickstep.views.OverviewActionsView.HIDDEN_SPLIT_SCREEN;
+import static com.android.quickstep.views.OverviewActionsView.HIDDEN_SPLIT_SELECT_ACTIVE;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -3387,11 +3390,11 @@
     private void updateCurrentTaskActionsVisibility() {
         boolean isCurrentSplit = getCurrentPageTaskView() instanceof GroupedTaskView;
         mActionsView.updateHiddenFlags(HIDDEN_SPLIT_SCREEN, isCurrentSplit);
-        if (isCurrentSplit) {
-            return;
-        }
-        mActionsView.setSplitButtonVisible(
-                mActivity.getDeviceProfile().isTablet && getTaskViewCount() > 1);
+        mActionsView.updateHiddenFlags(HIDDEN_SPLIT_SELECT_ACTIVE, isSplitSelectionActive());
+        mActionsView.updateSplitButtonFlags(FLAG_IS_NOT_TABLET,
+                !mActivity.getDeviceProfile().isTablet);
+        mActionsView.updateSplitButtonFlags(FLAG_SINGLE_TASK, getTaskViewCount() <= 1);
+        mActionsView.updateSplitButtonVisibility();
     }
 
     /**
@@ -4317,25 +4320,27 @@
 
         int taskIndex = indexOfChild(tv);
         int centerTaskIndex = getCurrentPage();
-        boolean launchingCenterTask = taskIndex == centerTaskIndex;
 
         float toScale = getMaxScaleForFullScreen();
-        RecentsView recentsView = tv.getRecentsView();
+        boolean showAsGrid = showAsGrid();
+        boolean launchingCenterTask = showAsGrid
+                ? tv.isFocusedTask() && isTaskViewFullyVisible(tv)
+                : taskIndex == centerTaskIndex;
         if (launchingCenterTask) {
-            anim.play(ObjectAnimator.ofFloat(recentsView, RECENTS_SCALE_PROPERTY, toScale));
-            anim.play(ObjectAnimator.ofFloat(recentsView, FULLSCREEN_PROGRESS, 1));
-        } else {
+            anim.play(ObjectAnimator.ofFloat(this, RECENTS_SCALE_PROPERTY, toScale));
+            anim.play(ObjectAnimator.ofFloat(this, FULLSCREEN_PROGRESS, 1));
+        } else if (!showAsGrid) {
             // We are launching an adjacent task, so parallax the center and other adjacent task.
             float displacementX = tv.getWidth() * (toScale - 1f);
             float primaryTranslation = mIsRtl ? -displacementX : displacementX;
             anim.play(ObjectAnimator.ofFloat(getPageAt(centerTaskIndex),
                     mOrientationHandler.getPrimaryViewTranslate(), primaryTranslation));
-            int runningTaskIndex = recentsView.getRunningTaskIndex();
+            int runningTaskIndex = getRunningTaskIndex();
             if (ENABLE_QUICKSTEP_LIVE_TILE.get()
                     && runningTaskIndex != -1
                     && runningTaskIndex != taskIndex
-                    && recentsView.getRemoteTargetHandles() != null) {
-                for (RemoteTargetHandle remoteHandle : recentsView.getRemoteTargetHandles()) {
+                    && getRemoteTargetHandles() != null) {
+                for (RemoteTargetHandle remoteHandle : getRemoteTargetHandles()) {
                     anim.play(ObjectAnimator.ofFloat(
                             remoteHandle.getTaskViewSimulator().taskPrimaryTranslation,
                             AnimatedFloat.VALUE,
@@ -4355,7 +4360,7 @@
                         properties));
             }
         }
-        anim.play(ObjectAnimator.ofFloat(recentsView, TASK_THUMBNAIL_SPLASH_ALPHA, 0, 1));
+        anim.play(ObjectAnimator.ofFloat(this, TASK_THUMBNAIL_SPLASH_ALPHA, 0, 1));
         return anim;
     }
 
diff --git a/quickstep/src/com/android/quickstep/views/SplitInstructionsView.java b/quickstep/src/com/android/quickstep/views/SplitInstructionsView.java
index 7d94505..bcaa462 100644
--- a/quickstep/src/com/android/quickstep/views/SplitInstructionsView.java
+++ b/quickstep/src/com/android/quickstep/views/SplitInstructionsView.java
@@ -16,7 +16,7 @@
 
 package com.android.quickstep.views;
 
-import static com.android.launcher3.util.DisplayController.NavigationMode.THREE_BUTTONS;
+import static com.android.launcher3.util.NavigationMode.THREE_BUTTONS;
 
 import android.content.Context;
 import android.util.AttributeSet;
diff --git a/quickstep/tests/src/com/android/quickstep/DeviceProfileTest.kt b/quickstep/tests/src/com/android/quickstep/DeviceProfileTest.kt
deleted file mode 100644
index 9977207..0000000
--- a/quickstep/tests/src/com/android/quickstep/DeviceProfileTest.kt
+++ /dev/null
@@ -1,1479 +0,0 @@
-/*
- * 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.quickstep
-
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.android.launcher3.DeviceProfileBaseTest
-import com.google.common.truth.Truth.assertThat
-import org.junit.Test
-import org.junit.runner.RunWith
-
-/**
- * Tests for DeviceProfile.
- */
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-class DeviceProfileTest : DeviceProfileBaseTest() {
-
-    @Test
-    fun phonePortrait3Button() {
-        initializeVarsForPhone(isGestureMode = false)
-        val dp = newDP()
-
-        assertThat(dump(dp)).isEqualTo("DeviceProfile:\n" +
-                "\t1 dp = 2.625 px\n" +
-                "\tisTablet:false\n" +
-                "\tisPhone:true\n" +
-                "\ttransposeLayoutWithOrientation:true\n" +
-                "\tisGestureMode:false\n" +
-                "\tisLandscape:false\n" +
-                "\tisMultiWindowMode:false\n" +
-                "\tisTwoPanels:false\n" +
-                "\twindowX: 0.0px (0.0dp)\n" +
-                "\twindowY: 0.0px (0.0dp)\n" +
-                "\twidthPx: 1080.0px (411.42856dp)\n" +
-                "\theightPx: 2400.0px (914.2857dp)\n" +
-                "\tavailableWidthPx: 1080.0px (411.42856dp)\n" +
-                "\tavailableHeightPx: 2156.0px (821.3333dp)\n" +
-                "\tmInsets.left: 0.0px (0.0dp)\n" +
-                "\tmInsets.top: 118.0px (44.95238dp)\n" +
-                "\tmInsets.right: 0.0px (0.0dp)\n" +
-                "\tmInsets.bottom: 126.0px (48.0dp)\n" +
-                "\taspectRatio:2.2222223\n" +
-                "\tisScalableGrid:true\n" +
-                "\tinv.numRows: 5\n" +
-                "\tinv.numColumns: 4\n" +
-                "\tinv.numSearchContainerColumns: 4\n" +
-                "\tminCellSize: PointF(80.0, 104.0)dp\n" +
-                "\tcellWidthPx: 210.0px (80.0dp)\n" +
-                "\tcellHeightPx: 272.0px (103.61905dp)\n" +
-                "\tgetCellSize().x: 210.0px (80.0dp)\n" +
-                "\tgetCellSize().y: 272.0px (103.61905dp)\n" +
-                "\tcellLayoutBorderSpacePx Horizontal: 42.0px (16.0dp)\n" +
-                "\tcellLayoutBorderSpacePx Vertical: 42.0px (16.0dp)\n" +
-                "\tcellLayoutPaddingPx.left: 28.0px (10.666667dp)\n" +
-                "\tcellLayoutPaddingPx.top: 28.0px (10.666667dp)\n" +
-                "\tcellLayoutPaddingPx.right: 28.0px (10.666667dp)\n" +
-                "\tcellLayoutPaddingPx.bottom: 28.0px (10.666667dp)\n" +
-                "\ticonSizePx: 157.0px (59.809525dp)\n" +
-                "\ticonTextSizePx: 36.0px (13.714286dp)\n" +
-                "\ticonDrawablePaddingPx: 17.0px (6.4761906dp)\n" +
-                "\tfolderCellWidthPx: 210.0px (80.0dp)\n" +
-                "\tfolderCellHeightPx: 247.0px (94.09524dp)\n" +
-                "\tfolderChildIconSizePx: 158.0px (60.190475dp)\n" +
-                "\tfolderChildTextSizePx: 37.0px (14.095238dp)\n" +
-                "\tfolderChildDrawablePaddingPx: 13.0px (4.952381dp)\n" +
-                "\tfolderCellLayoutBorderSpacePx Horizontal: 42.0px (16.0dp)\n" +
-                "\tfolderCellLayoutBorderSpacePx Vertical: 42.0px (16.0dp)\n" +
-                "\tfolderContentPaddingLeftRight: 42.0px (16.0dp)\n" +
-                "\tfolderTopPadding: 63.0px (24.0dp)\n" +
-                "\tbottomSheetTopPadding: 146.0px (55.61905dp)\n" +
-                "\tallAppsShiftRange: 788.0px (300.1905dp)\n" +
-                "\tallAppsTopPadding: 0.0px (0.0dp)\n" +
-                "\tallAppsIconSizePx: 157.0px (59.809525dp)\n" +
-                "\tallAppsIconTextSizePx: 37.0px (14.095238dp)\n" +
-                "\tallAppsIconDrawablePaddingPx: 18.0px (6.857143dp)\n" +
-                "\tallAppsCellHeightPx: 314.0px (119.61905dp)\n" +
-                "\tallAppsCellWidthPx: 210.0px (80.0dp)\n" +
-                "\tallAppsBorderSpacePxX: 42.0px (16.0dp)\n" +
-                "\tallAppsBorderSpacePxY: 42.0px (16.0dp)\n" +
-                "\tnumShownAllAppsColumns: 4\n" +
-                "\tallAppsLeftRightPadding: 57.0px (21.714285dp)\n" +
-                "\tallAppsLeftRightMargin: 0.0px (0.0dp)\n" +
-                "\thotseatBarSizePx: 511.0px (194.66667dp)\n" +
-                "\tinv.hotseatColumnSpan: 4\n" +
-                "\thotseatCellHeightPx: 177.0px (67.42857dp)\n" +
-                "\thotseatBarBottomSpacePx: 147.0px (56.0dp)\n" +
-                "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
-                "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
-                "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
-                "\thotseatQsbSpace: 74.0px (28.190475dp)\n" +
-                "\thotseatQsbHeight: 165.0px (62.857143dp)\n" +
-                "\tspringLoadedHotseatBarTopMarginPx: 200.0px (76.190475dp)\n" +
-                "\tgetHotseatLayoutPadding(context).top: 0.0px (0.0dp)\n" +
-                "\tgetHotseatLayoutPadding(context).bottom: 334.0px (127.2381dp)\n" +
-                "\tgetHotseatLayoutPadding(context).left: 83.0px (31.619047dp)\n" +
-                "\tgetHotseatLayoutPadding(context).right: 83.0px (31.619047dp)\n" +
-                "\tnumShownHotseatIcons: 4\n" +
-                "\thotseatBorderSpace: 95.0px (36.190475dp)\n" +
-                "\tisQsbInline: false\n" +
-                "\thotseatQsbWidth: 913.0px (347.8095dp)\n" +
-                "\tisTaskbarPresent:false\n" +
-                "\tisTaskbarPresentInApps:false\n" +
-                "\ttaskbarSize: 0.0px (0.0dp)\n" +
-                "\tdesiredWorkspaceHorizontalMarginPx: 57.0px (21.714285dp)\n" +
-                "\tworkspacePadding.left: 29.0px (11.047619dp)\n" +
-                "\tworkspacePadding.top: 67.0px (25.52381dp)\n" +
-                "\tworkspacePadding.right: 29.0px (11.047619dp)\n" +
-                "\tworkspacePadding.bottom: 504.0px (192.0dp)\n" +
-                "\ticonScale: 0.9981516px (0.38024822dp)\n" +
-                "\tcellScaleToFit : 0.9981516px (0.38024822dp)\n" +
-                "\textraSpace: 211.0px (80.38095dp)\n" +
-                "\tunscaled extraSpace: 211.39073px (80.5298dp)\n" +
-                "\tmaxEmptySpace: 315.0px (120.0dp)\n" +
-                "\tworkspaceTopPadding: 95.0px (36.190475dp)\n" +
-                "\tworkspaceBottomPadding: 116.0px (44.190475dp)\n" +
-                "\toverviewTaskMarginPx: 42.0px (16.0dp)\n" +
-                "\toverviewTaskIconSizePx: 126.0px (48.0dp)\n" +
-                "\toverviewTaskIconDrawableSizePx: 116.0px (44.190475dp)\n" +
-                "\toverviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)\n" +
-                "\toverviewTaskThumbnailTopMarginPx: 168.0px (64.0dp)\n" +
-                "\toverviewActionsTopMarginPx: 63.0px (24.0dp)\n" +
-                "\toverviewActionsHeight: 126.0px (48.0dp)\n" +
-                "\toverviewActionsButtonSpacing: 95.0px (36.190475dp)\n" +
-                "\toverviewPageSpacing: 42.0px (16.0dp)\n" +
-                "\toverviewRowSpacing: 0.0px (0.0dp)\n" +
-                "\toverviewGridSideMargin: 0.0px (0.0dp)\n" +
-                "\tdropTargetBarTopMarginPx: 84.0px (32.0dp)\n" +
-                "\tdropTargetBarSizePx: 147.0px (56.0dp)\n" +
-                "\tdropTargetBarBottomMarginPx: 42.0px (16.0dp)\n" +
-                "\tgetCellLayoutSpringLoadShrunkTop(): 391.0px (148.95238dp)\n" +
-                "\tgetCellLayoutSpringLoadShrunkBottom(): 1689.0px (643.4286dp)\n" +
-                "\tworkspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)\n" +
-                "\tgetWorkspaceSpringLoadScale(): 0.81892747px (0.31197238dp)\n" +
-                "\tgetCellLayoutHeight(): 1585.0px (603.8095dp)\n" +
-                "\tgetCellLayoutWidth(): 1022.0px (389.33334dp)\n")
-    }
-
-    @Test
-    fun phonePortrait() {
-        initializeVarsForPhone()
-        val dp = newDP()
-
-        assertThat(dump(dp)).isEqualTo("DeviceProfile:\n" +
-                "\t1 dp = 2.625 px\n" +
-                "\tisTablet:false\n" +
-                "\tisPhone:true\n" +
-                "\ttransposeLayoutWithOrientation:true\n" +
-                "\tisGestureMode:true\n" +
-                "\tisLandscape:false\n" +
-                "\tisMultiWindowMode:false\n" +
-                "\tisTwoPanels:false\n" +
-                "\twindowX: 0.0px (0.0dp)\n" +
-                "\twindowY: 0.0px (0.0dp)\n" +
-                "\twidthPx: 1080.0px (411.42856dp)\n" +
-                "\theightPx: 2400.0px (914.2857dp)\n" +
-                "\tavailableWidthPx: 1080.0px (411.42856dp)\n" +
-                "\tavailableHeightPx: 2219.0px (845.3333dp)\n" +
-                "\tmInsets.left: 0.0px (0.0dp)\n" +
-                "\tmInsets.top: 118.0px (44.95238dp)\n" +
-                "\tmInsets.right: 0.0px (0.0dp)\n" +
-                "\tmInsets.bottom: 63.0px (24.0dp)\n" +
-                "\taspectRatio:2.2222223\n" +
-                "\tisScalableGrid:true\n" +
-                "\tinv.numRows: 5\n" +
-                "\tinv.numColumns: 4\n" +
-                "\tinv.numSearchContainerColumns: 4\n" +
-                "\tminCellSize: PointF(80.0, 104.0)dp\n" +
-                "\tcellWidthPx: 210.0px (80.0dp)\n" +
-                "\tcellHeightPx: 272.0px (103.61905dp)\n" +
-                "\tgetCellSize().x: 210.0px (80.0dp)\n" +
-                "\tgetCellSize().y: 272.0px (103.61905dp)\n" +
-                "\tcellLayoutBorderSpacePx Horizontal: 42.0px (16.0dp)\n" +
-                "\tcellLayoutBorderSpacePx Vertical: 42.0px (16.0dp)\n" +
-                "\tcellLayoutPaddingPx.left: 28.0px (10.666667dp)\n" +
-                "\tcellLayoutPaddingPx.top: 28.0px (10.666667dp)\n" +
-                "\tcellLayoutPaddingPx.right: 28.0px (10.666667dp)\n" +
-                "\tcellLayoutPaddingPx.bottom: 28.0px (10.666667dp)\n" +
-                "\ticonSizePx: 157.0px (59.809525dp)\n" +
-                "\ticonTextSizePx: 36.0px (13.714286dp)\n" +
-                "\ticonDrawablePaddingPx: 17.0px (6.4761906dp)\n" +
-                "\tfolderCellWidthPx: 210.0px (80.0dp)\n" +
-                "\tfolderCellHeightPx: 247.0px (94.09524dp)\n" +
-                "\tfolderChildIconSizePx: 158.0px (60.190475dp)\n" +
-                "\tfolderChildTextSizePx: 37.0px (14.095238dp)\n" +
-                "\tfolderChildDrawablePaddingPx: 13.0px (4.952381dp)\n" +
-                "\tfolderCellLayoutBorderSpacePx Horizontal: 42.0px (16.0dp)\n" +
-                "\tfolderCellLayoutBorderSpacePx Vertical: 42.0px (16.0dp)\n" +
-                "\tfolderContentPaddingLeftRight: 42.0px (16.0dp)\n" +
-                "\tfolderTopPadding: 63.0px (24.0dp)\n" +
-                "\tbottomSheetTopPadding: 146.0px (55.61905dp)\n" +
-                "\tallAppsShiftRange: 788.0px (300.1905dp)\n" +
-                "\tallAppsTopPadding: 0.0px (0.0dp)\n" +
-                "\tallAppsIconSizePx: 157.0px (59.809525dp)\n" +
-                "\tallAppsIconTextSizePx: 37.0px (14.095238dp)\n" +
-                "\tallAppsIconDrawablePaddingPx: 18.0px (6.857143dp)\n" +
-                "\tallAppsCellHeightPx: 314.0px (119.61905dp)\n" +
-                "\tallAppsCellWidthPx: 210.0px (80.0dp)\n" +
-                "\tallAppsBorderSpacePxX: 42.0px (16.0dp)\n" +
-                "\tallAppsBorderSpacePxY: 42.0px (16.0dp)\n" +
-                "\tnumShownAllAppsColumns: 4\n" +
-                "\tallAppsLeftRightPadding: 57.0px (21.714285dp)\n" +
-                "\tallAppsLeftRightMargin: 0.0px (0.0dp)\n" +
-                "\thotseatBarSizePx: 511.0px (194.66667dp)\n" +
-                "\tinv.hotseatColumnSpan: 4\n" +
-                "\thotseatCellHeightPx: 177.0px (67.42857dp)\n" +
-                "\thotseatBarBottomSpacePx: 126.0px (48.0dp)\n" +
-                "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
-                "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
-                "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
-                "\thotseatQsbSpace: 95.0px (36.190475dp)\n" +
-                "\thotseatQsbHeight: 165.0px (62.857143dp)\n" +
-                "\tspringLoadedHotseatBarTopMarginPx: 200.0px (76.190475dp)\n" +
-                "\tgetHotseatLayoutPadding(context).top: 0.0px (0.0dp)\n" +
-                "\tgetHotseatLayoutPadding(context).bottom: 334.0px (127.2381dp)\n" +
-                "\tgetHotseatLayoutPadding(context).left: 83.0px (31.619047dp)\n" +
-                "\tgetHotseatLayoutPadding(context).right: 83.0px (31.619047dp)\n" +
-                "\tnumShownHotseatIcons: 4\n" +
-                "\thotseatBorderSpace: 95.0px (36.190475dp)\n" +
-                "\tisQsbInline: false\n" +
-                "\thotseatQsbWidth: 913.0px (347.8095dp)\n" +
-                "\tisTaskbarPresent:false\n" +
-                "\tisTaskbarPresentInApps:false\n" +
-                "\ttaskbarSize: 0.0px (0.0dp)\n" +
-                "\tdesiredWorkspaceHorizontalMarginPx: 57.0px (21.714285dp)\n" +
-                "\tworkspacePadding.left: 29.0px (11.047619dp)\n" +
-                "\tworkspacePadding.top: 67.0px (25.52381dp)\n" +
-                "\tworkspacePadding.right: 29.0px (11.047619dp)\n" +
-                "\tworkspacePadding.bottom: 567.0px (216.0dp)\n" +
-                "\ticonScale: 0.9981516px (0.38024822dp)\n" +
-                "\tcellScaleToFit : 0.9981516px (0.38024822dp)\n" +
-                "\textraSpace: 211.0px (80.38095dp)\n" +
-                "\tunscaled extraSpace: 211.39073px (80.5298dp)\n" +
-                "\tmaxEmptySpace: 315.0px (120.0dp)\n" +
-                "\tworkspaceTopPadding: 95.0px (36.190475dp)\n" +
-                "\tworkspaceBottomPadding: 116.0px (44.190475dp)\n" +
-                "\toverviewTaskMarginPx: 42.0px (16.0dp)\n" +
-                "\toverviewTaskIconSizePx: 126.0px (48.0dp)\n" +
-                "\toverviewTaskIconDrawableSizePx: 116.0px (44.190475dp)\n" +
-                "\toverviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)\n" +
-                "\toverviewTaskThumbnailTopMarginPx: 168.0px (64.0dp)\n" +
-                "\toverviewActionsTopMarginPx: 63.0px (24.0dp)\n" +
-                "\toverviewActionsHeight: 126.0px (48.0dp)\n" +
-                "\toverviewActionsButtonSpacing: 95.0px (36.190475dp)\n" +
-                "\toverviewPageSpacing: 42.0px (16.0dp)\n" +
-                "\toverviewRowSpacing: 0.0px (0.0dp)\n" +
-                "\toverviewGridSideMargin: 0.0px (0.0dp)\n" +
-                "\tdropTargetBarTopMarginPx: 84.0px (32.0dp)\n" +
-                "\tdropTargetBarSizePx: 147.0px (56.0dp)\n" +
-                "\tdropTargetBarBottomMarginPx: 42.0px (16.0dp)\n" +
-                "\tgetCellLayoutSpringLoadShrunkTop(): 391.0px (148.95238dp)\n" +
-                "\tgetCellLayoutSpringLoadShrunkBottom(): 1689.0px (643.4286dp)\n" +
-                "\tworkspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)\n" +
-                "\tgetWorkspaceSpringLoadScale(): 0.81892747px (0.31197238dp)\n" +
-                "\tgetCellLayoutHeight(): 1585.0px (603.8095dp)\n" +
-                "\tgetCellLayoutWidth(): 1022.0px (389.33334dp)\n")
-    }
-
-    @Test
-    fun tabletLandscape3Button() {
-        initializeVarsForTablet(isLandscape = true, isGestureMode = false)
-        val dp = newDP()
-        dp.isTaskbarPresentInApps = true
-
-        assertThat(dump(dp)).isEqualTo("DeviceProfile:\n" +
-                "\t1 dp = 2.0 px\n" +
-                "\tisTablet:true\n" +
-                "\tisPhone:false\n" +
-                "\ttransposeLayoutWithOrientation:false\n" +
-                "\tisGestureMode:false\n" +
-                "\tisLandscape:true\n" +
-                "\tisMultiWindowMode:false\n" +
-                "\tisTwoPanels:false\n" +
-                "\twindowX: 0.0px (0.0dp)\n" +
-                "\twindowY: 0.0px (0.0dp)\n" +
-                "\twidthPx: 2560.0px (1280.0dp)\n" +
-                "\theightPx: 1600.0px (800.0dp)\n" +
-                "\tavailableWidthPx: 2560.0px (1280.0dp)\n" +
-                "\tavailableHeightPx: 1496.0px (748.0dp)\n" +
-                "\tmInsets.left: 0.0px (0.0dp)\n" +
-                "\tmInsets.top: 104.0px (52.0dp)\n" +
-                "\tmInsets.right: 0.0px (0.0dp)\n" +
-                "\tmInsets.bottom: 0.0px (0.0dp)\n" +
-                "\taspectRatio:1.6\n" +
-                "\tisScalableGrid:true\n" +
-                "\tinv.numRows: 5\n" +
-                "\tinv.numColumns: 6\n" +
-                "\tinv.numSearchContainerColumns: 3\n" +
-                "\tminCellSize: PointF(120.0, 104.0)dp\n" +
-                "\tcellWidthPx: 240.0px (120.0dp)\n" +
-                "\tcellHeightPx: 208.0px (104.0dp)\n" +
-                "\tgetCellSize().x: 240.0px (120.0dp)\n" +
-                "\tgetCellSize().y: 208.0px (104.0dp)\n" +
-                "\tcellLayoutBorderSpacePx Horizontal: 128.0px (64.0dp)\n" +
-                "\tcellLayoutBorderSpacePx Vertical: 32.0px (16.0dp)\n" +
-                "\tcellLayoutPaddingPx.left: 59.0px (29.5dp)\n" +
-                "\tcellLayoutPaddingPx.top: 32.0px (16.0dp)\n" +
-                "\tcellLayoutPaddingPx.right: 59.0px (29.5dp)\n" +
-                "\tcellLayoutPaddingPx.bottom: 59.0px (29.5dp)\n" +
-                "\ticonSizePx: 120.0px (60.0dp)\n" +
-                "\ticonTextSizePx: 28.0px (14.0dp)\n" +
-                "\ticonDrawablePaddingPx: 14.0px (7.0dp)\n" +
-                "\tfolderCellWidthPx: 240.0px (120.0dp)\n" +
-                "\tfolderCellHeightPx: 208.0px (104.0dp)\n" +
-                "\tfolderChildIconSizePx: 120.0px (60.0dp)\n" +
-                "\tfolderChildTextSizePx: 28.0px (14.0dp)\n" +
-                "\tfolderChildDrawablePaddingPx: 16.0px (8.0dp)\n" +
-                "\tfolderCellLayoutBorderSpacePx Horizontal: 32.0px (16.0dp)\n" +
-                "\tfolderCellLayoutBorderSpacePx Vertical: 32.0px (16.0dp)\n" +
-                "\tfolderContentPaddingLeftRight: 32.0px (16.0dp)\n" +
-                "\tfolderTopPadding: 48.0px (24.0dp)\n" +
-                "\tbottomSheetTopPadding: 104.0px (52.0dp)\n" +
-                "\tallAppsShiftRange: 1496.0px (748.0dp)\n" +
-                "\tallAppsTopPadding: 104.0px (52.0dp)\n" +
-                "\tallAppsIconSizePx: 120.0px (60.0dp)\n" +
-                "\tallAppsIconTextSizePx: 28.0px (14.0dp)\n" +
-                "\tallAppsIconDrawablePaddingPx: 14.0px (7.0dp)\n" +
-                "\tallAppsCellHeightPx: 284.0px (142.0dp)\n" +
-                "\tallAppsCellWidthPx: 252.0px (126.0dp)\n" +
-                "\tallAppsBorderSpacePxX: 32.0px (16.0dp)\n" +
-                "\tallAppsBorderSpacePxY: 32.0px (16.0dp)\n" +
-                "\tnumShownAllAppsColumns: 6\n" +
-                "\tallAppsLeftRightPadding: 64.0px (32.0dp)\n" +
-                "\tallAppsLeftRightMargin: 380.0px (190.0dp)\n" +
-                "\thotseatBarSizePx: 200.0px (100.0dp)\n" +
-                "\tinv.hotseatColumnSpan: 4\n" +
-                "\thotseatCellHeightPx: 135.0px (67.5dp)\n" +
-                "\thotseatBarBottomSpacePx: 80.0px (40.0dp)\n" +
-                "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
-                "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
-                "\thotseatBarEndOffset: 705.0px (352.5dp)\n" +
-                "\thotseatQsbSpace: 64.0px (32.0dp)\n" +
-                "\thotseatQsbHeight: 126.0px (63.0dp)\n" +
-                "\tspringLoadedHotseatBarTopMarginPx: 128.0px (64.0dp)\n" +
-                "\tgetHotseatLayoutPadding(context).top: -8.0px (-4.0dp)\n" +
-                "\tgetHotseatLayoutPadding(context).bottom: 73.0px (36.5dp)\n" +
-                "\tgetHotseatLayoutPadding(context).left: 954.0px (477.0dp)\n" +
-                "\tgetHotseatLayoutPadding(context).right: 705.0px (352.5dp)\n" +
-                "\tnumShownHotseatIcons: 6\n" +
-                "\thotseatBorderSpace: 36.0px (18.0dp)\n" +
-                "\tisQsbInline: true\n" +
-                "\thotseatQsbWidth: 619.0px (309.5dp)\n" +
-                "\tisTaskbarPresent:true\n" +
-                "\tisTaskbarPresentInApps:true\n" +
-                "\ttaskbarSize: 120.0px (60.0dp)\n" +
-                "\tdesiredWorkspaceHorizontalMarginPx: 240.0px (120.0dp)\n" +
-                "\tworkspacePadding.left: 181.0px (90.5dp)\n" +
-                "\tworkspacePadding.top: 0.0px (0.0dp)\n" +
-                "\tworkspacePadding.right: 181.0px (90.5dp)\n" +
-                "\tworkspacePadding.bottom: 237.0px (118.5dp)\n" +
-                "\ticonScale: 1.0px (0.5dp)\n" +
-                "\tcellScaleToFit : 1.0px (0.5dp)\n" +
-                "\textraSpace: 104.0px (52.0dp)\n" +
-                "\tunscaled extraSpace: 104.0px (52.0dp)\n" +
-                "\tmaxEmptySpace: 200.0px (100.0dp)\n" +
-                "\tworkspaceTopPadding: 32.0px (16.0dp)\n" +
-                "\tworkspaceBottomPadding: 72.0px (36.0dp)\n" +
-                "\toverviewTaskMarginPx: 32.0px (16.0dp)\n" +
-                "\toverviewTaskIconSizePx: 96.0px (48.0dp)\n" +
-                "\toverviewTaskIconDrawableSizePx: 88.0px (44.0dp)\n" +
-                "\toverviewTaskIconDrawableSizeGridPx: 88.0px (44.0dp)\n" +
-                "\toverviewTaskThumbnailTopMarginPx: 128.0px (64.0dp)\n" +
-                "\toverviewActionsTopMarginPx: 40.0px (20.0dp)\n" +
-                "\toverviewActionsHeight: 96.0px (48.0dp)\n" +
-                "\toverviewActionsButtonSpacing: 72.0px (36.0dp)\n" +
-                "\toverviewPageSpacing: 88.0px (44.0dp)\n" +
-                "\toverviewRowSpacing: 72.0px (36.0dp)\n" +
-                "\toverviewGridSideMargin: 128.0px (64.0dp)\n" +
-                "\tdropTargetBarTopMarginPx: 0.0px (0.0dp)\n" +
-                "\tdropTargetBarSizePx: 144.0px (72.0dp)\n" +
-                "\tdropTargetBarBottomMarginPx: 64.0px (32.0dp)\n" +
-                "\tgetCellLayoutSpringLoadShrunkTop(): 312.0px (156.0dp)\n" +
-                "\tgetCellLayoutSpringLoadShrunkBottom(): 1272.0px (636.0dp)\n" +
-                "\tworkspaceSpringLoadedMinNextPageVisiblePx: 48.0px (24.0dp)\n" +
-                "\tgetWorkspaceSpringLoadScale(): 0.76250994px (0.38125497dp)\n" +
-                "\tgetCellLayoutHeight(): 1259.0px (629.5dp)\n" +
-                "\tgetCellLayoutWidth(): 2198.0px (1099.0dp)\n")
-    }
-
-    @Test
-    fun tabletLandscape() {
-        initializeVarsForTablet(isLandscape = true)
-        val dp = newDP()
-        dp.isTaskbarPresentInApps = true
-
-        assertThat(dump(dp)).isEqualTo("DeviceProfile:\n" +
-                "\t1 dp = 2.0 px\n" +
-                "\tisTablet:true\n" +
-                "\tisPhone:false\n" +
-                "\ttransposeLayoutWithOrientation:false\n" +
-                "\tisGestureMode:true\n" +
-                "\tisLandscape:true\n" +
-                "\tisMultiWindowMode:false\n" +
-                "\tisTwoPanels:false\n" +
-                "\twindowX: 0.0px (0.0dp)\n" +
-                "\twindowY: 0.0px (0.0dp)\n" +
-                "\twidthPx: 2560.0px (1280.0dp)\n" +
-                "\theightPx: 1600.0px (800.0dp)\n" +
-                "\tavailableWidthPx: 2560.0px (1280.0dp)\n" +
-                "\tavailableHeightPx: 1496.0px (748.0dp)\n" +
-                "\tmInsets.left: 0.0px (0.0dp)\n" +
-                "\tmInsets.top: 104.0px (52.0dp)\n" +
-                "\tmInsets.right: 0.0px (0.0dp)\n" +
-                "\tmInsets.bottom: 0.0px (0.0dp)\n" +
-                "\taspectRatio:1.6\n" +
-                "\tisScalableGrid:true\n" +
-                "\tinv.numRows: 5\n" +
-                "\tinv.numColumns: 6\n" +
-                "\tinv.numSearchContainerColumns: 3\n" +
-                "\tminCellSize: PointF(120.0, 104.0)dp\n" +
-                "\tcellWidthPx: 240.0px (120.0dp)\n" +
-                "\tcellHeightPx: 208.0px (104.0dp)\n" +
-                "\tgetCellSize().x: 240.0px (120.0dp)\n" +
-                "\tgetCellSize().y: 208.0px (104.0dp)\n" +
-                "\tcellLayoutBorderSpacePx Horizontal: 128.0px (64.0dp)\n" +
-                "\tcellLayoutBorderSpacePx Vertical: 32.0px (16.0dp)\n" +
-                "\tcellLayoutPaddingPx.left: 59.0px (29.5dp)\n" +
-                "\tcellLayoutPaddingPx.top: 32.0px (16.0dp)\n" +
-                "\tcellLayoutPaddingPx.right: 59.0px (29.5dp)\n" +
-                "\tcellLayoutPaddingPx.bottom: 59.0px (29.5dp)\n" +
-                "\ticonSizePx: 120.0px (60.0dp)\n" +
-                "\ticonTextSizePx: 28.0px (14.0dp)\n" +
-                "\ticonDrawablePaddingPx: 14.0px (7.0dp)\n" +
-                "\tfolderCellWidthPx: 240.0px (120.0dp)\n" +
-                "\tfolderCellHeightPx: 208.0px (104.0dp)\n" +
-                "\tfolderChildIconSizePx: 120.0px (60.0dp)\n" +
-                "\tfolderChildTextSizePx: 28.0px (14.0dp)\n" +
-                "\tfolderChildDrawablePaddingPx: 16.0px (8.0dp)\n" +
-                "\tfolderCellLayoutBorderSpacePx Horizontal: 32.0px (16.0dp)\n" +
-                "\tfolderCellLayoutBorderSpacePx Vertical: 32.0px (16.0dp)\n" +
-                "\tfolderContentPaddingLeftRight: 32.0px (16.0dp)\n" +
-                "\tfolderTopPadding: 48.0px (24.0dp)\n" +
-                "\tbottomSheetTopPadding: 104.0px (52.0dp)\n" +
-                "\tallAppsShiftRange: 1496.0px (748.0dp)\n" +
-                "\tallAppsTopPadding: 104.0px (52.0dp)\n" +
-                "\tallAppsIconSizePx: 120.0px (60.0dp)\n" +
-                "\tallAppsIconTextSizePx: 28.0px (14.0dp)\n" +
-                "\tallAppsIconDrawablePaddingPx: 14.0px (7.0dp)\n" +
-                "\tallAppsCellHeightPx: 284.0px (142.0dp)\n" +
-                "\tallAppsCellWidthPx: 252.0px (126.0dp)\n" +
-                "\tallAppsBorderSpacePxX: 32.0px (16.0dp)\n" +
-                "\tallAppsBorderSpacePxY: 32.0px (16.0dp)\n" +
-                "\tnumShownAllAppsColumns: 6\n" +
-                "\tallAppsLeftRightPadding: 64.0px (32.0dp)\n" +
-                "\tallAppsLeftRightMargin: 380.0px (190.0dp)\n" +
-                "\thotseatBarSizePx: 200.0px (100.0dp)\n" +
-                "\tinv.hotseatColumnSpan: 4\n" +
-                "\thotseatCellHeightPx: 135.0px (67.5dp)\n" +
-                "\thotseatBarBottomSpacePx: 80.0px (40.0dp)\n" +
-                "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
-                "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
-                "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
-                "\thotseatQsbSpace: 64.0px (32.0dp)\n" +
-                "\thotseatQsbHeight: 126.0px (63.0dp)\n" +
-                "\tspringLoadedHotseatBarTopMarginPx: 128.0px (64.0dp)\n" +
-                "\tgetHotseatLayoutPadding(context).top: -8.0px (-4.0dp)\n" +
-                "\tgetHotseatLayoutPadding(context).bottom: 73.0px (36.5dp)\n" +
-                "\tgetHotseatLayoutPadding(context).left: 1040.0px (520.0dp)\n" +
-                "\tgetHotseatLayoutPadding(context).right: 300.0px (150.0dp)\n" +
-                "\tnumShownHotseatIcons: 6\n" +
-                "\thotseatBorderSpace: 100.0px (50.0dp)\n" +
-                "\tisQsbInline: true\n" +
-                "\thotseatQsbWidth: 640.0px (320.0dp)\n" +
-                "\tisTaskbarPresent:true\n" +
-                "\tisTaskbarPresentInApps:true\n" +
-                "\ttaskbarSize: 120.0px (60.0dp)\n" +
-                "\tdesiredWorkspaceHorizontalMarginPx: 240.0px (120.0dp)\n" +
-                "\tworkspacePadding.left: 181.0px (90.5dp)\n" +
-                "\tworkspacePadding.top: 0.0px (0.0dp)\n" +
-                "\tworkspacePadding.right: 181.0px (90.5dp)\n" +
-                "\tworkspacePadding.bottom: 237.0px (118.5dp)\n" +
-                "\ticonScale: 1.0px (0.5dp)\n" +
-                "\tcellScaleToFit : 1.0px (0.5dp)\n" +
-                "\textraSpace: 104.0px (52.0dp)\n" +
-                "\tunscaled extraSpace: 104.0px (52.0dp)\n" +
-                "\tmaxEmptySpace: 200.0px (100.0dp)\n" +
-                "\tworkspaceTopPadding: 32.0px (16.0dp)\n" +
-                "\tworkspaceBottomPadding: 72.0px (36.0dp)\n" +
-                "\toverviewTaskMarginPx: 32.0px (16.0dp)\n" +
-                "\toverviewTaskIconSizePx: 96.0px (48.0dp)\n" +
-                "\toverviewTaskIconDrawableSizePx: 88.0px (44.0dp)\n" +
-                "\toverviewTaskIconDrawableSizeGridPx: 88.0px (44.0dp)\n" +
-                "\toverviewTaskThumbnailTopMarginPx: 128.0px (64.0dp)\n" +
-                "\toverviewActionsTopMarginPx: 40.0px (20.0dp)\n" +
-                "\toverviewActionsHeight: 96.0px (48.0dp)\n" +
-                "\toverviewActionsButtonSpacing: 72.0px (36.0dp)\n" +
-                "\toverviewPageSpacing: 88.0px (44.0dp)\n" +
-                "\toverviewRowSpacing: 72.0px (36.0dp)\n" +
-                "\toverviewGridSideMargin: 128.0px (64.0dp)\n" +
-                "\tdropTargetBarTopMarginPx: 0.0px (0.0dp)\n" +
-                "\tdropTargetBarSizePx: 144.0px (72.0dp)\n" +
-                "\tdropTargetBarBottomMarginPx: 64.0px (32.0dp)\n" +
-                "\tgetCellLayoutSpringLoadShrunkTop(): 312.0px (156.0dp)\n" +
-                "\tgetCellLayoutSpringLoadShrunkBottom(): 1272.0px (636.0dp)\n" +
-                "\tworkspaceSpringLoadedMinNextPageVisiblePx: 48.0px (24.0dp)\n" +
-                "\tgetWorkspaceSpringLoadScale(): 0.76250994px (0.38125497dp)\n" +
-                "\tgetCellLayoutHeight(): 1259.0px (629.5dp)\n" +
-                "\tgetCellLayoutWidth(): 2198.0px (1099.0dp)\n")
-    }
-
-    @Test
-    fun tabletPortrait3Button() {
-        initializeVarsForTablet(isGestureMode = false)
-        val dp = newDP()
-        dp.isTaskbarPresentInApps = true
-
-        assertThat(dump(dp)).isEqualTo("DeviceProfile:\n" +
-                "\t1 dp = 2.0 px\n" +
-                "\tisTablet:true\n" +
-                "\tisPhone:false\n" +
-                "\ttransposeLayoutWithOrientation:false\n" +
-                "\tisGestureMode:false\n" +
-                "\tisLandscape:false\n" +
-                "\tisMultiWindowMode:false\n" +
-                "\tisTwoPanels:false\n" +
-                "\twindowX: 0.0px (0.0dp)\n" +
-                "\twindowY: 0.0px (0.0dp)\n" +
-                "\twidthPx: 1600.0px (800.0dp)\n" +
-                "\theightPx: 2560.0px (1280.0dp)\n" +
-                "\tavailableWidthPx: 1600.0px (800.0dp)\n" +
-                "\tavailableHeightPx: 2456.0px (1228.0dp)\n" +
-                "\tmInsets.left: 0.0px (0.0dp)\n" +
-                "\tmInsets.top: 104.0px (52.0dp)\n" +
-                "\tmInsets.right: 0.0px (0.0dp)\n" +
-                "\tmInsets.bottom: 0.0px (0.0dp)\n" +
-                "\taspectRatio:1.6\n" +
-                "\tisScalableGrid:true\n" +
-                "\tinv.numRows: 5\n" +
-                "\tinv.numColumns: 6\n" +
-                "\tinv.numSearchContainerColumns: 3\n" +
-                "\tminCellSize: PointF(102.0, 120.0)dp\n" +
-                "\tcellWidthPx: 204.0px (102.0dp)\n" +
-                "\tcellHeightPx: 240.0px (120.0dp)\n" +
-                "\tgetCellSize().x: 204.0px (102.0dp)\n" +
-                "\tgetCellSize().y: 240.0px (120.0dp)\n" +
-                "\tcellLayoutBorderSpacePx Horizontal: 32.0px (16.0dp)\n" +
-                "\tcellLayoutBorderSpacePx Vertical: 128.0px (64.0dp)\n" +
-                "\tcellLayoutPaddingPx.left: 72.0px (36.0dp)\n" +
-                "\tcellLayoutPaddingPx.top: 72.0px (36.0dp)\n" +
-                "\tcellLayoutPaddingPx.right: 72.0px (36.0dp)\n" +
-                "\tcellLayoutPaddingPx.bottom: 72.0px (36.0dp)\n" +
-                "\ticonSizePx: 120.0px (60.0dp)\n" +
-                "\ticonTextSizePx: 28.0px (14.0dp)\n" +
-                "\ticonDrawablePaddingPx: 14.0px (7.0dp)\n" +
-                "\tfolderCellWidthPx: 240.0px (120.0dp)\n" +
-                "\tfolderCellHeightPx: 208.0px (104.0dp)\n" +
-                "\tfolderChildIconSizePx: 120.0px (60.0dp)\n" +
-                "\tfolderChildTextSizePx: 28.0px (14.0dp)\n" +
-                "\tfolderChildDrawablePaddingPx: 16.0px (8.0dp)\n" +
-                "\tfolderCellLayoutBorderSpacePx Horizontal: 32.0px (16.0dp)\n" +
-                "\tfolderCellLayoutBorderSpacePx Vertical: 32.0px (16.0dp)\n" +
-                "\tfolderContentPaddingLeftRight: 32.0px (16.0dp)\n" +
-                "\tfolderTopPadding: 48.0px (24.0dp)\n" +
-                "\tbottomSheetTopPadding: 704.0px (352.0dp)\n" +
-                "\tallAppsShiftRange: 1936.0px (968.0dp)\n" +
-                "\tallAppsTopPadding: 624.0px (312.0dp)\n" +
-                "\tallAppsIconSizePx: 120.0px (60.0dp)\n" +
-                "\tallAppsIconTextSizePx: 28.0px (14.0dp)\n" +
-                "\tallAppsIconDrawablePaddingPx: 14.0px (7.0dp)\n" +
-                "\tallAppsCellHeightPx: 316.0px (158.0dp)\n" +
-                "\tallAppsCellWidthPx: 192.0px (96.0dp)\n" +
-                "\tallAppsBorderSpacePxX: 16.0px (8.0dp)\n" +
-                "\tallAppsBorderSpacePxY: 32.0px (16.0dp)\n" +
-                "\tnumShownAllAppsColumns: 6\n" +
-                "\tallAppsLeftRightPadding: 56.0px (28.0dp)\n" +
-                "\tallAppsLeftRightMargin: 128.0px (64.0dp)\n" +
-                "\thotseatBarSizePx: 358.0px (179.0dp)\n" +
-                "\tinv.hotseatColumnSpan: 6\n" +
-                "\thotseatCellHeightPx: 135.0px (67.5dp)\n" +
-                "\thotseatBarBottomSpacePx: 72.0px (36.0dp)\n" +
-                "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
-                "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
-                "\thotseatBarEndOffset: 558.0px (279.0dp)\n" +
-                "\thotseatQsbSpace: 64.0px (32.0dp)\n" +
-                "\thotseatQsbHeight: 126.0px (63.0dp)\n" +
-                "\tspringLoadedHotseatBarTopMarginPx: 216.0px (108.0dp)\n" +
-                "\tgetHotseatLayoutPadding(context).top: 158.0px (79.0dp)\n" +
-                "\tgetHotseatLayoutPadding(context).bottom: 65.0px (32.5dp)\n" +
-                "\tgetHotseatLayoutPadding(context).left: 150.0px (75.0dp)\n" +
-                "\tgetHotseatLayoutPadding(context).right: 558.0px (279.0dp)\n" +
-                "\tnumShownHotseatIcons: 5\n" +
-                "\thotseatBorderSpace: 73.0px (36.5dp)\n" +
-                "\tisQsbInline: false\n" +
-                "\thotseatQsbWidth: 1300.0px (650.0dp)\n" +
-                "\tisTaskbarPresent:true\n" +
-                "\tisTaskbarPresentInApps:true\n" +
-                "\ttaskbarSize: 120.0px (60.0dp)\n" +
-                "\tdesiredWorkspaceHorizontalMarginPx: 108.0px (54.0dp)\n" +
-                "\tworkspacePadding.left: 36.0px (18.0dp)\n" +
-                "\tworkspacePadding.top: 87.0px (43.5dp)\n" +
-                "\tworkspacePadding.right: 36.0px (18.0dp)\n" +
-                "\tworkspacePadding.bottom: 513.0px (256.5dp)\n" +
-                "\ticonScale: 1.0px (0.5dp)\n" +
-                "\tcellScaleToFit : 1.0px (0.5dp)\n" +
-                "\textraSpace: 362.0px (181.0dp)\n" +
-                "\tunscaled extraSpace: 362.0px (181.0dp)\n" +
-                "\tmaxEmptySpace: 19998.0px (9999.0dp)\n" +
-                "\tworkspaceTopPadding: 159.0px (79.5dp)\n" +
-                "\tworkspaceBottomPadding: 203.0px (101.5dp)\n" +
-                "\toverviewTaskMarginPx: 32.0px (16.0dp)\n" +
-                "\toverviewTaskIconSizePx: 96.0px (48.0dp)\n" +
-                "\toverviewTaskIconDrawableSizePx: 88.0px (44.0dp)\n" +
-                "\toverviewTaskIconDrawableSizeGridPx: 88.0px (44.0dp)\n" +
-                "\toverviewTaskThumbnailTopMarginPx: 128.0px (64.0dp)\n" +
-                "\toverviewActionsTopMarginPx: 48.0px (24.0dp)\n" +
-                "\toverviewActionsHeight: 96.0px (48.0dp)\n" +
-                "\toverviewActionsButtonSpacing: 72.0px (36.0dp)\n" +
-                "\toverviewPageSpacing: 88.0px (44.0dp)\n" +
-                "\toverviewRowSpacing: 72.0px (36.0dp)\n" +
-                "\toverviewGridSideMargin: 128.0px (64.0dp)\n" +
-                "\tdropTargetBarTopMarginPx: 220.0px (110.0dp)\n" +
-                "\tdropTargetBarSizePx: 144.0px (72.0dp)\n" +
-                "\tdropTargetBarBottomMarginPx: 96.0px (48.0dp)\n" +
-                "\tgetCellLayoutSpringLoadShrunkTop(): 564.0px (282.0dp)\n" +
-                "\tgetCellLayoutSpringLoadShrunkBottom(): 1986.0px (993.0dp)\n" +
-                "\tworkspaceSpringLoadedMinNextPageVisiblePx: 48.0px (24.0dp)\n" +
-                "\tgetWorkspaceSpringLoadScale(): 0.76616377px (0.38308188dp)\n" +
-                "\tgetCellLayoutHeight(): 1856.0px (928.0dp)\n" +
-                "\tgetCellLayoutWidth(): 1528.0px (764.0dp)\n")
-    }
-
-    @Test
-    fun tabletPortrait() {
-        initializeVarsForTablet()
-        val dp = newDP()
-        dp.isTaskbarPresentInApps = true
-
-        assertThat(dump(dp)).isEqualTo("DeviceProfile:\n" +
-                "\t1 dp = 2.0 px\n" +
-                "\tisTablet:true\n" +
-                "\tisPhone:false\n" +
-                "\ttransposeLayoutWithOrientation:false\n" +
-                "\tisGestureMode:true\n" +
-                "\tisLandscape:false\n" +
-                "\tisMultiWindowMode:false\n" +
-                "\tisTwoPanels:false\n" +
-                "\twindowX: 0.0px (0.0dp)\n" +
-                "\twindowY: 0.0px (0.0dp)\n" +
-                "\twidthPx: 1600.0px (800.0dp)\n" +
-                "\theightPx: 2560.0px (1280.0dp)\n" +
-                "\tavailableWidthPx: 1600.0px (800.0dp)\n" +
-                "\tavailableHeightPx: 2456.0px (1228.0dp)\n" +
-                "\tmInsets.left: 0.0px (0.0dp)\n" +
-                "\tmInsets.top: 104.0px (52.0dp)\n" +
-                "\tmInsets.right: 0.0px (0.0dp)\n" +
-                "\tmInsets.bottom: 0.0px (0.0dp)\n" +
-                "\taspectRatio:1.6\n" +
-                "\tisScalableGrid:true\n" +
-                "\tinv.numRows: 5\n" +
-                "\tinv.numColumns: 6\n" +
-                "\tinv.numSearchContainerColumns: 3\n" +
-                "\tminCellSize: PointF(102.0, 120.0)dp\n" +
-                "\tcellWidthPx: 204.0px (102.0dp)\n" +
-                "\tcellHeightPx: 240.0px (120.0dp)\n" +
-                "\tgetCellSize().x: 204.0px (102.0dp)\n" +
-                "\tgetCellSize().y: 240.0px (120.0dp)\n" +
-                "\tcellLayoutBorderSpacePx Horizontal: 32.0px (16.0dp)\n" +
-                "\tcellLayoutBorderSpacePx Vertical: 128.0px (64.0dp)\n" +
-                "\tcellLayoutPaddingPx.left: 72.0px (36.0dp)\n" +
-                "\tcellLayoutPaddingPx.top: 72.0px (36.0dp)\n" +
-                "\tcellLayoutPaddingPx.right: 72.0px (36.0dp)\n" +
-                "\tcellLayoutPaddingPx.bottom: 72.0px (36.0dp)\n" +
-                "\ticonSizePx: 120.0px (60.0dp)\n" +
-                "\ticonTextSizePx: 28.0px (14.0dp)\n" +
-                "\ticonDrawablePaddingPx: 14.0px (7.0dp)\n" +
-                "\tfolderCellWidthPx: 240.0px (120.0dp)\n" +
-                "\tfolderCellHeightPx: 208.0px (104.0dp)\n" +
-                "\tfolderChildIconSizePx: 120.0px (60.0dp)\n" +
-                "\tfolderChildTextSizePx: 28.0px (14.0dp)\n" +
-                "\tfolderChildDrawablePaddingPx: 16.0px (8.0dp)\n" +
-                "\tfolderCellLayoutBorderSpacePx Horizontal: 32.0px (16.0dp)\n" +
-                "\tfolderCellLayoutBorderSpacePx Vertical: 32.0px (16.0dp)\n" +
-                "\tfolderContentPaddingLeftRight: 32.0px (16.0dp)\n" +
-                "\tfolderTopPadding: 48.0px (24.0dp)\n" +
-                "\tbottomSheetTopPadding: 704.0px (352.0dp)\n" +
-                "\tallAppsShiftRange: 1936.0px (968.0dp)\n" +
-                "\tallAppsTopPadding: 624.0px (312.0dp)\n" +
-                "\tallAppsIconSizePx: 120.0px (60.0dp)\n" +
-                "\tallAppsIconTextSizePx: 28.0px (14.0dp)\n" +
-                "\tallAppsIconDrawablePaddingPx: 14.0px (7.0dp)\n" +
-                "\tallAppsCellHeightPx: 316.0px (158.0dp)\n" +
-                "\tallAppsCellWidthPx: 192.0px (96.0dp)\n" +
-                "\tallAppsBorderSpacePxX: 16.0px (8.0dp)\n" +
-                "\tallAppsBorderSpacePxY: 32.0px (16.0dp)\n" +
-                "\tnumShownAllAppsColumns: 6\n" +
-                "\tallAppsLeftRightPadding: 56.0px (28.0dp)\n" +
-                "\tallAppsLeftRightMargin: 128.0px (64.0dp)\n" +
-                "\thotseatBarSizePx: 358.0px (179.0dp)\n" +
-                "\tinv.hotseatColumnSpan: 6\n" +
-                "\thotseatCellHeightPx: 135.0px (67.5dp)\n" +
-                "\thotseatBarBottomSpacePx: 72.0px (36.0dp)\n" +
-                "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
-                "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
-                "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
-                "\thotseatQsbSpace: 64.0px (32.0dp)\n" +
-                "\thotseatQsbHeight: 126.0px (63.0dp)\n" +
-                "\tspringLoadedHotseatBarTopMarginPx: 216.0px (108.0dp)\n" +
-                "\tgetHotseatLayoutPadding(context).top: 158.0px (79.0dp)\n" +
-                "\tgetHotseatLayoutPadding(context).bottom: 65.0px (32.5dp)\n" +
-                "\tgetHotseatLayoutPadding(context).left: 150.0px (75.0dp)\n" +
-                "\tgetHotseatLayoutPadding(context).right: 150.0px (75.0dp)\n" +
-                "\tnumShownHotseatIcons: 6\n" +
-                "\thotseatBorderSpace: 116.0px (58.0dp)\n" +
-                "\tisQsbInline: false\n" +
-                "\thotseatQsbWidth: 1300.0px (650.0dp)\n" +
-                "\tisTaskbarPresent:true\n" +
-                "\tisTaskbarPresentInApps:true\n" +
-                "\ttaskbarSize: 120.0px (60.0dp)\n" +
-                "\tdesiredWorkspaceHorizontalMarginPx: 108.0px (54.0dp)\n" +
-                "\tworkspacePadding.left: 36.0px (18.0dp)\n" +
-                "\tworkspacePadding.top: 87.0px (43.5dp)\n" +
-                "\tworkspacePadding.right: 36.0px (18.0dp)\n" +
-                "\tworkspacePadding.bottom: 513.0px (256.5dp)\n" +
-                "\ticonScale: 1.0px (0.5dp)\n" +
-                "\tcellScaleToFit : 1.0px (0.5dp)\n" +
-                "\textraSpace: 362.0px (181.0dp)\n" +
-                "\tunscaled extraSpace: 362.0px (181.0dp)\n" +
-                "\tmaxEmptySpace: 19998.0px (9999.0dp)\n" +
-                "\tworkspaceTopPadding: 159.0px (79.5dp)\n" +
-                "\tworkspaceBottomPadding: 203.0px (101.5dp)\n" +
-                "\toverviewTaskMarginPx: 32.0px (16.0dp)\n" +
-                "\toverviewTaskIconSizePx: 96.0px (48.0dp)\n" +
-                "\toverviewTaskIconDrawableSizePx: 88.0px (44.0dp)\n" +
-                "\toverviewTaskIconDrawableSizeGridPx: 88.0px (44.0dp)\n" +
-                "\toverviewTaskThumbnailTopMarginPx: 128.0px (64.0dp)\n" +
-                "\toverviewActionsTopMarginPx: 48.0px (24.0dp)\n" +
-                "\toverviewActionsHeight: 96.0px (48.0dp)\n" +
-                "\toverviewActionsButtonSpacing: 72.0px (36.0dp)\n" +
-                "\toverviewPageSpacing: 88.0px (44.0dp)\n" +
-                "\toverviewRowSpacing: 72.0px (36.0dp)\n" +
-                "\toverviewGridSideMargin: 128.0px (64.0dp)\n" +
-                "\tdropTargetBarTopMarginPx: 220.0px (110.0dp)\n" +
-                "\tdropTargetBarSizePx: 144.0px (72.0dp)\n" +
-                "\tdropTargetBarBottomMarginPx: 96.0px (48.0dp)\n" +
-                "\tgetCellLayoutSpringLoadShrunkTop(): 564.0px (282.0dp)\n" +
-                "\tgetCellLayoutSpringLoadShrunkBottom(): 1986.0px (993.0dp)\n" +
-                "\tworkspaceSpringLoadedMinNextPageVisiblePx: 48.0px (24.0dp)\n" +
-                "\tgetWorkspaceSpringLoadScale(): 0.76616377px (0.38308188dp)\n" +
-                "\tgetCellLayoutHeight(): 1856.0px (928.0dp)\n" +
-                "\tgetCellLayoutWidth(): 1528.0px (764.0dp)\n")
-    }
-
-    @Test
-    fun twoPanelLandscape3Button() {
-        initializeVarsForTwoPanel(isLandscape = true, isGestureMode = false)
-        val dp = newDP()
-        dp.isTaskbarPresentInApps = true
-
-        assertThat(dump(dp)).isEqualTo("DeviceProfile:\n" +
-                "\t1 dp = 2.625 px\n" +
-                "\tisTablet:true\n" +
-                "\tisPhone:false\n" +
-                "\ttransposeLayoutWithOrientation:false\n" +
-                "\tisGestureMode:false\n" +
-                "\tisLandscape:true\n" +
-                "\tisMultiWindowMode:false\n" +
-                "\tisTwoPanels:true\n" +
-                "\twindowX: 0.0px (0.0dp)\n" +
-                "\twindowY: 0.0px (0.0dp)\n" +
-                "\twidthPx: 2208.0px (841.1429dp)\n" +
-                "\theightPx: 1840.0px (700.9524dp)\n" +
-                "\tavailableWidthPx: 2208.0px (841.1429dp)\n" +
-                "\tavailableHeightPx: 1730.0px (659.0476dp)\n" +
-                "\tmInsets.left: 0.0px (0.0dp)\n" +
-                "\tmInsets.top: 110.0px (41.904762dp)\n" +
-                "\tmInsets.right: 0.0px (0.0dp)\n" +
-                "\tmInsets.bottom: 0.0px (0.0dp)\n" +
-                "\taspectRatio:1.2\n" +
-                "\tisScalableGrid:true\n" +
-                "\tinv.numRows: 4\n" +
-                "\tinv.numColumns: 4\n" +
-                "\tinv.numSearchContainerColumns: 4\n" +
-                "\tminCellSize: PointF(80.0, 102.0)dp\n" +
-                "\tcellWidthPx: 210.0px (80.0dp)\n" +
-                "\tcellHeightPx: 267.0px (101.71429dp)\n" +
-                "\tgetCellSize().x: 210.0px (80.0dp)\n" +
-                "\tgetCellSize().y: 267.0px (101.71429dp)\n" +
-                "\tcellLayoutBorderSpacePx Horizontal: 52.0px (19.809525dp)\n" +
-                "\tcellLayoutBorderSpacePx Vertical: 52.0px (19.809525dp)\n" +
-                "\tcellLayoutPaddingPx.left: 26.0px (9.904762dp)\n" +
-                "\tcellLayoutPaddingPx.top: 18.0px (6.857143dp)\n" +
-                "\tcellLayoutPaddingPx.right: 26.0px (9.904762dp)\n" +
-                "\tcellLayoutPaddingPx.bottom: 26.0px (9.904762dp)\n" +
-                "\ticonSizePx: 157.0px (59.809525dp)\n" +
-                "\ticonTextSizePx: 36.0px (13.714286dp)\n" +
-                "\ticonDrawablePaddingPx: 17.0px (6.4761906dp)\n" +
-                "\tfolderCellWidthPx: 210.0px (80.0dp)\n" +
-                "\tfolderCellHeightPx: 247.0px (94.09524dp)\n" +
-                "\tfolderChildIconSizePx: 158.0px (60.190475dp)\n" +
-                "\tfolderChildTextSizePx: 37.0px (14.095238dp)\n" +
-                "\tfolderChildDrawablePaddingPx: 13.0px (4.952381dp)\n" +
-                "\tfolderCellLayoutBorderSpacePx Horizontal: 42.0px (16.0dp)\n" +
-                "\tfolderCellLayoutBorderSpacePx Vertical: 42.0px (16.0dp)\n" +
-                "\tfolderContentPaddingLeftRight: 42.0px (16.0dp)\n" +
-                "\tfolderTopPadding: 63.0px (24.0dp)\n" +
-                "\tbottomSheetTopPadding: 110.0px (41.904762dp)\n" +
-                "\tallAppsShiftRange: 1730.0px (659.0476dp)\n" +
-                "\tallAppsTopPadding: 110.0px (41.904762dp)\n" +
-                "\tallAppsIconSizePx: 157.0px (59.809525dp)\n" +
-                "\tallAppsIconTextSizePx: 37.0px (14.095238dp)\n" +
-                "\tallAppsIconDrawablePaddingPx: 18.0px (6.857143dp)\n" +
-                "\tallAppsCellHeightPx: 315.0px (120.0dp)\n" +
-                "\tallAppsCellWidthPx: 210.0px (80.0dp)\n" +
-                "\tallAppsBorderSpacePxX: 52.0px (19.809525dp)\n" +
-                "\tallAppsBorderSpacePxY: 42.0px (16.0dp)\n" +
-                "\tnumShownAllAppsColumns: 6\n" +
-                "\tallAppsLeftRightPadding: 137.0px (52.190475dp)\n" +
-                "\tallAppsLeftRightMargin: 207.0px (78.85714dp)\n" +
-                "\thotseatBarSizePx: 417.0px (158.85715dp)\n" +
-                "\tinv.hotseatColumnSpan: 6\n" +
-                "\thotseatCellHeightPx: 177.0px (67.42857dp)\n" +
-                "\thotseatBarBottomSpacePx: 53.0px (20.190475dp)\n" +
-                "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
-                "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
-                "\thotseatBarEndOffset: 744.0px (283.42856dp)\n" +
-                "\thotseatQsbSpace: 74.0px (28.190475dp)\n" +
-                "\thotseatQsbHeight: 165.0px (62.857143dp)\n" +
-                "\tspringLoadedHotseatBarTopMarginPx: 116.0px (44.190475dp)\n" +
-                "\tgetHotseatLayoutPadding(context).top: 197.0px (75.04762dp)\n" +
-                "\tgetHotseatLayoutPadding(context).bottom: 43.0px (16.380953dp)\n" +
-                "\tgetHotseatLayoutPadding(context).left: 106.0px (40.38095dp)\n" +
-                "\tgetHotseatLayoutPadding(context).right: 744.0px (283.42856dp)\n" +
-                "\tnumShownHotseatIcons: 6\n" +
-                "\thotseatBorderSpace: 83.0px (31.619047dp)\n" +
-                "\tisQsbInline: false\n" +
-                "\thotseatQsbWidth: 1467.0px (558.8571dp)\n" +
-                "\tisTaskbarPresent:true\n" +
-                "\tisTaskbarPresentInApps:true\n" +
-                "\ttaskbarSize: 158.0px (60.190475dp)\n" +
-                "\tdesiredWorkspaceHorizontalMarginPx: 79.0px (30.095238dp)\n" +
-                "\tworkspacePadding.left: 53.0px (20.190475dp)\n" +
-                "\tworkspacePadding.top: 0.0px (0.0dp)\n" +
-                "\tworkspacePadding.right: 53.0px (20.190475dp)\n" +
-                "\tworkspacePadding.bottom: 461.0px (175.61905dp)\n" +
-                "\ticonScale: 0.99864316px (0.3804355dp)\n" +
-                "\tcellScaleToFit : 0.99864316px (0.3804355dp)\n" +
-                "\textraSpace: 57.0px (21.714285dp)\n" +
-                "\tunscaled extraSpace: 57.077446px (21.74379dp)\n" +
-                "\tmaxEmptySpace: 131.0px (49.904762dp)\n" +
-                "\tworkspaceTopPadding: 18.0px (6.857143dp)\n" +
-                "\tworkspaceBottomPadding: 39.0px (14.857142dp)\n" +
-                "\toverviewTaskMarginPx: 32.0px (12.190476dp)\n" +
-                "\toverviewTaskIconSizePx: 126.0px (48.0dp)\n" +
-                "\toverviewTaskIconDrawableSizePx: 116.0px (44.190475dp)\n" +
-                "\toverviewTaskIconDrawableSizeGridPx: 116.0px (44.190475dp)\n" +
-                "\toverviewTaskThumbnailTopMarginPx: 158.0px (60.190475dp)\n" +
-                "\toverviewActionsTopMarginPx: 32.0px (12.190476dp)\n" +
-                "\toverviewActionsHeight: 126.0px (48.0dp)\n" +
-                "\toverviewActionsButtonSpacing: 95.0px (36.190475dp)\n" +
-                "\toverviewPageSpacing: 95.0px (36.190475dp)\n" +
-                "\toverviewRowSpacing: 74.0px (28.190475dp)\n" +
-                "\toverviewGridSideMargin: 168.0px (64.0dp)\n" +
-                "\tdropTargetBarTopMarginPx: 0.0px (0.0dp)\n" +
-                "\tdropTargetBarSizePx: 147.0px (56.0dp)\n" +
-                "\tdropTargetBarBottomMarginPx: 42.0px (16.0dp)\n" +
-                "\tgetCellLayoutSpringLoadShrunkTop(): 299.0px (113.90476dp)\n" +
-                "\tgetCellLayoutSpringLoadShrunkBottom(): 1307.0px (497.90475dp)\n" +
-                "\tworkspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)\n" +
-                "\tgetWorkspaceSpringLoadScale(): 0.79432625px (0.30260047dp)\n" +
-                "\tgetCellLayoutHeight(): 1269.0px (483.42856dp)\n" +
-                "\tgetCellLayoutWidth(): 1051.0px (400.38095dp)\n")
-    }
-
-    @Test
-    fun twoPanelLandscape() {
-        initializeVarsForTwoPanel(isLandscape = true)
-        val dp = newDP()
-        dp.isTaskbarPresentInApps = true
-
-        assertThat(dump(dp)).isEqualTo("DeviceProfile:\n" +
-                "\t1 dp = 2.625 px\n" +
-                "\tisTablet:true\n" +
-                "\tisPhone:false\n" +
-                "\ttransposeLayoutWithOrientation:false\n" +
-                "\tisGestureMode:true\n" +
-                "\tisLandscape:true\n" +
-                "\tisMultiWindowMode:false\n" +
-                "\tisTwoPanels:true\n" +
-                "\twindowX: 0.0px (0.0dp)\n" +
-                "\twindowY: 0.0px (0.0dp)\n" +
-                "\twidthPx: 2208.0px (841.1429dp)\n" +
-                "\theightPx: 1840.0px (700.9524dp)\n" +
-                "\tavailableWidthPx: 2208.0px (841.1429dp)\n" +
-                "\tavailableHeightPx: 1730.0px (659.0476dp)\n" +
-                "\tmInsets.left: 0.0px (0.0dp)\n" +
-                "\tmInsets.top: 110.0px (41.904762dp)\n" +
-                "\tmInsets.right: 0.0px (0.0dp)\n" +
-                "\tmInsets.bottom: 0.0px (0.0dp)\n" +
-                "\taspectRatio:1.2\n" +
-                "\tisScalableGrid:true\n" +
-                "\tinv.numRows: 4\n" +
-                "\tinv.numColumns: 4\n" +
-                "\tinv.numSearchContainerColumns: 4\n" +
-                "\tminCellSize: PointF(80.0, 102.0)dp\n" +
-                "\tcellWidthPx: 210.0px (80.0dp)\n" +
-                "\tcellHeightPx: 267.0px (101.71429dp)\n" +
-                "\tgetCellSize().x: 210.0px (80.0dp)\n" +
-                "\tgetCellSize().y: 267.0px (101.71429dp)\n" +
-                "\tcellLayoutBorderSpacePx Horizontal: 52.0px (19.809525dp)\n" +
-                "\tcellLayoutBorderSpacePx Vertical: 52.0px (19.809525dp)\n" +
-                "\tcellLayoutPaddingPx.left: 26.0px (9.904762dp)\n" +
-                "\tcellLayoutPaddingPx.top: 18.0px (6.857143dp)\n" +
-                "\tcellLayoutPaddingPx.right: 26.0px (9.904762dp)\n" +
-                "\tcellLayoutPaddingPx.bottom: 26.0px (9.904762dp)\n" +
-                "\ticonSizePx: 157.0px (59.809525dp)\n" +
-                "\ticonTextSizePx: 36.0px (13.714286dp)\n" +
-                "\ticonDrawablePaddingPx: 17.0px (6.4761906dp)\n" +
-                "\tfolderCellWidthPx: 210.0px (80.0dp)\n" +
-                "\tfolderCellHeightPx: 247.0px (94.09524dp)\n" +
-                "\tfolderChildIconSizePx: 158.0px (60.190475dp)\n" +
-                "\tfolderChildTextSizePx: 37.0px (14.095238dp)\n" +
-                "\tfolderChildDrawablePaddingPx: 13.0px (4.952381dp)\n" +
-                "\tfolderCellLayoutBorderSpacePx Horizontal: 42.0px (16.0dp)\n" +
-                "\tfolderCellLayoutBorderSpacePx Vertical: 42.0px (16.0dp)\n" +
-                "\tfolderContentPaddingLeftRight: 42.0px (16.0dp)\n" +
-                "\tfolderTopPadding: 63.0px (24.0dp)\n" +
-                "\tbottomSheetTopPadding: 110.0px (41.904762dp)\n" +
-                "\tallAppsShiftRange: 1730.0px (659.0476dp)\n" +
-                "\tallAppsTopPadding: 110.0px (41.904762dp)\n" +
-                "\tallAppsIconSizePx: 157.0px (59.809525dp)\n" +
-                "\tallAppsIconTextSizePx: 37.0px (14.095238dp)\n" +
-                "\tallAppsIconDrawablePaddingPx: 18.0px (6.857143dp)\n" +
-                "\tallAppsCellHeightPx: 315.0px (120.0dp)\n" +
-                "\tallAppsCellWidthPx: 210.0px (80.0dp)\n" +
-                "\tallAppsBorderSpacePxX: 52.0px (19.809525dp)\n" +
-                "\tallAppsBorderSpacePxY: 42.0px (16.0dp)\n" +
-                "\tnumShownAllAppsColumns: 6\n" +
-                "\tallAppsLeftRightPadding: 137.0px (52.190475dp)\n" +
-                "\tallAppsLeftRightMargin: 207.0px (78.85714dp)\n" +
-                "\thotseatBarSizePx: 417.0px (158.85715dp)\n" +
-                "\tinv.hotseatColumnSpan: 6\n" +
-                "\thotseatCellHeightPx: 177.0px (67.42857dp)\n" +
-                "\thotseatBarBottomSpacePx: 53.0px (20.190475dp)\n" +
-                "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
-                "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
-                "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
-                "\thotseatQsbSpace: 74.0px (28.190475dp)\n" +
-                "\thotseatQsbHeight: 165.0px (62.857143dp)\n" +
-                "\tspringLoadedHotseatBarTopMarginPx: 116.0px (44.190475dp)\n" +
-                "\tgetHotseatLayoutPadding(context).top: 197.0px (75.04762dp)\n" +
-                "\tgetHotseatLayoutPadding(context).bottom: 43.0px (16.380953dp)\n" +
-                "\tgetHotseatLayoutPadding(context).left: 370.0px (140.95238dp)\n" +
-                "\tgetHotseatLayoutPadding(context).right: 370.0px (140.95238dp)\n" +
-                "\tnumShownHotseatIcons: 6\n" +
-                "\thotseatBorderSpace: 105.0px (40.0dp)\n" +
-                "\tisQsbInline: false\n" +
-                "\thotseatQsbWidth: 1467.0px (558.8571dp)\n" +
-                "\tisTaskbarPresent:true\n" +
-                "\tisTaskbarPresentInApps:true\n" +
-                "\ttaskbarSize: 158.0px (60.190475dp)\n" +
-                "\tdesiredWorkspaceHorizontalMarginPx: 79.0px (30.095238dp)\n" +
-                "\tworkspacePadding.left: 53.0px (20.190475dp)\n" +
-                "\tworkspacePadding.top: 0.0px (0.0dp)\n" +
-                "\tworkspacePadding.right: 53.0px (20.190475dp)\n" +
-                "\tworkspacePadding.bottom: 461.0px (175.61905dp)\n" +
-                "\ticonScale: 0.99864316px (0.3804355dp)\n" +
-                "\tcellScaleToFit : 0.99864316px (0.3804355dp)\n" +
-                "\textraSpace: 57.0px (21.714285dp)\n" +
-                "\tunscaled extraSpace: 57.077446px (21.74379dp)\n" +
-                "\tmaxEmptySpace: 131.0px (49.904762dp)\n" +
-                "\tworkspaceTopPadding: 18.0px (6.857143dp)\n" +
-                "\tworkspaceBottomPadding: 39.0px (14.857142dp)\n" +
-                "\toverviewTaskMarginPx: 32.0px (12.190476dp)\n" +
-                "\toverviewTaskIconSizePx: 126.0px (48.0dp)\n" +
-                "\toverviewTaskIconDrawableSizePx: 116.0px (44.190475dp)\n" +
-                "\toverviewTaskIconDrawableSizeGridPx: 116.0px (44.190475dp)\n" +
-                "\toverviewTaskThumbnailTopMarginPx: 158.0px (60.190475dp)\n" +
-                "\toverviewActionsTopMarginPx: 32.0px (12.190476dp)\n" +
-                "\toverviewActionsHeight: 126.0px (48.0dp)\n" +
-                "\toverviewActionsButtonSpacing: 95.0px (36.190475dp)\n" +
-                "\toverviewPageSpacing: 95.0px (36.190475dp)\n" +
-                "\toverviewRowSpacing: 74.0px (28.190475dp)\n" +
-                "\toverviewGridSideMargin: 168.0px (64.0dp)\n" +
-                "\tdropTargetBarTopMarginPx: 0.0px (0.0dp)\n" +
-                "\tdropTargetBarSizePx: 147.0px (56.0dp)\n" +
-                "\tdropTargetBarBottomMarginPx: 42.0px (16.0dp)\n" +
-                "\tgetCellLayoutSpringLoadShrunkTop(): 299.0px (113.90476dp)\n" +
-                "\tgetCellLayoutSpringLoadShrunkBottom(): 1307.0px (497.90475dp)\n" +
-                "\tworkspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)\n" +
-                "\tgetWorkspaceSpringLoadScale(): 0.79432625px (0.30260047dp)\n" +
-                "\tgetCellLayoutHeight(): 1269.0px (483.42856dp)\n" +
-                "\tgetCellLayoutWidth(): 1051.0px (400.38095dp)\n")
-    }
-
-    @Test
-    fun twoPanelPortrait3Button() {
-        initializeVarsForTwoPanel(isGestureMode = false)
-        val dp = newDP()
-        dp.isTaskbarPresentInApps = true
-
-        assertThat(dump(dp)).isEqualTo("DeviceProfile:\n" +
-                "\t1 dp = 2.625 px\n" +
-                "\tisTablet:true\n" +
-                "\tisPhone:false\n" +
-                "\ttransposeLayoutWithOrientation:false\n" +
-                "\tisGestureMode:false\n" +
-                "\tisLandscape:false\n" +
-                "\tisMultiWindowMode:false\n" +
-                "\tisTwoPanels:true\n" +
-                "\twindowX: 0.0px (0.0dp)\n" +
-                "\twindowY: 0.0px (0.0dp)\n" +
-                "\twidthPx: 1840.0px (700.9524dp)\n" +
-                "\theightPx: 2208.0px (841.1429dp)\n" +
-                "\tavailableWidthPx: 1840.0px (700.9524dp)\n" +
-                "\tavailableHeightPx: 2098.0px (799.2381dp)\n" +
-                "\tmInsets.left: 0.0px (0.0dp)\n" +
-                "\tmInsets.top: 110.0px (41.904762dp)\n" +
-                "\tmInsets.right: 0.0px (0.0dp)\n" +
-                "\tmInsets.bottom: 0.0px (0.0dp)\n" +
-                "\taspectRatio:1.2\n" +
-                "\tisScalableGrid:true\n" +
-                "\tinv.numRows: 4\n" +
-                "\tinv.numColumns: 4\n" +
-                "\tinv.numSearchContainerColumns: 4\n" +
-                "\tminCellSize: PointF(68.0, 116.0)dp\n" +
-                "\tcellWidthPx: 178.0px (67.809525dp)\n" +
-                "\tcellHeightPx: 304.0px (115.809525dp)\n" +
-                "\tgetCellSize().x: 178.0px (67.809525dp)\n" +
-                "\tgetCellSize().y: 304.0px (115.809525dp)\n" +
-                "\tcellLayoutBorderSpacePx Horizontal: 42.0px (16.0dp)\n" +
-                "\tcellLayoutBorderSpacePx Vertical: 52.0px (19.809525dp)\n" +
-                "\tcellLayoutPaddingPx.left: 21.0px (8.0dp)\n" +
-                "\tcellLayoutPaddingPx.top: 21.0px (8.0dp)\n" +
-                "\tcellLayoutPaddingPx.right: 21.0px (8.0dp)\n" +
-                "\tcellLayoutPaddingPx.bottom: 21.0px (8.0dp)\n" +
-                "\ticonSizePx: 136.0px (51.809525dp)\n" +
-                "\ticonTextSizePx: 31.0px (11.809524dp)\n" +
-                "\ticonDrawablePaddingPx: 17.0px (6.4761906dp)\n" +
-                "\tfolderCellWidthPx: 210.0px (80.0dp)\n" +
-                "\tfolderCellHeightPx: 247.0px (94.09524dp)\n" +
-                "\tfolderChildIconSizePx: 158.0px (60.190475dp)\n" +
-                "\tfolderChildTextSizePx: 37.0px (14.095238dp)\n" +
-                "\tfolderChildDrawablePaddingPx: 13.0px (4.952381dp)\n" +
-                "\tfolderCellLayoutBorderSpacePx Horizontal: 42.0px (16.0dp)\n" +
-                "\tfolderCellLayoutBorderSpacePx Vertical: 42.0px (16.0dp)\n" +
-                "\tfolderContentPaddingLeftRight: 42.0px (16.0dp)\n" +
-                "\tfolderTopPadding: 63.0px (24.0dp)\n" +
-                "\tbottomSheetTopPadding: 110.0px (41.904762dp)\n" +
-                "\tallAppsShiftRange: 2098.0px (799.2381dp)\n" +
-                "\tallAppsTopPadding: 110.0px (41.904762dp)\n" +
-                "\tallAppsIconSizePx: 136.0px (51.809525dp)\n" +
-                "\tallAppsIconTextSizePx: 31.0px (11.809524dp)\n" +
-                "\tallAppsIconDrawablePaddingPx: 18.0px (6.857143dp)\n" +
-                "\tallAppsCellHeightPx: 345.0px (131.42857dp)\n" +
-                "\tallAppsCellWidthPx: 178.0px (67.809525dp)\n" +
-                "\tallAppsBorderSpacePxX: 42.0px (16.0dp)\n" +
-                "\tallAppsBorderSpacePxY: 73.0px (27.809525dp)\n" +
-                "\tnumShownAllAppsColumns: 6\n" +
-                "\tallAppsLeftRightPadding: 126.0px (48.0dp)\n" +
-                "\tallAppsLeftRightMargin: 155.0px (59.04762dp)\n" +
-                "\thotseatBarSizePx: 459.0px (174.85715dp)\n" +
-                "\tinv.hotseatColumnSpan: 6\n" +
-                "\thotseatCellHeightPx: 153.0px (58.285713dp)\n" +
-                "\thotseatBarBottomSpacePx: 95.0px (36.190475dp)\n" +
-                "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
-                "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
-                "\thotseatBarEndOffset: 660.0px (251.42857dp)\n" +
-                "\thotseatQsbSpace: 95.0px (36.190475dp)\n" +
-                "\thotseatQsbHeight: 165.0px (62.857143dp)\n" +
-                "\tspringLoadedHotseatBarTopMarginPx: 171.0px (65.14286dp)\n" +
-                "\tgetHotseatLayoutPadding(context).top: 219.0px (83.42857dp)\n" +
-                "\tgetHotseatLayoutPadding(context).bottom: 87.0px (33.142857dp)\n" +
-                "\tgetHotseatLayoutPadding(context).left: 78.0px (29.714285dp)\n" +
-                "\tgetHotseatLayoutPadding(context).right: 660.0px (251.42857dp)\n" +
-                "\tnumShownHotseatIcons: 6\n" +
-                "\thotseatBorderSpace: 57.0px (21.714285dp)\n" +
-                "\tisQsbInline: false\n" +
-                "\thotseatQsbWidth: 1236.0px (470.85715dp)\n" +
-                "\tisTaskbarPresent:true\n" +
-                "\tisTaskbarPresentInApps:true\n" +
-                "\ttaskbarSize: 158.0px (60.190475dp)\n" +
-                "\tdesiredWorkspaceHorizontalMarginPx: 58.0px (22.095238dp)\n" +
-                "\tworkspacePadding.left: 37.0px (14.095238dp)\n" +
-                "\tworkspacePadding.top: 68.0px (25.904762dp)\n" +
-                "\tworkspacePadding.right: 37.0px (14.095238dp)\n" +
-                "\tworkspacePadding.bottom: 615.0px (234.28572dp)\n" +
-                "\ticonScale: 0.9978308px (0.38012603dp)\n" +
-                "\tcellScaleToFit : 0.9978308px (0.38012603dp)\n" +
-                "\textraSpace: 235.0px (89.52381dp)\n" +
-                "\tunscaled extraSpace: 235.51086px (89.71842dp)\n" +
-                "\tmaxEmptySpace: 236.0px (89.90476dp)\n" +
-                "\tworkspaceTopPadding: 89.0px (33.904762dp)\n" +
-                "\tworkspaceBottomPadding: 146.0px (55.61905dp)\n" +
-                "\toverviewTaskMarginPx: 32.0px (12.190476dp)\n" +
-                "\toverviewTaskIconSizePx: 126.0px (48.0dp)\n" +
-                "\toverviewTaskIconDrawableSizePx: 116.0px (44.190475dp)\n" +
-                "\toverviewTaskIconDrawableSizeGridPx: 116.0px (44.190475dp)\n" +
-                "\toverviewTaskThumbnailTopMarginPx: 158.0px (60.190475dp)\n" +
-                "\toverviewActionsTopMarginPx: 63.0px (24.0dp)\n" +
-                "\toverviewActionsHeight: 126.0px (48.0dp)\n" +
-                "\toverviewActionsButtonSpacing: 95.0px (36.190475dp)\n" +
-                "\toverviewPageSpacing: 95.0px (36.190475dp)\n" +
-                "\toverviewRowSpacing: 74.0px (28.190475dp)\n" +
-                "\toverviewGridSideMargin: 168.0px (64.0dp)\n" +
-                "\tdropTargetBarTopMarginPx: 168.0px (64.0dp)\n" +
-                "\tdropTargetBarSizePx: 147.0px (56.0dp)\n" +
-                "\tdropTargetBarBottomMarginPx: 42.0px (16.0dp)\n" +
-                "\tgetCellLayoutSpringLoadShrunkTop(): 467.0px (177.90475dp)\n" +
-                "\tgetCellLayoutSpringLoadShrunkBottom(): 1578.0px (601.1429dp)\n" +
-                "\tworkspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)\n" +
-                "\tgetWorkspaceSpringLoadScale(): 0.785159px (0.29910818dp)\n" +
-                "\tgetCellLayoutHeight(): 1415.0px (539.0476dp)\n" +
-                "\tgetCellLayoutWidth(): 883.0px (336.38095dp)\n")
-    }
-
-    @Test
-    fun twoPanelPortrait() {
-        initializeVarsForTwoPanel()
-        val dp = newDP()
-        dp.isTaskbarPresentInApps = true
-
-        assertThat(dump(dp)).isEqualTo("DeviceProfile:\n" +
-                "\t1 dp = 2.625 px\n" +
-                "\tisTablet:true\n" +
-                "\tisPhone:false\n" +
-                "\ttransposeLayoutWithOrientation:false\n" +
-                "\tisGestureMode:true\n" +
-                "\tisLandscape:false\n" +
-                "\tisMultiWindowMode:false\n" +
-                "\tisTwoPanels:true\n" +
-                "\twindowX: 0.0px (0.0dp)\n" +
-                "\twindowY: 0.0px (0.0dp)\n" +
-                "\twidthPx: 1840.0px (700.9524dp)\n" +
-                "\theightPx: 2208.0px (841.1429dp)\n" +
-                "\tavailableWidthPx: 1840.0px (700.9524dp)\n" +
-                "\tavailableHeightPx: 2098.0px (799.2381dp)\n" +
-                "\tmInsets.left: 0.0px (0.0dp)\n" +
-                "\tmInsets.top: 110.0px (41.904762dp)\n" +
-                "\tmInsets.right: 0.0px (0.0dp)\n" +
-                "\tmInsets.bottom: 0.0px (0.0dp)\n" +
-                "\taspectRatio:1.2\n" +
-                "\tisScalableGrid:true\n" +
-                "\tinv.numRows: 4\n" +
-                "\tinv.numColumns: 4\n" +
-                "\tinv.numSearchContainerColumns: 4\n" +
-                "\tminCellSize: PointF(68.0, 116.0)dp\n" +
-                "\tcellWidthPx: 178.0px (67.809525dp)\n" +
-                "\tcellHeightPx: 304.0px (115.809525dp)\n" +
-                "\tgetCellSize().x: 178.0px (67.809525dp)\n" +
-                "\tgetCellSize().y: 304.0px (115.809525dp)\n" +
-                "\tcellLayoutBorderSpacePx Horizontal: 42.0px (16.0dp)\n" +
-                "\tcellLayoutBorderSpacePx Vertical: 52.0px (19.809525dp)\n" +
-                "\tcellLayoutPaddingPx.left: 21.0px (8.0dp)\n" +
-                "\tcellLayoutPaddingPx.top: 21.0px (8.0dp)\n" +
-                "\tcellLayoutPaddingPx.right: 21.0px (8.0dp)\n" +
-                "\tcellLayoutPaddingPx.bottom: 21.0px (8.0dp)\n" +
-                "\ticonSizePx: 136.0px (51.809525dp)\n" +
-                "\ticonTextSizePx: 31.0px (11.809524dp)\n" +
-                "\ticonDrawablePaddingPx: 17.0px (6.4761906dp)\n" +
-                "\tfolderCellWidthPx: 210.0px (80.0dp)\n" +
-                "\tfolderCellHeightPx: 247.0px (94.09524dp)\n" +
-                "\tfolderChildIconSizePx: 158.0px (60.190475dp)\n" +
-                "\tfolderChildTextSizePx: 37.0px (14.095238dp)\n" +
-                "\tfolderChildDrawablePaddingPx: 13.0px (4.952381dp)\n" +
-                "\tfolderCellLayoutBorderSpacePx Horizontal: 42.0px (16.0dp)\n" +
-                "\tfolderCellLayoutBorderSpacePx Vertical: 42.0px (16.0dp)\n" +
-                "\tfolderContentPaddingLeftRight: 42.0px (16.0dp)\n" +
-                "\tfolderTopPadding: 63.0px (24.0dp)\n" +
-                "\tbottomSheetTopPadding: 110.0px (41.904762dp)\n" +
-                "\tallAppsShiftRange: 2098.0px (799.2381dp)\n" +
-                "\tallAppsTopPadding: 110.0px (41.904762dp)\n" +
-                "\tallAppsIconSizePx: 136.0px (51.809525dp)\n" +
-                "\tallAppsIconTextSizePx: 31.0px (11.809524dp)\n" +
-                "\tallAppsIconDrawablePaddingPx: 18.0px (6.857143dp)\n" +
-                "\tallAppsCellHeightPx: 345.0px (131.42857dp)\n" +
-                "\tallAppsCellWidthPx: 178.0px (67.809525dp)\n" +
-                "\tallAppsBorderSpacePxX: 42.0px (16.0dp)\n" +
-                "\tallAppsBorderSpacePxY: 73.0px (27.809525dp)\n" +
-                "\tnumShownAllAppsColumns: 6\n" +
-                "\tallAppsLeftRightPadding: 126.0px (48.0dp)\n" +
-                "\tallAppsLeftRightMargin: 155.0px (59.04762dp)\n" +
-                "\thotseatBarSizePx: 459.0px (174.85715dp)\n" +
-                "\tinv.hotseatColumnSpan: 6\n" +
-                "\thotseatCellHeightPx: 153.0px (58.285713dp)\n" +
-                "\thotseatBarBottomSpacePx: 95.0px (36.190475dp)\n" +
-                "\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
-                "\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
-                "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
-                "\thotseatQsbSpace: 95.0px (36.190475dp)\n" +
-                "\thotseatQsbHeight: 165.0px (62.857143dp)\n" +
-                "\tspringLoadedHotseatBarTopMarginPx: 171.0px (65.14286dp)\n" +
-                "\tgetHotseatLayoutPadding(context).top: 219.0px (83.42857dp)\n" +
-                "\tgetHotseatLayoutPadding(context).bottom: 87.0px (33.142857dp)\n" +
-                "\tgetHotseatLayoutPadding(context).left: 302.0px (115.04762dp)\n" +
-                "\tgetHotseatLayoutPadding(context).right: 302.0px (115.04762dp)\n" +
-                "\tnumShownHotseatIcons: 6\n" +
-                "\thotseatBorderSpace: 84.0px (32.0dp)\n" +
-                "\tisQsbInline: false\n" +
-                "\thotseatQsbWidth: 1236.0px (470.85715dp)\n" +
-                "\tisTaskbarPresent:true\n" +
-                "\tisTaskbarPresentInApps:true\n" +
-                "\ttaskbarSize: 158.0px (60.190475dp)\n" +
-                "\tdesiredWorkspaceHorizontalMarginPx: 58.0px (22.095238dp)\n" +
-                "\tworkspacePadding.left: 37.0px (14.095238dp)\n" +
-                "\tworkspacePadding.top: 68.0px (25.904762dp)\n" +
-                "\tworkspacePadding.right: 37.0px (14.095238dp)\n" +
-                "\tworkspacePadding.bottom: 615.0px (234.28572dp)\n" +
-                "\ticonScale: 0.9978308px (0.38012603dp)\n" +
-                "\tcellScaleToFit : 0.9978308px (0.38012603dp)\n" +
-                "\textraSpace: 235.0px (89.52381dp)\n" +
-                "\tunscaled extraSpace: 235.51086px (89.71842dp)\n" +
-                "\tmaxEmptySpace: 236.0px (89.90476dp)\n" +
-                "\tworkspaceTopPadding: 89.0px (33.904762dp)\n" +
-                "\tworkspaceBottomPadding: 146.0px (55.61905dp)\n" +
-                "\toverviewTaskMarginPx: 32.0px (12.190476dp)\n" +
-                "\toverviewTaskIconSizePx: 126.0px (48.0dp)\n" +
-                "\toverviewTaskIconDrawableSizePx: 116.0px (44.190475dp)\n" +
-                "\toverviewTaskIconDrawableSizeGridPx: 116.0px (44.190475dp)\n" +
-                "\toverviewTaskThumbnailTopMarginPx: 158.0px (60.190475dp)\n" +
-                "\toverviewActionsTopMarginPx: 63.0px (24.0dp)\n" +
-                "\toverviewActionsHeight: 126.0px (48.0dp)\n" +
-                "\toverviewActionsButtonSpacing: 95.0px (36.190475dp)\n" +
-                "\toverviewPageSpacing: 95.0px (36.190475dp)\n" +
-                "\toverviewRowSpacing: 74.0px (28.190475dp)\n" +
-                "\toverviewGridSideMargin: 168.0px (64.0dp)\n" +
-                "\tdropTargetBarTopMarginPx: 168.0px (64.0dp)\n" +
-                "\tdropTargetBarSizePx: 147.0px (56.0dp)\n" +
-                "\tdropTargetBarBottomMarginPx: 42.0px (16.0dp)\n" +
-                "\tgetCellLayoutSpringLoadShrunkTop(): 467.0px (177.90475dp)\n" +
-                "\tgetCellLayoutSpringLoadShrunkBottom(): 1578.0px (601.1429dp)\n" +
-                "\tworkspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)\n" +
-                "\tgetWorkspaceSpringLoadScale(): 0.785159px (0.29910818dp)\n" +
-                "\tgetCellLayoutHeight(): 1415.0px (539.0476dp)\n" +
-                "\tgetCellLayoutWidth(): 883.0px (336.38095dp)\n")
-    }
-
-    @Test
-    fun phoneVerticalBar3Button() {
-        initializeVarsForPhone(isVerticalBar = true, isGestureMode = false)
-        val dp = newDP()
-
-        assertThat(dump(dp)).isEqualTo("DeviceProfile:\n" +
-                "\t1 dp = 2.625 px\n" +
-                "\tisTablet:false\n" +
-                "\tisPhone:true\n" +
-                "\ttransposeLayoutWithOrientation:true\n" +
-                "\tisGestureMode:false\n" +
-                "\tisLandscape:true\n" +
-                "\tisMultiWindowMode:false\n" +
-                "\tisTwoPanels:false\n" +
-                "\twindowX: 0.0px (0.0dp)\n" +
-                "\twindowY: 0.0px (0.0dp)\n" +
-                "\twidthPx: 2400.0px (914.2857dp)\n" +
-                "\theightPx: 1080.0px (411.42856dp)\n" +
-                "\tavailableWidthPx: 2156.0px (821.3333dp)\n" +
-                "\tavailableHeightPx: 1006.0px (383.2381dp)\n" +
-                "\tmInsets.left: 118.0px (44.95238dp)\n" +
-                "\tmInsets.top: 74.0px (28.190475dp)\n" +
-                "\tmInsets.right: 126.0px (48.0dp)\n" +
-                "\tmInsets.bottom: 0.0px (0.0dp)\n" +
-                "\taspectRatio:2.2222223\n" +
-                "\tisScalableGrid:false\n" +
-                "\tinv.numRows: 5\n" +
-                "\tinv.numColumns: 4\n" +
-                "\tinv.numSearchContainerColumns: 4\n" +
-                "\tminCellSize: PointF(80.0, 104.0)dp\n" +
-                "\tcellWidthPx: 153.0px (58.285713dp)\n" +
-                "\tcellHeightPx: 160.0px (60.95238dp)\n" +
-                "\tgetCellSize().x: 461.0px (175.61905dp)\n" +
-                "\tgetCellSize().y: 193.0px (73.52381dp)\n" +
-                "\tcellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)\n" +
-                "\tcellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)\n" +
-                "\tcellLayoutPaddingPx.left: 53.0px (20.190475dp)\n" +
-                "\tcellLayoutPaddingPx.top: 0.0px (0.0dp)\n" +
-                "\tcellLayoutPaddingPx.right: 53.0px (20.190475dp)\n" +
-                "\tcellLayoutPaddingPx.bottom: 40.0px (15.238095dp)\n" +
-                "\ticonSizePx: 142.0px (54.095238dp)\n" +
-                "\ticonTextSizePx: 0.0px (0.0dp)\n" +
-                "\ticonDrawablePaddingPx: 0.0px (0.0dp)\n" +
-                "\tfolderCellWidthPx: 175.0px (66.666664dp)\n" +
-                "\tfolderCellHeightPx: 205.0px (78.09524dp)\n" +
-                "\tfolderChildIconSizePx: 131.0px (49.904762dp)\n" +
-                "\tfolderChildTextSizePx: 34.0px (12.952381dp)\n" +
-                "\tfolderChildDrawablePaddingPx: 9.0px (3.4285715dp)\n" +
-                "\tfolderCellLayoutBorderSpacePx Horizontal: 42.0px (16.0dp)\n" +
-                "\tfolderCellLayoutBorderSpacePx Vertical: 42.0px (16.0dp)\n" +
-                "\tfolderContentPaddingLeftRight: 21.0px (8.0dp)\n" +
-                "\tfolderTopPadding: 42.0px (16.0dp)\n" +
-                "\tbottomSheetTopPadding: 114.0px (43.42857dp)\n" +
-                "\tallAppsShiftRange: 788.0px (300.1905dp)\n" +
-                "\tallAppsTopPadding: 0.0px (0.0dp)\n" +
-                "\tallAppsIconSizePx: 158.0px (60.190475dp)\n" +
-                "\tallAppsIconTextSizePx: 37.0px (14.095238dp)\n" +
-                "\tallAppsIconDrawablePaddingPx: 21.0px (8.0dp)\n" +
-                "\tallAppsCellHeightPx: 329.0px (125.333336dp)\n" +
-                "\tallAppsCellWidthPx: 200.0px (76.190475dp)\n" +
-                "\tallAppsBorderSpacePxX: 42.0px (16.0dp)\n" +
-                "\tallAppsBorderSpacePxY: 42.0px (16.0dp)\n" +
-                "\tnumShownAllAppsColumns: 4\n" +
-                "\tallAppsLeftRightPadding: 0.0px (0.0dp)\n" +
-                "\tallAppsLeftRightMargin: 0.0px (0.0dp)\n" +
-                "\thotseatBarSizePx: 247.0px (94.09524dp)\n" +
-                "\tinv.hotseatColumnSpan: 4\n" +
-                "\thotseatCellHeightPx: 160.0px (60.95238dp)\n" +
-                "\thotseatBarBottomSpacePx: 126.0px (48.0dp)\n" +
-                "\thotseatBarSidePaddingStartPx: 63.0px (24.0dp)\n" +
-                "\thotseatBarSidePaddingEndPx: 42.0px (16.0dp)\n" +
-                "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
-                "\thotseatQsbSpace: 95.0px (36.190475dp)\n" +
-                "\thotseatQsbHeight: 165.0px (62.857143dp)\n" +
-                "\tspringLoadedHotseatBarTopMarginPx: 118.0px (44.95238dp)\n" +
-                "\tgetHotseatLayoutPadding(context).top: 65.0px (24.761906dp)\n" +
-                "\tgetHotseatLayoutPadding(context).bottom: 48.0px (18.285715dp)\n" +
-                "\tgetHotseatLayoutPadding(context).left: 42.0px (16.0dp)\n" +
-                "\tgetHotseatLayoutPadding(context).right: 189.0px (72.0dp)\n" +
-                "\tnumShownHotseatIcons: 4\n" +
-                "\thotseatBorderSpace: 0.0px (0.0dp)\n" +
-                "\tisQsbInline: false\n" +
-                "\thotseatQsbWidth: 1525.0px (580.9524dp)\n" +
-                "\tisTaskbarPresent:false\n" +
-                "\tisTaskbarPresentInApps:false\n" +
-                "\ttaskbarSize: 0.0px (0.0dp)\n" +
-                "\tdesiredWorkspaceHorizontalMarginPx: 0.0px (0.0dp)\n" +
-                "\tworkspacePadding.left: 10.0px (3.8095238dp)\n" +
-                "\tworkspacePadding.top: 0.0px (0.0dp)\n" +
-                "\tworkspacePadding.right: 194.0px (73.90476dp)\n" +
-                "\tworkspacePadding.bottom: 0.0px (0.0dp)\n" +
-                "\ticonScale: 1.0px (0.3809524dp)\n" +
-                "\tcellScaleToFit : 1.0px (0.3809524dp)\n" +
-                "\textraSpace: 166.0px (63.238094dp)\n" +
-                "\tunscaled extraSpace: 166.0px (63.238094dp)\n" +
-                "\tmaxEmptySpace: 184.0px (70.09524dp)\n" +
-                "\tworkspaceTopPadding: 0.0px (0.0dp)\n" +
-                "\tworkspaceBottomPadding: 0.0px (0.0dp)\n" +
-                "\toverviewTaskMarginPx: 42.0px (16.0dp)\n" +
-                "\toverviewTaskIconSizePx: 126.0px (48.0dp)\n" +
-                "\toverviewTaskIconDrawableSizePx: 116.0px (44.190475dp)\n" +
-                "\toverviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)\n" +
-                "\toverviewTaskThumbnailTopMarginPx: 168.0px (64.0dp)\n" +
-                "\toverviewActionsTopMarginPx: 32.0px (12.190476dp)\n" +
-                "\toverviewActionsHeight: 126.0px (48.0dp)\n" +
-                "\toverviewActionsButtonSpacing: 95.0px (36.190475dp)\n" +
-                "\toverviewPageSpacing: 42.0px (16.0dp)\n" +
-                "\toverviewRowSpacing: 0.0px (0.0dp)\n" +
-                "\toverviewGridSideMargin: 0.0px (0.0dp)\n" +
-                "\tdropTargetBarTopMarginPx: 16.0px (6.095238dp)\n" +
-                "\tdropTargetBarSizePx: 95.0px (36.190475dp)\n" +
-                "\tdropTargetBarBottomMarginPx: 16.0px (6.095238dp)\n" +
-                "\tgetCellLayoutSpringLoadShrunkTop(): 201.0px (76.57143dp)\n" +
-                "\tgetCellLayoutSpringLoadShrunkBottom(): 983.0px (374.4762dp)\n" +
-                "\tworkspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)\n" +
-                "\tgetWorkspaceSpringLoadScale(): 0.777336px (0.296128dp)\n" +
-                "\tgetCellLayoutHeight(): 1006.0px (383.2381dp)\n" +
-                "\tgetCellLayoutWidth(): 1952.0px (743.619dp)\n")
-    }
-
-    @Test
-    fun phoneVerticalBar() {
-        initializeVarsForPhone(isVerticalBar = true)
-        val dp = newDP()
-
-        assertThat(dump(dp)).isEqualTo("DeviceProfile:\n" +
-                "\t1 dp = 2.625 px\n" +
-                "\tisTablet:false\n" +
-                "\tisPhone:true\n" +
-                "\ttransposeLayoutWithOrientation:true\n" +
-                "\tisGestureMode:true\n" +
-                "\tisLandscape:true\n" +
-                "\tisMultiWindowMode:false\n" +
-                "\tisTwoPanels:false\n" +
-                "\twindowX: 0.0px (0.0dp)\n" +
-                "\twindowY: 0.0px (0.0dp)\n" +
-                "\twidthPx: 2400.0px (914.2857dp)\n" +
-                "\theightPx: 1080.0px (411.42856dp)\n" +
-                "\tavailableWidthPx: 2282.0px (869.3333dp)\n" +
-                "\tavailableHeightPx: 943.0px (359.2381dp)\n" +
-                "\tmInsets.left: 118.0px (44.95238dp)\n" +
-                "\tmInsets.top: 74.0px (28.190475dp)\n" +
-                "\tmInsets.right: 0.0px (0.0dp)\n" +
-                "\tmInsets.bottom: 63.0px (24.0dp)\n" +
-                "\taspectRatio:2.2222223\n" +
-                "\tisScalableGrid:false\n" +
-                "\tinv.numRows: 5\n" +
-                "\tinv.numColumns: 4\n" +
-                "\tinv.numSearchContainerColumns: 4\n" +
-                "\tminCellSize: PointF(80.0, 104.0)dp\n" +
-                "\tcellWidthPx: 153.0px (58.285713dp)\n" +
-                "\tcellHeightPx: 160.0px (60.95238dp)\n" +
-                "\tgetCellSize().x: 493.0px (187.80952dp)\n" +
-                "\tgetCellSize().y: 180.0px (68.57143dp)\n" +
-                "\tcellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)\n" +
-                "\tcellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)\n" +
-                "\tcellLayoutPaddingPx.left: 53.0px (20.190475dp)\n" +
-                "\tcellLayoutPaddingPx.top: 0.0px (0.0dp)\n" +
-                "\tcellLayoutPaddingPx.right: 53.0px (20.190475dp)\n" +
-                "\tcellLayoutPaddingPx.bottom: 40.0px (15.238095dp)\n" +
-                "\ticonSizePx: 142.0px (54.095238dp)\n" +
-                "\ticonTextSizePx: 0.0px (0.0dp)\n" +
-                "\ticonDrawablePaddingPx: 0.0px (0.0dp)\n" +
-                "\tfolderCellWidthPx: 159.0px (60.57143dp)\n" +
-                "\tfolderCellHeightPx: 187.0px (71.2381dp)\n" +
-                "\tfolderChildIconSizePx: 119.0px (45.333332dp)\n" +
-                "\tfolderChildTextSizePx: 31.0px (11.809524dp)\n" +
-                "\tfolderChildDrawablePaddingPx: 8.0px (3.047619dp)\n" +
-                "\tfolderCellLayoutBorderSpacePx Horizontal: 42.0px (16.0dp)\n" +
-                "\tfolderCellLayoutBorderSpacePx Vertical: 42.0px (16.0dp)\n" +
-                "\tfolderContentPaddingLeftRight: 21.0px (8.0dp)\n" +
-                "\tfolderTopPadding: 42.0px (16.0dp)\n" +
-                "\tbottomSheetTopPadding: 114.0px (43.42857dp)\n" +
-                "\tallAppsShiftRange: 788.0px (300.1905dp)\n" +
-                "\tallAppsTopPadding: 0.0px (0.0dp)\n" +
-                "\tallAppsIconSizePx: 158.0px (60.190475dp)\n" +
-                "\tallAppsIconTextSizePx: 37.0px (14.095238dp)\n" +
-                "\tallAppsIconDrawablePaddingPx: 21.0px (8.0dp)\n" +
-                "\tallAppsCellHeightPx: 329.0px (125.333336dp)\n" +
-                "\tallAppsCellWidthPx: 200.0px (76.190475dp)\n" +
-                "\tallAppsBorderSpacePxX: 42.0px (16.0dp)\n" +
-                "\tallAppsBorderSpacePxY: 42.0px (16.0dp)\n" +
-                "\tnumShownAllAppsColumns: 4\n" +
-                "\tallAppsLeftRightPadding: 0.0px (0.0dp)\n" +
-                "\tallAppsLeftRightMargin: 0.0px (0.0dp)\n" +
-                "\thotseatBarSizePx: 247.0px (94.09524dp)\n" +
-                "\tinv.hotseatColumnSpan: 4\n" +
-                "\thotseatCellHeightPx: 160.0px (60.95238dp)\n" +
-                "\thotseatBarBottomSpacePx: 126.0px (48.0dp)\n" +
-                "\thotseatBarSidePaddingStartPx: 63.0px (24.0dp)\n" +
-                "\thotseatBarSidePaddingEndPx: 42.0px (16.0dp)\n" +
-                "\thotseatBarEndOffset: 0.0px (0.0dp)\n" +
-                "\thotseatQsbSpace: 95.0px (36.190475dp)\n" +
-                "\thotseatQsbHeight: 165.0px (62.857143dp)\n" +
-                "\tspringLoadedHotseatBarTopMarginPx: 118.0px (44.95238dp)\n" +
-                "\tgetHotseatLayoutPadding(context).top: 65.0px (24.761906dp)\n" +
-                "\tgetHotseatLayoutPadding(context).bottom: 111.0px (42.285713dp)\n" +
-                "\tgetHotseatLayoutPadding(context).left: 42.0px (16.0dp)\n" +
-                "\tgetHotseatLayoutPadding(context).right: 63.0px (24.0dp)\n" +
-                "\tnumShownHotseatIcons: 4\n" +
-                "\thotseatBorderSpace: 0.0px (0.0dp)\n" +
-                "\tisQsbInline: false\n" +
-                "\thotseatQsbWidth: 1621.0px (617.5238dp)\n" +
-                "\tisTaskbarPresent:false\n" +
-                "\tisTaskbarPresentInApps:false\n" +
-                "\ttaskbarSize: 0.0px (0.0dp)\n" +
-                "\tdesiredWorkspaceHorizontalMarginPx: 0.0px (0.0dp)\n" +
-                "\tworkspacePadding.left: 10.0px (3.8095238dp)\n" +
-                "\tworkspacePadding.top: 0.0px (0.0dp)\n" +
-                "\tworkspacePadding.right: 194.0px (73.90476dp)\n" +
-                "\tworkspacePadding.bottom: 0.0px (0.0dp)\n" +
-                "\ticonScale: 1.0px (0.3809524dp)\n" +
-                "\tcellScaleToFit : 1.0px (0.3809524dp)\n" +
-                "\textraSpace: 103.0px (39.238094dp)\n" +
-                "\tunscaled extraSpace: 103.0px (39.238094dp)\n" +
-                "\tmaxEmptySpace: 131.0px (49.904762dp)\n" +
-                "\tworkspaceTopPadding: 0.0px (0.0dp)\n" +
-                "\tworkspaceBottomPadding: 0.0px (0.0dp)\n" +
-                "\toverviewTaskMarginPx: 42.0px (16.0dp)\n" +
-                "\toverviewTaskIconSizePx: 126.0px (48.0dp)\n" +
-                "\toverviewTaskIconDrawableSizePx: 116.0px (44.190475dp)\n" +
-                "\toverviewTaskIconDrawableSizeGridPx: 0.0px (0.0dp)\n" +
-                "\toverviewTaskThumbnailTopMarginPx: 168.0px (64.0dp)\n" +
-                "\toverviewActionsTopMarginPx: 32.0px (12.190476dp)\n" +
-                "\toverviewActionsHeight: 126.0px (48.0dp)\n" +
-                "\toverviewActionsButtonSpacing: 95.0px (36.190475dp)\n" +
-                "\toverviewPageSpacing: 42.0px (16.0dp)\n" +
-                "\toverviewRowSpacing: 0.0px (0.0dp)\n" +
-                "\toverviewGridSideMargin: 0.0px (0.0dp)\n" +
-                "\tdropTargetBarTopMarginPx: 16.0px (6.095238dp)\n" +
-                "\tdropTargetBarSizePx: 95.0px (36.190475dp)\n" +
-                "\tdropTargetBarBottomMarginPx: 16.0px (6.095238dp)\n" +
-                "\tgetCellLayoutSpringLoadShrunkTop(): 201.0px (76.57143dp)\n" +
-                "\tgetCellLayoutSpringLoadShrunkBottom(): 927.0px (353.14285dp)\n" +
-                "\tworkspaceSpringLoadedMinNextPageVisiblePx: 63.0px (24.0dp)\n" +
-                "\tgetWorkspaceSpringLoadScale(): 0.76988333px (0.2932889dp)\n" +
-                "\tgetCellLayoutHeight(): 943.0px (359.2381dp)\n" +
-                "\tgetCellLayoutWidth(): 2078.0px (791.619dp)\n")
-    }
-}
\ No newline at end of file
diff --git a/quickstep/tests/src/com/android/quickstep/OrientationTouchTransformerTest.java b/quickstep/tests/src/com/android/quickstep/OrientationTouchTransformerTest.java
index c822578..9c240f0 100644
--- a/quickstep/tests/src/com/android/quickstep/OrientationTouchTransformerTest.java
+++ b/quickstep/tests/src/com/android/quickstep/OrientationTouchTransformerTest.java
@@ -19,7 +19,7 @@
 
 import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
 
-import static com.android.launcher3.util.DisplayController.NavigationMode.NO_BUTTON;
+import static com.android.launcher3.util.NavigationMode.NO_BUTTON;
 
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
diff --git a/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java b/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java
index 4e49716..262dc37 100644
--- a/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java
+++ b/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java
@@ -70,7 +70,7 @@
 
     @Test
     public void loadTasksInBackground_onlyKeys_noValidTaskDescription() {
-        GroupedRecentTaskInfo recentTaskInfos = new GroupedRecentTaskInfo(
+        GroupedRecentTaskInfo recentTaskInfos = GroupedRecentTaskInfo.forSplitTasks(
                 new ActivityManager.RecentTaskInfo(), new ActivityManager.RecentTaskInfo(), null);
         when(mockSystemUiProxy.getRecentTasks(anyInt(), anyInt()))
                 .thenReturn(new ArrayList<>(Collections.singletonList(recentTaskInfos)));
@@ -90,8 +90,8 @@
         task1.taskDescription = new ActivityManager.TaskDescription(taskDescription);
         ActivityManager.RecentTaskInfo task2 = new ActivityManager.RecentTaskInfo();
         task2.taskDescription = new ActivityManager.TaskDescription();
-        GroupedRecentTaskInfo recentTaskInfos = new GroupedRecentTaskInfo(
-                task1, task2, null);
+        GroupedRecentTaskInfo recentTaskInfos = GroupedRecentTaskInfo.forSplitTasks(task1, task2,
+                null);
         when(mockSystemUiProxy.getRecentTasks(anyInt(), anyInt()))
                 .thenReturn(new ArrayList<>(Collections.singletonList(recentTaskInfos)));
 
diff --git a/quickstep/tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java b/quickstep/tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java
index d43aafa..190b002 100644
--- a/quickstep/tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java
+++ b/quickstep/tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java
@@ -34,6 +34,7 @@
 import com.android.launcher3.util.DisplayController;
 import com.android.launcher3.util.DisplayController.Info;
 import com.android.launcher3.util.LauncherModelHelper;
+import com.android.launcher3.util.NavigationMode;
 import com.android.launcher3.util.ReflectionHelpers;
 import com.android.launcher3.util.RotationUtils;
 import com.android.launcher3.util.WindowBounds;
@@ -164,6 +165,7 @@
                 WindowManagerProxy wmProxy = mock(WindowManagerProxy.class);
                 doReturn(cdi).when(wmProxy).getDisplayInfo(any());
                 doReturn(wm).when(wmProxy).getRealBounds(any(), any());
+                doReturn(NavigationMode.NO_BUTTON).when(wmProxy).getNavigationMode(any());
 
                 ArrayMap<CachedDisplayInfo, WindowBounds[]> perDisplayBoundsCache =
                         new ArrayMap<>();
diff --git a/res/layout/user_folder_icon_normalized.xml b/res/layout/user_folder_icon_normalized.xml
index 87bf33d..4dee6e7 100644
--- a/res/layout/user_folder_icon_normalized.xml
+++ b/res/layout/user_folder_icon_normalized.xml
@@ -34,7 +34,8 @@
         android:clipChildren="false"
         android:orientation="horizontal"
         android:paddingLeft="12dp"
-        android:paddingRight="12dp" >
+        android:paddingRight="12dp"
+        android:alpha="0">
 
         <com.android.launcher3.folder.FolderNameEditText
             android:id="@+id/folder_name"
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index a9d1127..2e886db 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -226,6 +226,7 @@
     <dimen name="drop_target_text_size">16sp</dimen>
     <dimen name="drop_target_shadow_elevation">2dp</dimen>
     <dimen name="drop_target_bar_margin_horizontal">4dp</dimen>
+    <dimen name="drop_target_button_drawable_size">20dp</dimen>
     <dimen name="drop_target_button_drawable_padding">8dp</dimen>
     <dimen name="drop_target_button_drawable_horizontal_padding">16dp</dimen>
     <dimen name="drop_target_button_drawable_vertical_padding">8dp</dimen>
diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java
index 3b24df2..5abe3d3 100644
--- a/src/com/android/launcher3/ButtonDropTarget.java
+++ b/src/com/android/launcher3/ButtonDropTarget.java
@@ -91,7 +91,7 @@
 
         Resources resources = getResources();
         mDragDistanceThreshold = resources.getDimensionPixelSize(R.dimen.drag_distanceThreshold);
-        mDrawableSize = resources.getDimensionPixelSize(R.dimen.drop_target_text_size);
+        mDrawableSize = resources.getDimensionPixelSize(R.dimen.drop_target_button_drawable_size);
         mDrawablePadding = resources.getDimensionPixelSize(
                 R.dimen.drop_target_button_drawable_padding);
     }
@@ -374,11 +374,63 @@
         hideTooltip();
     }
 
+    /**
+     * Returns if the text will be truncated within the provided availableWidth.
+     */
     public boolean isTextTruncated(int availableWidth) {
-        availableWidth -= (getPaddingLeft() + getPaddingRight() + mDrawable.getIntrinsicWidth()
-                + getCompoundDrawablePadding());
-        CharSequence displayedText = TextUtils.ellipsize(mText, getPaint(), availableWidth,
+        availableWidth -= getPaddingLeft() + getPaddingRight();
+        if (mIconVisible) {
+            availableWidth -= mDrawable.getIntrinsicWidth() + getCompoundDrawablePadding();
+        }
+        if (availableWidth <= 0) {
+            return true;
+        }
+        CharSequence firstLine = TextUtils.ellipsize(mText, getPaint(), availableWidth,
                 TextUtils.TruncateAt.END);
-        return !mText.equals(displayedText);
+        if (!mTextMultiLine) {
+            return !TextUtils.equals(mText, firstLine);
+        }
+        if (TextUtils.equals(mText, firstLine)) {
+            // When multi-line is active, if it can display as one line, then text is not truncated.
+            return false;
+        }
+        CharSequence secondLine =
+                TextUtils.ellipsize(mText.subSequence(firstLine.length(), mText.length()),
+                        getPaint(), availableWidth, TextUtils.TruncateAt.END);
+        return !(TextUtils.equals(mText.subSequence(0, firstLine.length()), firstLine)
+                && TextUtils.equals(mText.subSequence(firstLine.length(), secondLine.length()),
+                secondLine));
+    }
+
+    /**
+     * Reduce the size of the text until it fits the measured width or reaches a minimum.
+     *
+     * The minimum size is defined by {@code R.dimen.button_drop_target_min_text_size} and
+     * it diminishes by intervals defined by
+     * {@code R.dimen.button_drop_target_resize_text_increment}
+     * This functionality is very similar to the option
+     * {@link TextView#setAutoSizeTextTypeWithDefaults(int)} but can't be used in this view because
+     * the layout width is {@code WRAP_CONTENT}.
+     *
+     * @return The biggest text size in SP that makes the text fit or if the text can't fit returns
+     *         the min available value
+     */
+    public float resizeTextToFit() {
+        float minSize = Utilities.pxToSp(getResources()
+                .getDimensionPixelSize(R.dimen.button_drop_target_min_text_size));
+        float step = Utilities.pxToSp(getResources()
+                .getDimensionPixelSize(R.dimen.button_drop_target_resize_text_increment));
+        float textSize = Utilities.pxToSp(getTextSize());
+
+        int availableWidth = getMeasuredWidth();
+        while (textSize > minSize) {
+            if (isTextTruncated(availableWidth)) {
+                textSize -= step;
+                setTextSize(textSize);
+            } else {
+                return textSize;
+            }
+        }
+        return minSize;
     }
 }
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index a330fb3..0292e04 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -52,6 +52,7 @@
 
 import java.io.PrintWriter;
 import java.util.List;
+import java.util.Locale;
 
 @SuppressLint("NewApi")
 public class DeviceProfile {
@@ -1037,7 +1038,7 @@
                         / getCellLayoutHeight();
         scale = Math.min(scale, 1f);
 
-        // Reduce scale if next pages would not be visible after scaling the workspace
+        // Reduce scale if next pages would not be visible after scaling the workspace.
         int workspaceWidth = availableWidthPx;
         float scaledWorkspaceWidth = workspaceWidth * scale;
         float maxAvailableWidth = workspaceWidth - (2 * workspaceSpringLoadedMinNextPageVisiblePx);
@@ -1354,6 +1355,10 @@
         return "\t" + name + ": " + value + "px (" + dpiFromPx(value, mMetrics.densityDpi) + "dp)";
     }
 
+    private String dpPointFToString(String name, PointF value) {
+        return String.format(Locale.ENGLISH, "\t%s: PointF(%.1f, %.1f)dp", name, value.x, value.y);
+    }
+
     /** Dumps various DeviceProfile variables to the specified writer. */
     public void dump(Context context, String prefix, PrintWriter writer) {
         writer.println(prefix + "DeviceProfile:");
@@ -1389,7 +1394,7 @@
         writer.println(prefix + "\tinv.numSearchContainerColumns: "
                 + inv.numSearchContainerColumns);
 
-        writer.println(prefix + "\tminCellSize: " + inv.minCellSize[mTypeIndex] + "dp");
+        writer.println(prefix + dpPointFToString("minCellSize", inv.minCellSize[mTypeIndex]));
 
         writer.println(prefix + pxToDpStr("cellWidthPx", cellWidthPx));
         writer.println(prefix + pxToDpStr("cellHeightPx", cellHeightPx));
@@ -1669,7 +1674,7 @@
                 mTransposeLayoutWithOrientation = !mInfo.isTablet(mWindowBounds);
             }
             if (mIsGestureMode == null) {
-                mIsGestureMode = DisplayController.getNavigationMode(mContext).hasGestures;
+                mIsGestureMode = mInfo.navigationMode.hasGestures;
             }
             if (mDotRendererCache == null) {
                 mDotRendererCache = new SparseArray<>();
diff --git a/src/com/android/launcher3/DropTargetBar.java b/src/com/android/launcher3/DropTargetBar.java
index d64cb26..98ecf3a 100644
--- a/src/com/android/launcher3/DropTargetBar.java
+++ b/src/com/android/launcher3/DropTargetBar.java
@@ -151,6 +151,8 @@
             int widthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST);
 
             ButtonDropTarget firstButton = mTempTargets[0];
+            firstButton.setTextSize(TypedValue.COMPLEX_UNIT_PX,
+                    mLauncher.getDeviceProfile().dropTargetTextSizePx);
             firstButton.setTextVisible(true);
             firstButton.setIconVisible(true);
             firstButton.measure(widthSpec, heightSpec);
@@ -160,14 +162,16 @@
             int horizontalPadding = dp.dropTargetHorizontalPaddingPx;
 
             ButtonDropTarget firstButton = mTempTargets[0];
+            firstButton.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp.dropTargetTextSizePx);
             firstButton.setTextVisible(true);
             firstButton.setIconVisible(true);
             firstButton.setTextMultiLine(false);
-            // Reset second button padding in case it was previously changed to multi-line text.
+            // Reset first button padding in case it was previously changed to multi-line text.
             firstButton.setPadding(horizontalPadding, verticalPadding, horizontalPadding,
                     verticalPadding);
 
             ButtonDropTarget secondButton = mTempTargets[1];
+            secondButton.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp.dropTargetTextSizePx);
             secondButton.setTextVisible(true);
             secondButton.setIconVisible(true);
             secondButton.setTextMultiLine(false);
@@ -175,20 +179,14 @@
             secondButton.setPadding(horizontalPadding, verticalPadding, horizontalPadding,
                     verticalPadding);
 
-            float scale = dp.getWorkspaceSpringLoadScale(mLauncher);
-            int scaledPanelWidth = (int) (dp.getCellLayoutWidth() * scale);
-
             int availableWidth;
             if (dp.isTwoPanels) {
-                // Both buttons for two panel fit to the width of one Cell Layout (less
-                // half of the center gap between the buttons).
-                int halfButtonGap = dp.dropTargetGapPx / 2;
-                availableWidth = scaledPanelWidth - halfButtonGap / 2;
+                // Each button for two panel fits to half the width of the screen excluding the
+                // center gap between the buttons.
+                availableWidth = (dp.availableWidthPx - dp.dropTargetGapPx) / 2;
             } else {
-                // Both buttons plus the button gap do not display past the edge of the scaled
-                // workspace, less a pre-defined gap from the edge of the workspace.
-                availableWidth = scaledPanelWidth - dp.dropTargetGapPx
-                        - 2 * dp.dropTargetButtonWorkspaceEdgeGapPx;
+                // Both buttons plus the button gap do not display past the edge of the screen.
+                availableWidth = dp.availableWidthPx - dp.dropTargetGapPx;
             }
 
             int widthSpec = MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST);
@@ -219,6 +217,15 @@
                             horizontalPadding, verticalPadding / 2);
                 }
             }
+
+            // If text is still truncated, shrink to fit in measured width and resize both targets.
+            float minTextSize =
+                    Math.min(firstButton.resizeTextToFit(), secondButton.resizeTextToFit());
+            if (firstButton.getTextSize() != minTextSize
+                    || secondButton.getTextSize() != minTextSize) {
+                firstButton.setTextSize(minTextSize);
+                secondButton.setTextSize(minTextSize);
+            }
         }
         setMeasuredDimension(width, height);
     }
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 4a52d3e..4312c3d 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -195,7 +195,6 @@
 import com.android.launcher3.util.TouchController;
 import com.android.launcher3.util.TraceHelper;
 import com.android.launcher3.util.UiThreadHelper;
-import com.android.launcher3.util.ViewCapture;
 import com.android.launcher3.util.ViewOnDrawExecutor;
 import com.android.launcher3.views.ActivityContext;
 import com.android.launcher3.views.FloatingIconView;
@@ -393,7 +392,6 @@
     private LauncherState mPrevLauncherState;
 
     private StringCache mStringCache;
-    private ViewCapture mViewCapture;
 
     @Override
     @TargetApi(Build.VERSION_CODES.S)
@@ -1488,23 +1486,11 @@
     public void onAttachedToWindow() {
         super.onAttachedToWindow();
         mOverlayManager.onAttachedToWindow();
-        if (FeatureFlags.CONTINUOUS_VIEW_TREE_CAPTURE.get()) {
-            View root = getDragLayer().getRootView();
-            if (mViewCapture != null) {
-                mViewCapture.detach();
-            }
-            mViewCapture = new ViewCapture(getWindow());
-            mViewCapture.attach();
-        }
     }
 
     @Override
     public void onDetachedFromWindow() {
         super.onDetachedFromWindow();
-        if (mViewCapture != null) {
-            mViewCapture.detach();
-            mViewCapture = null;
-        }
         mOverlayManager.onDetachedFromWindow();
         closeContextMenu();
     }
@@ -2985,7 +2971,6 @@
      */
     @Override
     public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
-        SafeCloseable viewDump = mViewCapture == null ? null : mViewCapture.beginDump(writer, fd);
         super.dump(prefix, fd, writer, args);
 
         if (args.length > 0 && TextUtils.equals(args[0], "--all")) {
@@ -3026,10 +3011,6 @@
         mPopupDataProvider.dump(prefix, writer);
         mDeviceProfile.dump(this, prefix, writer);
 
-        if (viewDump != null) {
-            viewDump.close();
-        }
-
         try {
             FileLog.flushAll(writer);
         } catch (Exception e) {
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index ff40712..a643196 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -65,12 +65,12 @@
      */
     public static final BooleanFlag ENABLE_INPUT_CONSUMER_REASON_LOGGING = getDebugFlag(
             "ENABLE_INPUT_CONSUMER_REASON_LOGGING",
-            false,
+            true,
             "Log the reason why an Input Consumer was selected for a gesture.");
 
     public static final BooleanFlag ENABLE_GESTURE_ERROR_DETECTION = getDebugFlag(
             "ENABLE_GESTURE_ERROR_DETECTION",
-            false,
+            true,
             "Analyze gesture events and log detected errors");
 
     // When enabled the promise icon is visible in all apps while installation an app.
@@ -285,6 +285,9 @@
             "FOLDABLE_WORKSPACE_REORDER", true,
             "In foldables, when reordering the icons and widgets, is now going to use both sides");
 
+    public static final BooleanFlag SHOW_SEARCH_EDUCARD_QSB = new DeviceFlag(
+            "SHOW_SEARCH_EDUCARD_QSB", false, "Shows Search Educard for QSB entry in OneSearch.");
+
     public static void initialize(Context context) {
         synchronized (sDebugFlags) {
             for (DebugFlag flag : sDebugFlags) {
diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
index 33b2f55..a55f7e3 100644
--- a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
+++ b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
@@ -73,11 +73,11 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         mModel = LauncherAppState.getInstance(this).getModel();
+        mOnboardingPrefs = new OnboardingPrefs<>(this, Utilities.getPrefs(this));
+        mSecondaryDisplayPredictions = SecondaryDisplayPredictions.newInstance(this);
         if (getWindow().getDecorView().isAttachedToWindow()) {
             initUi();
         }
-        mOnboardingPrefs = new OnboardingPrefs<>(this, Utilities.getPrefs(this));
-        mSecondaryDisplayPredictions = SecondaryDisplayPredictions.newInstance(this);
     }
 
     @Override
diff --git a/src/com/android/launcher3/testing/shared/ResourceUtils.java b/src/com/android/launcher3/testing/shared/ResourceUtils.java
index 551aeaf..d0ae258 100644
--- a/src/com/android/launcher3/testing/shared/ResourceUtils.java
+++ b/src/com/android/launcher3/testing/shared/ResourceUtils.java
@@ -36,6 +36,8 @@
     public static final String STATUS_BAR_HEIGHT_LANDSCAPE = "status_bar_height_landscape";
     public static final String STATUS_BAR_HEIGHT_PORTRAIT = "status_bar_height_portrait";
 
+    public static final String NAV_BAR_INTERACTION_MODE_RES_NAME = "config_navBarInteractionMode";
+
     public static int getNavbarSize(String resName, Resources res) {
         return getDimenByName(resName, res, DEFAULT_NAVBAR_VALUE);
     }
diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
index dd9f642..07d1839 100644
--- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
+++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
@@ -27,7 +27,7 @@
 import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;
 import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
 import static com.android.launcher3.touch.SingleAxisSwipeDetector.VERTICAL;
-import static com.android.launcher3.util.DisplayController.NavigationMode.THREE_BUTTONS;
+import static com.android.launcher3.util.NavigationMode.THREE_BUTTONS;
 import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
 import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
 
diff --git a/src/com/android/launcher3/util/DisplayController.java b/src/com/android/launcher3/util/DisplayController.java
index 94f9f25..e57c88d 100644
--- a/src/com/android/launcher3/util/DisplayController.java
+++ b/src/com/android/launcher3/util/DisplayController.java
@@ -19,11 +19,7 @@
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 
-import static com.android.launcher3.testing.shared.ResourceUtils.INVALID_RESOURCE_HANDLE;
 import static com.android.launcher3.Utilities.dpiFromPx;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NAVIGATION_MODE_2_BUTTON;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NAVIGATION_MODE_3_BUTTON;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NAVIGATION_MODE_GESTURE_BUTTON;
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
 import static com.android.launcher3.util.PackageManagerHelper.getPackageFilter;
 import static com.android.launcher3.util.window.WindowManagerProxy.MIN_TABLET_WIDTH;
@@ -46,9 +42,7 @@
 import androidx.annotation.AnyThread;
 import androidx.annotation.UiThread;
 
-import com.android.launcher3.testing.shared.ResourceUtils;
 import com.android.launcher3.Utilities;
-import com.android.launcher3.logging.StatsLogManager.LauncherEvent;
 import com.android.launcher3.util.window.CachedDisplayInfo;
 import com.android.launcher3.util.window.WindowManagerProxy;
 
@@ -56,6 +50,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 
@@ -81,7 +76,6 @@
             | CHANGE_DENSITY | CHANGE_SUPPORTED_BOUNDS | CHANGE_NAVIGATION_MODE;
 
     private static final String ACTION_OVERLAY_CHANGED = "android.intent.action.OVERLAY_CHANGED";
-    private static final String NAV_BAR_INTERACTION_MODE_RES_NAME = "config_navBarInteractionMode";
     private static final String TARGET_OVERLAY_PACKAGE = "android";
 
     private final Context mContext;
@@ -294,7 +288,7 @@
         // Used for testing
         public Info(Context displayInfoContext,
                 WindowManagerProxy wmProxy,
-                ArrayMap<CachedDisplayInfo, WindowBounds[]> perDisplayBoundsCache) {
+                Map<CachedDisplayInfo, WindowBounds[]> perDisplayBoundsCache) {
             CachedDisplayInfo displayInfo = wmProxy.getDisplayInfo(displayInfoContext);
             normalizedDisplayInfo = displayInfo.normalize();
             rotation = displayInfo.rotation;
@@ -305,7 +299,7 @@
             fontScale = config.fontScale;
             densityDpi = config.densityDpi;
             mScreenSizeDp = new PortraitSize(config.screenHeightDp, config.screenWidthDp);
-            navigationMode = parseNavigationMode(displayInfoContext);
+            navigationMode = wmProxy.getNavigationMode(displayInfoContext);
 
             mPerDisplayBounds.putAll(perDisplayBoundsCache);
             WindowBounds[] cachedValue = mPerDisplayBounds.get(normalizedDisplayInfo);
@@ -405,35 +399,4 @@
         }
     }
 
-    public enum NavigationMode {
-        THREE_BUTTONS(false, 0, LAUNCHER_NAVIGATION_MODE_3_BUTTON),
-        TWO_BUTTONS(true, 1, LAUNCHER_NAVIGATION_MODE_2_BUTTON),
-        NO_BUTTON(true, 2, LAUNCHER_NAVIGATION_MODE_GESTURE_BUTTON);
-
-        public final boolean hasGestures;
-        public final int resValue;
-        public final LauncherEvent launcherEvent;
-
-        NavigationMode(boolean hasGestures, int resValue, LauncherEvent launcherEvent) {
-            this.hasGestures = hasGestures;
-            this.resValue = resValue;
-            this.launcherEvent = launcherEvent;
-        }
-    }
-
-    private static NavigationMode parseNavigationMode(Context context) {
-        int modeInt = ResourceUtils.getIntegerByName(NAV_BAR_INTERACTION_MODE_RES_NAME,
-                context.getResources(), INVALID_RESOURCE_HANDLE);
-
-        if (modeInt == INVALID_RESOURCE_HANDLE) {
-            Log.e(TAG, "Failed to get system resource ID. Incompatible framework version?");
-        } else {
-            for (NavigationMode m : NavigationMode.values()) {
-                if (m.resValue == modeInt) {
-                    return m;
-                }
-            }
-        }
-        return Utilities.ATLEAST_S ? NavigationMode.NO_BUTTON : NavigationMode.THREE_BUTTONS;
-    }
 }
diff --git a/src/com/android/launcher3/util/NavigationMode.java b/src/com/android/launcher3/util/NavigationMode.java
new file mode 100644
index 0000000..37dd41c
--- /dev/null
+++ b/src/com/android/launcher3/util/NavigationMode.java
@@ -0,0 +1,42 @@
+/*
+ * 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;
+
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NAVIGATION_MODE_2_BUTTON;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NAVIGATION_MODE_3_BUTTON;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NAVIGATION_MODE_GESTURE_BUTTON;
+
+import com.android.launcher3.logging.StatsLogManager;
+
+/**
+ * Navigation mode used in the device.
+ */
+public enum NavigationMode {
+    THREE_BUTTONS(false, 0, LAUNCHER_NAVIGATION_MODE_3_BUTTON),
+    TWO_BUTTONS(true, 1, LAUNCHER_NAVIGATION_MODE_2_BUTTON),
+    NO_BUTTON(true, 2, LAUNCHER_NAVIGATION_MODE_GESTURE_BUTTON);
+
+    public final boolean hasGestures;
+    public final int resValue;
+    public final StatsLogManager.LauncherEvent launcherEvent;
+
+    NavigationMode(boolean hasGestures, int resValue, StatsLogManager.LauncherEvent launcherEvent) {
+        this.hasGestures = hasGestures;
+        this.resValue = resValue;
+        this.launcherEvent = launcherEvent;
+    }
+}
diff --git a/src/com/android/launcher3/util/ViewCapture.java b/src/com/android/launcher3/util/ViewCapture.java
index e368ac3..0cf3ad7 100644
--- a/src/com/android/launcher3/util/ViewCapture.java
+++ b/src/com/android/launcher3/util/ViewCapture.java
@@ -17,18 +17,25 @@
 
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
 import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+import static com.android.launcher3.util.Executors.createAndStartNewLooper;
 
 import static java.util.stream.Collectors.toList;
 
+import android.content.Context;
 import android.content.res.Resources;
 import android.os.Handler;
+import android.os.Looper;
 import android.os.Message;
+import android.os.Process;
 import android.os.Trace;
 import android.text.TextUtils;
 import android.util.Base64;
 import android.util.Base64OutputStream;
 import android.util.Log;
+import android.util.Pair;
+import android.util.SparseArray;
 import android.view.View;
+import android.view.View.OnAttachStateChangeListener;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver.OnDrawListener;
 import android.view.Window;
@@ -36,6 +43,7 @@
 import androidx.annotation.UiThread;
 import androidx.annotation.WorkerThread;
 
+import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.view.ViewCaptureData.ExportedData;
 import com.android.launcher3.view.ViewCaptureData.FrameData;
 import com.android.launcher3.view.ViewCaptureData.ViewNode;
@@ -45,13 +53,14 @@
 import java.io.OutputStream;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.List;
 import java.util.concurrent.Future;
 import java.util.zip.GZIPOutputStream;
 
 /**
  * Utility class for capturing view data every frame
  */
-public class ViewCapture implements OnDrawListener {
+public class ViewCapture {
 
     private static final String TAG = "ViewCapture";
 
@@ -61,104 +70,27 @@
     // Launcher. This allows the first free frames avoid object allocation during view capture.
     private static final int INIT_POOL_SIZE = 300;
 
-    private final Window mWindow;
-    private final View mRoot;
-    private final Resources mResources;
+    public static final MainThreadInitializedObject<ViewCapture> INSTANCE =
+            new MainThreadInitializedObject<>(ViewCapture::new);
 
-    private final Handler mHandler;
-    private final ViewRef mViewRef = new ViewRef();
+    private final List<WindowListener> mListeners = new ArrayList<>();
 
-    private int mFrameIndexBg = -1;
-    private final long[] mFrameTimesBg = new long[MEMORY_SIZE];
-    private final ViewPropertyRef[] mNodesBg = new ViewPropertyRef[MEMORY_SIZE];
+    private final Context mContext;
+    private final LooperExecutor mExecutor;
 
     // Pool used for capturing view tree on the UI thread.
     private ViewRef mPool = new ViewRef();
 
-    /**
-     * @param window the window for the capture data
-     */
-    public ViewCapture(Window window) {
-        mWindow = window;
-        mRoot = mWindow.getDecorView();
-        mResources = mRoot.getResources();
-        mHandler = new Handler(UI_HELPER_EXECUTOR.getLooper(), this::captureViewPropertiesBg);
-    }
-
-    /**
-     * Attaches the ViewCapture to the root
-     */
-    public void attach() {
-        mHandler.post(this::initPool);
-    }
-
-    /**
-     * Removes a previously attached ViewCapture from the root
-     */
-    public void detach() {
-        mHandler.post(() -> MAIN_EXECUTOR.execute(
-                () -> mRoot.getViewTreeObserver().removeOnDrawListener(this)));
-    }
-
-    @Override
-    public void onDraw() {
-        Trace.beginSection("view_capture");
-        captureViewTree(mRoot, mViewRef);
-        Message m = Message.obtain(mHandler);
-        m.obj = mViewRef.next;
-        mHandler.sendMessage(m);
-        Trace.endSection();
-    }
-
-    /**
-     * Captures the View property on the background thread, and transfer all the ViewRef objects
-     * back to the pool
-     */
-    @WorkerThread
-    private boolean captureViewPropertiesBg(Message msg) {
-        ViewRef start = (ViewRef) msg.obj;
-        long time = msg.getWhen();
-        if (start == null) {
-            return false;
+    private ViewCapture(Context context) {
+        mContext = context;
+        if (FeatureFlags.CONTINUOUS_VIEW_TREE_CAPTURE.get()) {
+            Looper looper = createAndStartNewLooper("ViewCapture",
+                    Process.THREAD_PRIORITY_FOREGROUND);
+            mExecutor = new LooperExecutor(looper);
+            mExecutor.execute(this::initPool);
+        } else {
+            mExecutor = UI_HELPER_EXECUTOR;
         }
-        mFrameIndexBg++;
-        if (mFrameIndexBg >= MEMORY_SIZE) {
-            mFrameIndexBg = 0;
-        }
-        mFrameTimesBg[mFrameIndexBg] = time;
-
-        ViewPropertyRef recycle = mNodesBg[mFrameIndexBg];
-
-        ViewPropertyRef result = null;
-        ViewPropertyRef resultEnd = null;
-
-        ViewRef current = start;
-        ViewRef last = start;
-        while (current != null) {
-            ViewPropertyRef propertyRef = recycle;
-            if (propertyRef == null) {
-                propertyRef = new ViewPropertyRef();
-            } else {
-                recycle = recycle.next;
-                propertyRef.next = null;
-            }
-
-            propertyRef.transfer(current);
-            last = current;
-            current = current.next;
-
-            if (result == null) {
-                result = propertyRef;
-                resultEnd = result;
-            } else {
-                resultEnd.next = propertyRef;
-                resultEnd = propertyRef;
-            }
-        }
-        mNodesBg[mFrameIndexBg] = result;
-        ViewRef end = last;
-        MAIN_EXECUTOR.execute(() -> addToPool(start, end));
-        return true;
     }
 
     @UiThread
@@ -177,36 +109,59 @@
             current = current.next;
         }
 
-        ViewRef end = current;
-        MAIN_EXECUTOR.execute(() ->  {
-            addToPool(start, end);
-            if (mRoot.isAttachedToWindow()) {
-                mRoot.getViewTreeObserver().addOnDrawListener(this);
-            }
-        });
-    }
-
-    private String getName() {
-        String title = mWindow.getAttributes().getTitle().toString();
-        return TextUtils.isEmpty(title) ? mWindow.toString() : title;
+        ViewRef finalCurrent = current;
+        MAIN_EXECUTOR.execute(() -> addToPool(start, finalCurrent));
     }
 
     /**
-     * Starts the dump process which is completed on closing the returned object.
+     * Attaches the ViewCapture to the provided window and returns a handle to detach the listener
      */
-    public SafeCloseable beginDump(PrintWriter writer, FileDescriptor out) {
-        Future<ExportedData> task = UI_HELPER_EXECUTOR.submit(this::dumpToProto);
+    public SafeCloseable startCapture(Window window) {
+        String title = window.getAttributes().getTitle().toString();
+        String name = TextUtils.isEmpty(title) ? window.toString() : title;
+        return startCapture(window.getDecorView(), name);
+    }
 
+    /**
+     * Attaches the ViewCapture to the provided window and returns a handle to detach the listener
+     */
+    public SafeCloseable startCapture(View view, String name) {
+        if (!FeatureFlags.CONTINUOUS_VIEW_TREE_CAPTURE.get()) {
+            return () -> { };
+        }
+
+        WindowListener listener = new WindowListener(view, name);
+        mExecutor.execute(() -> MAIN_EXECUTOR.execute(listener::attachToRoot));
+        mListeners.add(listener);
         return () -> {
+            mListeners.remove(listener);
+            listener.destroy();
+        };
+    }
+
+    /**
+     * Dumps all the active view captures
+     */
+    public void dump(PrintWriter writer, FileDescriptor out) {
+        if (!FeatureFlags.CONTINUOUS_VIEW_TREE_CAPTURE.get()) {
+            return;
+        }
+        ViewIdProvider idProvider = new ViewIdProvider(mContext.getResources());
+
+        // Collect all the tasks first so that all the tasks are posted on the executor
+        List<Pair<String, Future<ExportedData>>> tasks = mListeners.stream()
+                .map(l -> Pair.create(l.name, mExecutor.submit(() -> l.dumpToProto(idProvider))))
+                .collect(toList());
+
+        tasks.forEach(pair -> {
             writer.println();
             writer.println(" ContinuousViewCapture:");
-            writer.println(" window " + getName() + ":");
-            writer.println("  pkg:" + mRoot.getContext().getPackageName());
+            writer.println(" window " + pair.first + ":");
+            writer.println("  pkg:" + mContext.getPackageName());
             writer.print("  data:");
             writer.flush();
-
             try (OutputStream os = new FileOutputStream(out)) {
-                ExportedData data = task.get();
+                ExportedData data = pair.second.get();
                 OutputStream encodedOS = new GZIPOutputStream(new Base64OutputStream(os,
                         Base64.NO_CLOSE | Base64.NO_PADDING | Base64.NO_WRAP));
                 data.writeTo(encodedOS);
@@ -217,51 +172,156 @@
             }
             writer.println();
             writer.println("--end--");
-        };
+        });
     }
 
-    @WorkerThread
-    private ExportedData dumpToProto() {
-        ExportedData.Builder dataBuilder = ExportedData.newBuilder();
-        Resources res = mResources;
-        ArrayList<Class> classList = new ArrayList<>();
+    private class WindowListener implements OnDrawListener {
 
-        int size = (mNodesBg[MEMORY_SIZE - 1] == null) ? mFrameIndexBg + 1 : MEMORY_SIZE;
-        for (int i = size - 1; i >= 0; i--) {
-            int index = (MEMORY_SIZE + mFrameIndexBg - i) % MEMORY_SIZE;
-            ViewNode.Builder nodeBuilder = ViewNode.newBuilder();
-            mNodesBg[index].toProto(res, classList, nodeBuilder);
-            dataBuilder.addFrameData(FrameData.newBuilder()
-                    .setNode(nodeBuilder)
-                    .setTimestamp(mFrameTimesBg[index]));
-        }
-        return dataBuilder
-                .addAllClassname(classList.stream().map(Class::getName).collect(toList()))
-                .build();
-    }
+        private final View mRoot;
+        public final String name;
 
-    private ViewRef captureViewTree(View view, ViewRef start) {
-        ViewRef ref;
-        if (mPool != null) {
-            ref = mPool;
-            mPool = mPool.next;
-            ref.next = null;
-        } else {
-            ref = new ViewRef();
+        private final Handler mHandler;
+        private final ViewRef mViewRef = new ViewRef();
+
+        private int mFrameIndexBg = -1;
+        private final long[] mFrameTimesBg = new long[MEMORY_SIZE];
+        private final ViewPropertyRef[] mNodesBg = new ViewPropertyRef[MEMORY_SIZE];
+
+        private boolean mDestroyed = false;
+
+        WindowListener(View view, String name) {
+            mRoot = view;
+            this.name = name;
+            mHandler = new Handler(mExecutor.getLooper(), this::captureViewPropertiesBg);
         }
-        ref.view = view;
-        start.next = ref;
-        if (view instanceof ViewGroup) {
-            ViewRef result = ref;
-            ViewGroup parent = (ViewGroup) view;
-            int childCount = ref.childCount = parent.getChildCount();
-            for (int i = 0; i < childCount; i++) {
-                result = captureViewTree(parent.getChildAt(i), result);
+
+        @Override
+        public void onDraw() {
+            Trace.beginSection("view_capture");
+            captureViewTree(mRoot, mViewRef);
+            Message m = Message.obtain(mHandler);
+            m.obj = mViewRef.next;
+            mHandler.sendMessage(m);
+            Trace.endSection();
+        }
+
+        /**
+         * Captures the View property on the background thread, and transfer all the ViewRef objects
+         * back to the pool
+         */
+        @WorkerThread
+        private boolean captureViewPropertiesBg(Message msg) {
+            ViewRef start = (ViewRef) msg.obj;
+            long time = msg.getWhen();
+            if (start == null) {
+                return false;
             }
-            return result;
-        } else {
-            ref.childCount = 0;
-            return ref;
+            mFrameIndexBg++;
+            if (mFrameIndexBg >= MEMORY_SIZE) {
+                mFrameIndexBg = 0;
+            }
+            mFrameTimesBg[mFrameIndexBg] = time;
+
+            ViewPropertyRef recycle = mNodesBg[mFrameIndexBg];
+
+            ViewPropertyRef result = null;
+            ViewPropertyRef resultEnd = null;
+
+            ViewRef current = start;
+            ViewRef last = start;
+            while (current != null) {
+                ViewPropertyRef propertyRef = recycle;
+                if (propertyRef == null) {
+                    propertyRef = new ViewPropertyRef();
+                } else {
+                    recycle = recycle.next;
+                    propertyRef.next = null;
+                }
+
+                propertyRef.transfer(current);
+                last = current;
+                current = current.next;
+
+                if (result == null) {
+                    result = propertyRef;
+                    resultEnd = result;
+                } else {
+                    resultEnd.next = propertyRef;
+                    resultEnd = propertyRef;
+                }
+            }
+            mNodesBg[mFrameIndexBg] = result;
+            ViewRef end = last;
+            MAIN_EXECUTOR.execute(() -> addToPool(start, end));
+            return true;
+        }
+
+        void attachToRoot() {
+            if (mRoot.isAttachedToWindow()) {
+                mRoot.getViewTreeObserver().addOnDrawListener(this);
+            } else {
+                mRoot.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {
+                    @Override
+                    public void onViewAttachedToWindow(View v) {
+                        if (!mDestroyed) {
+                            mRoot.getViewTreeObserver().addOnDrawListener(WindowListener.this);
+                        }
+                        mRoot.removeOnAttachStateChangeListener(this);
+                    }
+
+                    @Override
+                    public void onViewDetachedFromWindow(View v) { }
+                });
+            }
+        }
+
+        void destroy() {
+            mRoot.getViewTreeObserver().removeOnDrawListener(this);
+            mDestroyed = true;
+        }
+
+        @WorkerThread
+        private ExportedData dumpToProto(ViewIdProvider idProvider) {
+            ExportedData.Builder dataBuilder = ExportedData.newBuilder();
+            ArrayList<Class> classList = new ArrayList<>();
+
+            int size = (mNodesBg[MEMORY_SIZE - 1] == null) ? mFrameIndexBg + 1 : MEMORY_SIZE;
+            for (int i = size - 1; i >= 0; i--) {
+                int index = (MEMORY_SIZE + mFrameIndexBg - i) % MEMORY_SIZE;
+                ViewNode.Builder nodeBuilder = ViewNode.newBuilder();
+                mNodesBg[index].toProto(idProvider, classList, nodeBuilder);
+                dataBuilder.addFrameData(FrameData.newBuilder()
+                        .setNode(nodeBuilder)
+                        .setTimestamp(mFrameTimesBg[index]));
+            }
+            return dataBuilder
+                    .addAllClassname(classList.stream().map(Class::getName).collect(toList()))
+                    .build();
+        }
+
+        private ViewRef captureViewTree(View view, ViewRef start) {
+            ViewRef ref;
+            if (mPool != null) {
+                ref = mPool;
+                mPool = mPool.next;
+                ref.next = null;
+            } else {
+                ref = new ViewRef();
+            }
+            ref.view = view;
+            start.next = ref;
+            if (view instanceof ViewGroup) {
+                ViewRef result = ref;
+                ViewGroup parent = (ViewGroup) view;
+                int childCount = ref.childCount = parent.getChildCount();
+                for (int i = 0; i < childCount; i++) {
+                    result = captureViewTree(parent.getChildAt(i), result);
+                }
+                return result;
+            } else {
+                ref.childCount = 0;
+                return ref;
+            }
         }
     }
 
@@ -318,18 +378,8 @@
          * at the end of the iteration.
          * @return
          */
-        public ViewPropertyRef toProto(Resources res, ArrayList<Class> classList,
+        public ViewPropertyRef toProto(ViewIdProvider idProvider, ArrayList<Class> classList,
                 ViewNode.Builder outBuilder) {
-            String resolvedId;
-            if (id >= 0) {
-                try {
-                    resolvedId = res.getResourceTypeName(id) + '/' + res.getResourceEntryName(id);
-                } catch (Resources.NotFoundException e) {
-                    resolvedId = "id/" + "0x" + Integer.toHexString(id).toUpperCase();
-                }
-            } else {
-                resolvedId = "NO_ID";
-            }
             int classnameIndex = classList.indexOf(clazz);
             if (classnameIndex < 0) {
                 classnameIndex = classList.size();
@@ -338,7 +388,7 @@
             outBuilder
                     .setClassnameIndex(classnameIndex)
                     .setHashcode(hashCode)
-                    .setId(resolvedId)
+                    .setId(idProvider.getName(id))
                     .setLeft(left)
                     .setTop(top)
                     .setWidth(right - left)
@@ -356,7 +406,7 @@
             ViewPropertyRef result = next;
             for (int i = 0; (i < childCount) && (result != null); i++) {
                 ViewNode.Builder childBuilder = ViewNode.newBuilder();
-                result = result.toProto(res, classList, childBuilder);
+                result = result.toProto(idProvider, classList, childBuilder);
                 outBuilder.addChildren(childBuilder);
             }
             return result;
@@ -368,4 +418,31 @@
         public int childCount = 0;
         public ViewRef next;
     }
+
+    private static final class ViewIdProvider {
+
+        private final SparseArray<String> mNames = new SparseArray<>();
+        private final Resources mRes;
+
+        ViewIdProvider(Resources res) {
+            mRes = res;
+        }
+
+        String getName(int id) {
+            String name = mNames.get(id);
+            if (name == null) {
+                if (id >= 0) {
+                    try {
+                        name = mRes.getResourceTypeName(id) + '/' + mRes.getResourceEntryName(id);
+                    } catch (Resources.NotFoundException e) {
+                        name = "id/" + "0x" + Integer.toHexString(id).toUpperCase();
+                    }
+                } else {
+                    name = "NO_ID";
+                }
+                mNames.put(id, name);
+            }
+            return name;
+        }
+    }
 }
diff --git a/src/com/android/launcher3/util/window/WindowManagerProxy.java b/src/com/android/launcher3/util/window/WindowManagerProxy.java
index 582ff8d..fb2ae73 100644
--- a/src/com/android/launcher3/util/window/WindowManagerProxy.java
+++ b/src/com/android/launcher3/util/window/WindowManagerProxy.java
@@ -17,14 +17,15 @@
 
 import static android.view.Display.DEFAULT_DISPLAY;
 
+import static com.android.launcher3.Utilities.dpiFromPx;
 import static com.android.launcher3.testing.shared.ResourceUtils.INVALID_RESOURCE_HANDLE;
 import static com.android.launcher3.testing.shared.ResourceUtils.NAVBAR_HEIGHT;
 import static com.android.launcher3.testing.shared.ResourceUtils.NAVBAR_HEIGHT_LANDSCAPE;
 import static com.android.launcher3.testing.shared.ResourceUtils.NAVBAR_LANDSCAPE_LEFT_RIGHT_SIZE;
+import static com.android.launcher3.testing.shared.ResourceUtils.NAV_BAR_INTERACTION_MODE_RES_NAME;
 import static com.android.launcher3.testing.shared.ResourceUtils.STATUS_BAR_HEIGHT;
 import static com.android.launcher3.testing.shared.ResourceUtils.STATUS_BAR_HEIGHT_LANDSCAPE;
 import static com.android.launcher3.testing.shared.ResourceUtils.STATUS_BAR_HEIGHT_PORTRAIT;
-import static com.android.launcher3.Utilities.dpiFromPx;
 import static com.android.launcher3.util.MainThreadInitializedObject.forOverride;
 import static com.android.launcher3.util.RotationUtils.deltaRotation;
 import static com.android.launcher3.util.RotationUtils.rotateRect;
@@ -40,6 +41,7 @@
 import android.hardware.display.DisplayManager;
 import android.os.Build;
 import android.util.ArrayMap;
+import android.util.Log;
 import android.view.Display;
 import android.view.DisplayCutout;
 import android.view.Surface;
@@ -48,9 +50,10 @@
 import android.view.WindowMetrics;
 
 import com.android.launcher3.R;
-import com.android.launcher3.testing.shared.ResourceUtils;
 import com.android.launcher3.Utilities;
+import com.android.launcher3.testing.shared.ResourceUtils;
 import com.android.launcher3.util.MainThreadInitializedObject;
+import com.android.launcher3.util.NavigationMode;
 import com.android.launcher3.util.ResourceBasedOverride;
 import com.android.launcher3.util.WindowBounds;
 
@@ -59,6 +62,7 @@
  */
 public class WindowManagerProxy implements ResourceBasedOverride {
 
+    private static final String TAG = "WindowManagerProxy";
     public static final int MIN_TABLET_WIDTH = 600;
 
     public static final MainThreadInitializedObject<WindowManagerProxy> INSTANCE =
@@ -343,4 +347,24 @@
         return displayInfoContext.getSystemService(DisplayManager.class).getDisplay(
                 DEFAULT_DISPLAY);
     }
+
+    /**
+     * Returns the current navigation mode from resource.
+     */
+    public NavigationMode getNavigationMode(Context context) {
+        int modeInt = ResourceUtils.getIntegerByName(NAV_BAR_INTERACTION_MODE_RES_NAME,
+                context.getResources(), INVALID_RESOURCE_HANDLE);
+
+        if (modeInt == INVALID_RESOURCE_HANDLE) {
+            Log.e(TAG, "Failed to get system resource ID. Incompatible framework version?");
+        } else {
+            for (NavigationMode m : NavigationMode.values()) {
+                if (m.resValue == modeInt) {
+                    return m;
+                }
+            }
+        }
+        return Utilities.ATLEAST_S ? NavigationMode.NO_BUTTON :
+                NavigationMode.THREE_BUTTONS;
+    }
 }
diff --git a/src/com/android/launcher3/views/ActivityContext.java b/src/com/android/launcher3/views/ActivityContext.java
index 93078e4..e2dc34f 100644
--- a/src/com/android/launcher3/views/ActivityContext.java
+++ b/src/com/android/launcher3/views/ActivityContext.java
@@ -141,6 +141,7 @@
     default void applyOverwritesToLogItem(LauncherAtom.ItemInfo.Builder itemInfoBuilder) { }
 
     /** Onboarding preferences for any onboarding data within this context. */
+    @Nullable
     default OnboardingPrefs<?> getOnboardingPrefs() {
         return null;
     }