Merge "Set FLAG_IMMUTABLE flag on FirstScreenBroadcast PendingIntent." into sc-dev
diff --git a/quickstep/res/values/styles.xml b/quickstep/res/values/styles.xml
index df089f6..e56397a 100644
--- a/quickstep/res/values/styles.xml
+++ b/quickstep/res/values/styles.xml
@@ -81,7 +81,7 @@
         parent="@android:style/Widget.DeviceDefault.Button.Borderless">
         <item name="android:textColor">@color/overview_button</item>
         <item name="android:drawableTint">@color/overview_button</item>
-        <item name="android:tint">?attr/workspaceTextColor</item>
+        <item name="android:tint">?android:attr/textColorPrimary</item>
         <item name="android:drawablePadding">8dp</item>
         <item name="android:textAllCaps">false</item>
     </style>
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
index 43e70a3..b269901 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
@@ -105,7 +105,7 @@
 
     @Override
     public float getOverviewScrimAlpha(Launcher launcher) {
-        return 0.5f;
+        return 1f;
     }
 
     @Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
index e70450d..0921ad3 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
@@ -38,7 +38,6 @@
 import android.animation.ValueAnimator;
 import android.graphics.PointF;
 import android.view.MotionEvent;
-import android.view.View;
 import android.view.ViewConfiguration;
 
 import com.android.launcher3.Launcher;
@@ -155,11 +154,6 @@
             super.onDragEnd(velocity);
         }
 
-        View searchView = mLauncher.getHotseat().getQsb();
-        if (searchView instanceof FeedbackHandler) {
-            ((FeedbackHandler) searchView).resetFeedback();
-        }
-
         mMotionPauseDetector.clear();
         mNormalToHintOverviewScrimAnimator = null;
         if (mLauncher.isInState(OVERVIEW)) {
@@ -314,15 +308,4 @@
         }
         return super.getConfigForStates(fromState, toState);
     }
-
-    /**
-     * Interface for views with feedback animation requiring reset
-     */
-    public interface FeedbackHandler {
-
-        /**
-         * reset searchWidget feedback
-         */
-        void resetFeedback();
-    }
 }
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
index 8542209..94a7442 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
@@ -137,14 +137,17 @@
 
     private void updateFullscreenProgress(float progress) {
         mOverviewPanel.setFullscreenProgress(progress);
-        int sysuiFlags = 0;
         if (progress > UPDATE_SYSUI_FLAGS_THRESHOLD) {
+            int sysuiFlags = 0;
             TaskView tv = mOverviewPanel.getTaskViewAt(0);
             if (tv != null) {
                 sysuiFlags = tv.getThumbnail().getSysUiStatusNavFlags();
             }
+            mLauncher.getSystemUiController().updateUiState(UI_STATE_OVERVIEW, sysuiFlags);
+        } else {
+            mLauncher.getSystemUiController().updateUiState(
+                    UI_STATE_OVERVIEW, mOverviewPanel.hasLightBackground());
         }
-        mLauncher.getSystemUiController().updateUiState(UI_STATE_OVERVIEW, sysuiFlags);
     }
 
     @Override
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 6759936..b7c6743 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -93,7 +93,6 @@
 import com.android.launcher3.util.WindowBounds;
 import com.android.quickstep.BaseActivityInterface.AnimationFactory;
 import com.android.quickstep.GestureState.GestureEndTarget;
-import com.android.quickstep.inputconsumers.OverviewInputConsumer;
 import com.android.quickstep.util.ActiveGestureLog;
 import com.android.quickstep.util.ActivityInitListener;
 import com.android.quickstep.util.AnimatorControllerWithResistance;
@@ -656,8 +655,13 @@
                     ||  (quickswitchThresholdPassed && centermostTaskFlags != 0));
             mRecentsAnimationController.setSplitScreenMinimized(swipeUpThresholdPassed);
 
-            int sysuiFlags = swipeUpThresholdPassed ? 0 : centermostTaskFlags;
-            mActivity.getSystemUiController().updateUiState(UI_STATE_OVERVIEW, sysuiFlags);
+            if (swipeUpThresholdPassed) {
+                mActivity.getSystemUiController().updateUiState(
+                        UI_STATE_OVERVIEW, mRecentsView.hasLightBackground());
+            } else {
+                mActivity.getSystemUiController().updateUiState(
+                        UI_STATE_OVERVIEW, centermostTaskFlags);
+            }
         }
     }
 
@@ -1067,9 +1071,9 @@
             HomeAnimationFactory homeAnimFactory = createHomeAnimationFactory(duration);
             mIsSwipingPipToHome = homeAnimFactory.supportSwipePipToHome()
                     && runningTaskTarget != null
-                    && runningTaskTarget.pictureInPictureParams != null
+                    && runningTaskTarget.taskInfo.pictureInPictureParams != null
                     && TaskInfoCompat.isAutoEnterPipEnabled(
-                            runningTaskTarget.pictureInPictureParams);
+                            runningTaskTarget.taskInfo.pictureInPictureParams);
             if (mIsSwipingPipToHome) {
                 mSwipePipToHomeAnimator = getSwipePipToHomeAnimator(
                         homeAnimFactory, runningTaskTarget, start);
@@ -1157,7 +1161,7 @@
         final Rect destinationBounds = SystemUiProxy.INSTANCE.get(mContext)
                 .startSwipePipToHome(taskInfo.topActivity,
                         TaskInfoCompat.getTopActivityInfo(taskInfo),
-                        runningTaskTarget.pictureInPictureParams,
+                        runningTaskTarget.taskInfo.pictureInPictureParams,
                         homeRotation,
                         mDp.hotseatBarSizePx);
         final Rect startBounds = new Rect();
@@ -1166,7 +1170,8 @@
                 runningTaskTarget.taskId,
                 taskInfo.topActivity,
                 runningTaskTarget.leash.getSurfaceControl(),
-                TaskInfoCompat.getPipSourceRectHint(runningTaskTarget.pictureInPictureParams),
+                TaskInfoCompat.getPipSourceRectHint(
+                        runningTaskTarget.taskInfo.pictureInPictureParams),
                 TaskInfoCompat.getWindowConfigurationBounds(taskInfo),
                 startBounds,
                 destinationBounds,
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
index d3ed791..1340abb 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -56,7 +56,6 @@
 import com.android.launcher3.util.ActivityTracker;
 import com.android.launcher3.util.RunnableList;
 import com.android.launcher3.util.SystemUiController;
-import com.android.launcher3.util.Themes;
 import com.android.launcher3.views.BaseDragLayer;
 import com.android.quickstep.fallback.FallbackRecentsStateController;
 import com.android.quickstep.fallback.FallbackRecentsView;
@@ -267,7 +266,7 @@
         setupViews();
 
         getSystemUiController().updateUiState(SystemUiController.UI_STATE_BASE_WINDOW,
-                Themes.getAttrBoolean(this, R.attr.isWorkspaceDarkText));
+                mFallbackRecentsView.hasLightBackground());
         ACTIVITY_TRACKER.handleCreate(this);
     }
 
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
index 458f45a..23e35f6 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -187,7 +187,7 @@
             SettingsCache.OnChangeListener onChangeListener =
                     enabled -> mIsOneHandedModeEnabled = enabled;
             settingsCache.register(oneHandedUri, onChangeListener);
-            settingsCache.dispatchOnChange(oneHandedUri);
+            mIsOneHandedModeEnabled = settingsCache.getValue(oneHandedUri);
             runOnDestroy(() -> settingsCache.unregister(oneHandedUri, onChangeListener));
         } else {
             mIsOneHandedModeEnabled = false;
@@ -199,7 +199,7 @@
         SettingsCache.OnChangeListener onChangeListener =
                 enabled -> mIsSwipeToNotificationEnabled = enabled;
         settingsCache.register(swipeBottomNotificationUri, onChangeListener);
-        settingsCache.dispatchOnChange(swipeBottomNotificationUri);
+        mIsSwipeToNotificationEnabled = settingsCache.getValue(swipeBottomNotificationUri);
         runOnDestroy(() -> settingsCache.unregister(swipeBottomNotificationUri, onChangeListener));
 
         Uri setupCompleteUri = Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE);
diff --git a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
index f4b8b62..a8c09dc 100644
--- a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
+++ b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
@@ -29,7 +29,6 @@
 import androidx.annotation.UiThread;
 
 import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.AnimationSuccessListener;
 import com.android.launcher3.anim.AnimatorPlaybackController;
@@ -67,8 +66,6 @@
     // How much further we can drag past recents, as a factor of mTransitionDragLength.
     protected float mDragLengthFactor = 1;
 
-    protected final float mMaxShadowRadius;
-
     protected AnimatorControllerWithResistance mWindowTransitionController;
 
     public SwipeUpAnimationLogic(Context context, RecentsAnimationDeviceState deviceState,
@@ -82,9 +79,6 @@
         mTaskViewSimulator.getOrientationState().update(
                 mDeviceState.getRotationTouchHelper().getCurrentActiveRotation(),
                 mDeviceState.getRotationTouchHelper().getDisplayRotation());
-
-        mMaxShadowRadius = context.getResources().getDimensionPixelSize(R.dimen.max_shadow_radius);
-        mTransformParams.setShadowRadius(mMaxShadowRadius);
     }
 
     protected void initTransitionEndpoints(DeviceProfile dp) {
@@ -271,11 +265,9 @@
 
             mMatrix.setRectToRect(mCropRectF, mWindowCurrentRect, ScaleToFit.FILL);
             float cornerRadius = Utilities.mapRange(progress, mStartRadius, mEndRadius);
-            float shadowRadius = Utilities.mapRange(progress, mMaxShadowRadius, 0);
             mTransformParams
                     .setTargetAlpha(getWindowAlpha(progress))
-                    .setCornerRadius(cornerRadius)
-                    .setShadowRadius(shadowRadius);
+                    .setCornerRadius(cornerRadius);
 
             mTransformParams.applySurfaceParams(mTransformParams.createSurfaceParams(this));
             mAnimationFactory.update(currentRect, progress, mMatrix.mapRadius(cornerRadius));
@@ -286,8 +278,7 @@
                 Builder builder, RemoteAnimationTargetCompat app, TransformParams params) {
             builder.withMatrix(mMatrix)
                     .withWindowCrop(mCropRect)
-                    .withCornerRadius(params.getCornerRadius())
-                    .withShadowRadius(app.isTranslucent ? 0 : params.getShadowRadius());
+                    .withCornerRadius(params.getCornerRadius());
         }
 
         @Override
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index cf71eae..1f332c4 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -88,6 +88,17 @@
     }
 
     @Override
+    public void onBackPressed() {
+        if (mSystemUiProxy != null) {
+            try {
+                mSystemUiProxy.onBackPressed();
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call onBackPressed", e);
+            }
+        }
+    }
+
+    @Override
     public IBinder asBinder() {
         // Do nothing
         return null;
diff --git a/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java b/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java
index f336bf5..b336d2f 100644
--- a/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java
+++ b/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java
@@ -80,7 +80,7 @@
         SettingsCache mSettingsCache = SettingsCache.INSTANCE.get(context);
         mSettingsCache.register(NOTIFICATION_BADGING_URI,
                 this::onNotificationDotsChanged);
-        mSettingsCache.dispatchOnChange(NOTIFICATION_BADGING_URI);
+        onNotificationDotsChanged(mSettingsCache.getValue(NOTIFICATION_BADGING_URI));
     }
 
     private static ArrayMap<String, LoggablePref> loadPrefKeys(Context context) {
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
index 6cfe302..3c8a12c 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -330,8 +330,7 @@
             Builder builder, RemoteAnimationTargetCompat app, TransformParams params) {
         builder.withMatrix(mMatrix)
                 .withWindowCrop(mTmpCropRect)
-                .withCornerRadius(getCurrentCornerRadius())
-                .withShadowRadius(app.isTranslucent ? 0 : params.getShadowRadius());
+                .withCornerRadius(getCurrentCornerRadius());
 
         if (LIVE_TILE.get() && params.getRecentsSurface() != null) {
             // When relativeLayer = 0, it reverts the surfaces back to the original order.
diff --git a/quickstep/src/com/android/quickstep/util/TransformParams.java b/quickstep/src/com/android/quickstep/util/TransformParams.java
index cdf5163..756331d 100644
--- a/quickstep/src/com/android/quickstep/util/TransformParams.java
+++ b/quickstep/src/com/android/quickstep/util/TransformParams.java
@@ -57,7 +57,6 @@
     private float mProgress;
     private float mTargetAlpha;
     private float mCornerRadius;
-    private float mShadowRadius;
     private RemoteAnimationTargets mTargetSet;
     private SurfaceTransactionApplier mSyncTransactionApplier;
     private SurfaceControl mRecentsSurface;
@@ -69,7 +68,6 @@
         mProgress = 0;
         mTargetAlpha = 1;
         mCornerRadius = -1;
-        mShadowRadius = 0;
     }
 
     /**
@@ -93,14 +91,6 @@
     }
 
     /**
-     * Sets the shadow radius of the transformed window, in pixels.
-     */
-    public TransformParams setShadowRadius(float shadowRadius) {
-        mShadowRadius = shadowRadius;
-        return this;
-    }
-
-    /**
      * Specifies the alpha of the transformed window. Default is 1.
      */
     public TransformParams setTargetAlpha(float targetAlpha) {
@@ -207,10 +197,6 @@
         return mCornerRadius;
     }
 
-    public float getShadowRadius() {
-        return mShadowRadius;
-    }
-
     public SurfaceControl getRecentsSurface() {
         return mRecentsSurface;
     }
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index ad266ce..bf237fd 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -439,6 +439,7 @@
 
     private boolean mRunningTaskIconScaledDown = false;
 
+    private final boolean mHasLightBackground;
     private boolean mOverviewStateEnabled;
     private boolean mHandleTaskStackChanges;
     private boolean mSwipeDownShouldLaunchApp;
@@ -570,6 +571,8 @@
         mLiveTileTaskViewSimulator.recentsViewScale.value = 1;
         mLiveTileTaskViewSimulator.setOrientationState(mOrientationState);
         mLiveTileTaskViewSimulator.setDrawsBelowRecents(true);
+
+        mHasLightBackground = Themes.getAttrBoolean(mActivity, android.R.attr.isLightTheme);
     }
 
     public OverScroller getScroller() {
@@ -847,6 +850,13 @@
                 cancelSplitSelect(false);
             }
         }
+
+        if (enabled) {
+            mActivity.getSystemUiController().updateUiState(
+                    UI_STATE_OVERVIEW, hasLightBackground());
+        } else {
+            mActivity.getSystemUiController().updateUiState(UI_STATE_OVERVIEW, 0);
+        }
     }
 
     public void onDigitalWellbeingToastShown() {
@@ -2510,6 +2520,14 @@
         }
     }
 
+    /**
+     * True if the background scrim of the recents view is light colored and the foreground elements
+     * should use dark colors.
+     */
+    public boolean hasLightBackground() {
+        return mHasLightBackground;
+    }
+
     public void initiateSplitSelect(TaskView taskView, SplitPositionOption splitPositionOption) {
         mSplitHiddenTaskView = taskView;
         mSplitPlaceholderView.getSplitController().setInitialTaskSelect(taskView,
@@ -2754,10 +2772,13 @@
         progressAnim.addUpdateListener(animator -> {
             // Once we pass a certain threshold, update the sysui flags to match the target
             // tasks' flags
-            mActivity.getSystemUiController().updateUiState(UI_STATE_OVERVIEW,
-                    animator.getAnimatedFraction() > UPDATE_SYSUI_FLAGS_THRESHOLD
-                            ? targetSysUiFlags
-                            : 0);
+            if (animator.getAnimatedFraction() > UPDATE_SYSUI_FLAGS_THRESHOLD) {
+                mActivity.getSystemUiController().updateUiState(
+                        UI_STATE_OVERVIEW, targetSysUiFlags);
+            } else {
+                mActivity.getSystemUiController().updateUiState(
+                        UI_STATE_OVERVIEW, hasLightBackground());
+            }
 
             // Passing the threshold from taskview to fullscreen app will vibrate
             final boolean passed = animator.getAnimatedFraction() >=
diff --git a/res/color/overview_button.xml b/res/color/overview_button.xml
index 6ac36bf..aa48b78 100644
--- a/res/color/overview_button.xml
+++ b/res/color/overview_button.xml
@@ -2,10 +2,10 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item
         android:alpha="1"
-        android:color="?attr/workspaceTextColor"
+        android:color="?android:attr/textColorPrimary"
         android:state_enabled="true" />
     <item
         android:alpha="?android:disabledAlpha"
-        android:color="?attr/workspaceTextColor"
+        android:color="?android:attr/textColorPrimary"
         android:state_enabled="false" />
 </selector>
\ No newline at end of file
diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java
index 9b350a1..5ba03ed 100644
--- a/src/com/android/launcher3/BaseDraggingActivity.java
+++ b/src/com/android/launcher3/BaseDraggingActivity.java
@@ -28,6 +28,7 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
+import android.os.Binder;
 import android.os.Bundle;
 import android.os.Process;
 import android.os.StrictMode;
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 7ece72e..c16c44b 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -212,7 +212,10 @@
         mActivity = ActivityContext.lookupContext(context);
         DeviceProfile deviceProfile = mActivity.getDeviceProfile();
 
-        mBorderSpacing = deviceProfile.cellLayoutBorderSpacingPx;
+        mBorderSpacing = mContainerType == FOLDER
+                ? deviceProfile.folderCellLayoutBorderSpacingPx
+                : deviceProfile.cellLayoutBorderSpacingPx;
+
         mCellWidth = mCellHeight = -1;
         mFixedCellWidth = mFixedCellHeight = -1;
 
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 1ce5f4d..a29eab7 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -123,6 +123,7 @@
     public int folderIconOffsetYPx;
 
     // Folder content
+    public int folderCellLayoutBorderSpacingPx;
     public int folderContentPaddingLeftRight;
     public int folderContentPaddingTop;
 
@@ -254,6 +255,7 @@
 
         setCellLayoutBorderSpacing(pxFromDp(inv.borderSpacing, mInfo.metrics, 1f));
         cellLayoutBorderSpacingOriginalPx = cellLayoutBorderSpacingPx;
+        folderCellLayoutBorderSpacingPx = cellLayoutBorderSpacingPx;
 
         int cellLayoutPaddingLeftRightMultiplier = !isVerticalBarLayout() && isTablet
                 ? PORTRAIT_TABLET_LEFT_RIGHT_PADDING_MULTIPLIER : 1;
@@ -352,13 +354,7 @@
     }
 
     private void setCellLayoutBorderSpacing(int borderSpacing) {
-        if (isScalableGrid) {
-            cellLayoutBorderSpacingPx = borderSpacing;
-            folderContentPaddingLeftRight = borderSpacing;
-            folderContentPaddingTop = borderSpacing;
-        } else {
-            cellLayoutBorderSpacingPx = 0;
-        }
+        cellLayoutBorderSpacingPx = isScalableGrid ? borderSpacing : 0;
     }
 
     /**
@@ -404,12 +400,7 @@
                 .setMultiWindowMode(true)
                 .build();
 
-        // If there isn't enough vertical cell padding with the labels displayed, hide the labels.
-        float workspaceCellPaddingY = profile.getCellSize().y - profile.iconSizePx
-                - iconDrawablePaddingPx - profile.iconTextSizePx;
-        if (workspaceCellPaddingY < profile.iconDrawablePaddingPx * 2) {
-            profile.adjustToHideWorkspaceLabels();
-        }
+        profile.hideWorkspaceLabelsIfNotEnoughSpace();
 
         // We use these scales to measure and layout the widgets using their full invariant profile
         // sizes and then draw them scaled and centered to fit in their multi-window mode cellspans.
@@ -430,24 +421,32 @@
     }
 
     /**
-     * Adjusts the profile so that the labels on the Workspace are hidden.
+     * Checks if there is enough space for labels on the workspace.
+     * If there is not, labels on the Workspace are hidden.
      * It is important to call this method after the All Apps variables have been set.
      */
-    private void adjustToHideWorkspaceLabels() {
-        iconTextSizePx = 0;
-        iconDrawablePaddingPx = 0;
-        cellHeightPx = iconSizePx;
-        autoResizeAllAppsCells();
+    private void hideWorkspaceLabelsIfNotEnoughSpace() {
+        float iconTextHeight = Utilities.calculateTextHeight(iconTextSizePx);
+        float workspaceCellPaddingY = getCellSize().y - iconSizePx - iconDrawablePaddingPx
+                - iconTextHeight;
+
+        // We want enough space so that the text is closer to its corresponding icon.
+        if (workspaceCellPaddingY < iconTextHeight) {
+            iconTextSizePx = 0;
+            iconDrawablePaddingPx = 0;
+            cellHeightPx = iconSizePx;
+            autoResizeAllAppsCells();
+        }
     }
 
     /**
      * Re-computes the all-apps cell size to be independent of workspace
      */
     public void autoResizeAllAppsCells() {
-        int topBottomPadding = allAppsIconDrawablePaddingPx * (isVerticalBarLayout() ? 2 : 1);
+        int textHeight = Utilities.calculateTextHeight(allAppsIconTextSizePx);
+        int topBottomPadding = textHeight;
         allAppsCellHeightPx = allAppsIconSizePx + allAppsIconDrawablePaddingPx
-                + Utilities.calculateTextHeight(allAppsIconTextSizePx)
-                + topBottomPadding * 2;
+                + textHeight + (topBottomPadding * 2);
     }
 
     /**
@@ -536,9 +535,7 @@
             allAppsIconSizePx = pxFromDp(inv.allAppsIconSize, mInfo.metrics);
             allAppsIconTextSizePx = Utilities.pxFromSp(inv.allAppsIconTextSize, mInfo.metrics);
             allAppsIconDrawablePaddingPx = iconDrawablePaddingOriginalPx;
-            // We use 4 below to ensure labels are closer to their corresponding icon.
-            allAppsCellHeightPx = Math.round(allAppsIconSizePx + allAppsIconTextSizePx
-                    + (4 * allAppsIconDrawablePaddingPx));
+            autoResizeAllAppsCells();
         } else {
             allAppsIconSizePx = iconSizePx;
             allAppsIconTextSizePx = iconTextSizePx;
@@ -547,9 +544,8 @@
         }
         allAppsCellWidthPx = allAppsIconSizePx + allAppsIconDrawablePaddingPx;
 
-        if (isVerticalBarLayout()) {
-            // Always hide the Workspace text with vertical bar layout.
-            adjustToHideWorkspaceLabels();
+        if (isVerticalLayout) {
+            hideWorkspaceLabelsIfNotEnoughSpace();
         }
 
         // Hotseat
@@ -587,14 +583,14 @@
 
         // Check if the icons fit within the available height.
         float contentUsedHeight = folderCellHeightPx * inv.numFolderRows
-                + ((inv.numFolderRows - 1) * cellLayoutBorderSpacingPx);
+                + ((inv.numFolderRows - 1) * folderCellLayoutBorderSpacingPx);
         int contentMaxHeight = availableHeightPx - totalWorkspacePadding.y - folderBottomPanelSize
                 - folderMargin - folderContentPaddingTop;
         float scaleY = contentMaxHeight / contentUsedHeight;
 
         // Check if the icons fit within the available width.
         float contentUsedWidth = folderCellWidthPx * inv.numFolderColumns
-                + ((inv.numFolderColumns - 1) * cellLayoutBorderSpacingPx);
+                + ((inv.numFolderColumns - 1) * folderCellLayoutBorderSpacingPx);
         int contentMaxWidth = availableWidthPx - totalWorkspacePadding.x - folderMargin
                 - folderContentPaddingLeftRight * 2;
         float scaleX = contentMaxWidth / contentUsedWidth;
@@ -612,11 +608,25 @@
         folderLabelTextSizePx = (int) (folderChildTextSizePx * folderLabelTextScale);
 
         int textHeight = Utilities.calculateTextHeight(folderChildTextSizePx);
-        int cellPaddingX = (int) (res.getDimensionPixelSize(R.dimen.folder_cell_x_padding) * scale);
-        int cellPaddingY = (int) (res.getDimensionPixelSize(R.dimen.folder_cell_y_padding) * scale);
 
-        folderCellWidthPx = folderChildIconSizePx + 2 * cellPaddingX;
-        folderCellHeightPx = folderChildIconSizePx + 2 * cellPaddingY + textHeight;
+        if (isScalableGrid) {
+            folderCellWidthPx = (int) (cellWidthPx * scale);
+            folderCellHeightPx = (int) (cellHeightPx * scale);
+
+            int borderSpacing = (int) (cellLayoutBorderSpacingOriginalPx * scale);
+            folderCellLayoutBorderSpacingPx = borderSpacing;
+            folderContentPaddingLeftRight = borderSpacing;
+            folderContentPaddingTop = borderSpacing;
+        } else {
+            int cellPaddingX = (int) (res.getDimensionPixelSize(R.dimen.folder_cell_x_padding)
+                    * scale);
+            int cellPaddingY = (int) (res.getDimensionPixelSize(R.dimen.folder_cell_y_padding)
+                    * scale);
+
+            folderCellWidthPx = folderChildIconSizePx + 2 * cellPaddingX;
+            folderCellHeightPx = folderChildIconSizePx + 2 * cellPaddingY + textHeight;
+        }
+
         folderChildDrawablePaddingPx = Math.max(0,
                 (folderCellHeightPx - folderChildIconSizePx - textHeight) / 3);
     }
@@ -868,6 +878,8 @@
         writer.println(prefix + pxToDpStr("folderChildTextSizePx", folderChildTextSizePx));
         writer.println(prefix + pxToDpStr("folderChildDrawablePaddingPx",
                 folderChildDrawablePaddingPx));
+        writer.println(prefix + pxToDpStr("folderCellLayoutBorderSpacingPx",
+                folderCellLayoutBorderSpacingPx));
 
         writer.println(prefix + pxToDpStr("cellLayoutBorderSpacingPx",
                 cellLayoutBorderSpacingPx));
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 15e12d6..5429806 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -29,7 +29,6 @@
 
 import androidx.annotation.Nullable;
 
-import java.util.Arrays;
 import java.util.function.Consumer;
 
 /**
@@ -97,7 +96,6 @@
         } else {
             setGridSize(idp.numHotseatIcons, 1);
         }
-        showInlineQsb();
     }
 
     @Override
@@ -182,10 +180,6 @@
         mOnVisibilityAggregatedCallback = callback;
     }
 
-    protected void showInlineQsb() {
-        //Does nothing
-    }
-
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
@@ -224,13 +218,6 @@
     }
 
     /**
-     * Returns the first View for which the given itemOperator returns true, or null.
-     */
-    public View getFirstItemMatch(Workspace.ItemOperator itemOperator) {
-        return mWorkspace.getFirstMatch(Arrays.asList(this), itemOperator);
-    }
-
-    /**
      * Sets the alpha value of just our ShortcutAndWidgetContainer.
      */
     public void setIconsAlpha(float alpha) {
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 5eba399..f7cf66b 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -34,7 +34,6 @@
 import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.LauncherState.NO_OFFSET;
 import static com.android.launcher3.LauncherState.NO_SCALE;
-import static com.android.launcher3.LauncherState.OVERVIEW;
 import static com.android.launcher3.LauncherState.SPRING_LOADED;
 import static com.android.launcher3.Utilities.postAsyncCallback;
 import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.getSupportedActions;
@@ -149,7 +148,6 @@
 import com.android.launcher3.qsb.QsbContainerView;
 import com.android.launcher3.statemanager.StateManager;
 import com.android.launcher3.statemanager.StateManager.StateHandler;
-import com.android.launcher3.statemanager.StateManager.StateListener;
 import com.android.launcher3.statemanager.StatefulActivity;
 import com.android.launcher3.states.RotationHelper;
 import com.android.launcher3.testing.TestLogging;
@@ -269,9 +267,6 @@
     private static final int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;
     @Thunk @VisibleForTesting public static final int NEW_APPS_ANIMATION_DELAY = 500;
 
-    private static final int APPS_VIEW_ALPHA_CHANNEL_INDEX = 1;
-    private static final int SCRIM_VIEW_ALPHA_CHANNEL_INDEX = 0;
-
     private static final int THEME_CROSS_FADE_ANIMATION_DURATION = 375;
 
     private Configuration mOldConfig;
@@ -342,8 +337,6 @@
 
     private RotationHelper mRotationHelper;
 
-    private float mCurrentAssistantVisibility = 0f;
-
     protected LauncherOverlayManager mOverlayManager;
     // If true, overlay callbacks are deferred
     private boolean mDeferOverlayCallbacks;
@@ -457,24 +450,6 @@
                 OverlayPlugin.class, false /* allowedMultiple */);
 
         mRotationHelper.initialize();
-
-        mStateManager.addStateListener(new StateListener<LauncherState>() {
-
-            @Override
-            public void onStateTransitionComplete(LauncherState finalState) {
-                float alpha = 1f - mCurrentAssistantVisibility;
-                if (finalState == NORMAL) {
-                    mAppsView.getAlphaProperty(APPS_VIEW_ALPHA_CHANNEL_INDEX).setValue(alpha);
-                } else if (finalState == OVERVIEW) {
-                    mAppsView.getAlphaProperty(APPS_VIEW_ALPHA_CHANNEL_INDEX).setValue(alpha);
-                    mScrimView.setAlpha(alpha);
-                } else {
-                    mAppsView.getAlphaProperty(APPS_VIEW_ALPHA_CHANNEL_INDEX).setValue(1f);
-                    mScrimView.setAlpha(1f);
-                }
-            }
-        });
-
         TraceHelper.INSTANCE.endSection(traceToken);
 
         mUserChangedCallbackCloseable = UserCache.INSTANCE.get(this).addUserChangeListener(
@@ -563,15 +538,7 @@
     }
 
     public void onAssistantVisibilityChanged(float visibility) {
-        mCurrentAssistantVisibility = visibility;
-        float alpha = 1f - visibility;
-        LauncherState state = mStateManager.getState();
-        if (state == NORMAL) {
-            mAppsView.getAlphaProperty(APPS_VIEW_ALPHA_CHANNEL_INDEX).setValue(alpha);
-        } else if (state == OVERVIEW) {
-            mAppsView.getAlphaProperty(APPS_VIEW_ALPHA_CHANNEL_INDEX).setValue(alpha);
-            mScrimView.setAlpha(alpha);
-        }
+        mHotseat.getQsb().setAlpha(1f - visibility);
     }
 
     private void initDeviceProfile(InvariantDeviceProfile idp) {
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index ccc023a..4754558 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -116,7 +116,7 @@
         mNotificationSettingsChangedListener = this::onNotificationSettingsChanged;
         mSettingsCache.register(NOTIFICATION_BADGING_URI,
                 mNotificationSettingsChangedListener);
-        mSettingsCache.dispatchOnChange(NOTIFICATION_BADGING_URI);
+        onNotificationSettingsChanged(mSettingsCache.getValue(NOTIFICATION_BADGING_URI));
     }
 
     public LauncherAppState(Context context, @Nullable String iconCacheFileName) {
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 225e1c1..406e785 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -64,8 +64,6 @@
 import com.android.launcher3.model.data.AppInfo;
 import com.android.launcher3.testing.TestProtocol;
 import com.android.launcher3.util.ItemInfoMatcher;
-import com.android.launcher3.util.MultiValueAlpha;
-import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
 import com.android.launcher3.util.Themes;
 import com.android.launcher3.views.RecyclerViewFastScroller;
 import com.android.launcher3.views.SpringRelativeLayout;
@@ -80,7 +78,6 @@
     private static final float FLING_VELOCITY_MULTIPLIER = 1000 * .8f;
     // Starts the springs after at least 55% of the animation has passed.
     private static final float FLING_ANIMATION_THRESHOLD = 0.55f;
-    private static final int ALPHA_CHANNEL_COUNT = 2;
 
     protected final BaseDraggingActivity mLauncher;
     protected final AdapterHolder[] mAH;
@@ -107,8 +104,6 @@
     protected RecyclerViewFastScroller mTouchHandler;
     protected final Point mFastScrollerOffset = new Point();
 
-    private final MultiValueAlpha mMultiValueAlpha;
-
     private Rect mInsets = new Rect();
 
     SearchAdapterProvider mSearchAdapterProvider;
@@ -139,8 +134,6 @@
         mNavBarScrimPaint.setColor(Themes.getAttrColor(context, R.attr.allAppsNavBarScrimColor));
 
         mAllAppsStore.addUpdateListener(this::onAppsUpdated);
-
-        mMultiValueAlpha = new MultiValueAlpha(this, ALPHA_CHANNEL_COUNT);
     }
 
     /**
@@ -156,10 +149,6 @@
         return mAllAppsStore;
     }
 
-    public AlphaProperty getAlphaProperty(int index) {
-        return mMultiValueAlpha.getProperty(index);
-    }
-
     public WorkModeSwitch getWorkModeSwitch() {
         return mWorkModeSwitch;
     }
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 8c5b0fe..f031136 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -110,7 +110,6 @@
         setScrollRangeDelta(mScrollRangeDelta);
 
         if (mIsVerticalLayout) {
-            mAppsView.getAlphaProperty(APPS_VIEW_ALPHA_CHANNEL_INDEX).setValue(1);
             mLauncher.getHotseat().setTranslationY(0);
             mLauncher.getWorkspace().getPageIndicator().setTranslationY(0);
         }
diff --git a/src/com/android/launcher3/dragndrop/AppWidgetHostViewDrawable.java b/src/com/android/launcher3/dragndrop/AppWidgetHostViewDrawable.java
index 5cd95dc..7b32bbf 100644
--- a/src/com/android/launcher3/dragndrop/AppWidgetHostViewDrawable.java
+++ b/src/com/android/launcher3/dragndrop/AppWidgetHostViewDrawable.java
@@ -27,15 +27,21 @@
 
 import com.android.launcher3.widget.LauncherAppWidgetHostView;
 
-/** A drawable which renders {@link LauncherAppWidgetHostView} to a canvas. */
+/**
+ * A drawable which renders {@link LauncherAppWidgetHostView} to a canvas.
+ *
+ * TODO(b/183609936) Stop using that class and remove it.
+ */
 public final class AppWidgetHostViewDrawable extends Drawable {
 
     private final LauncherAppWidgetHostView mAppWidgetHostView;
     private Paint mPaint = new Paint();
     private final Path mClipPath;
+    private final boolean mWasAttached;
 
     public AppWidgetHostViewDrawable(LauncherAppWidgetHostView appWidgetHostView) {
         mAppWidgetHostView = appWidgetHostView;
+        mWasAttached = appWidgetHostView.isAttachedToWindow();
         Path clipPath = null;
         if (appWidgetHostView.getClipToOutline()) {
             Outline outline = new Outline();
@@ -56,7 +62,12 @@
         if (mClipPath != null) {
             canvas.clipPath(mClipPath);
         }
-        mAppWidgetHostView.draw(canvas);
+        // If the view was never attached, or is current attached, then draw. Otherwise do not try
+        // to draw, or we might trigger bugs with items that get drawn while requiring the view to
+        // be attached.
+        if (!mWasAttached || mAppWidgetHostView.isAttachedToWindow()) {
+            mAppWidgetHostView.draw(canvas);
+        }
         canvas.restoreToCount(saveCount);
     }
 
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index ec7155c..a1b7997 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -745,6 +745,10 @@
         if (mIsAnimatingClosed) {
             return;
         }
+
+        mContent.completePendingPageChanges();
+        mContent.snapToPageImmediately(mContent.getDestinationPage());
+
         if (mCurrentAnimator != null && mCurrentAnimator.isRunning()) {
             mCurrentAnimator.cancel();
         }
diff --git a/src/com/android/launcher3/graphics/NinePatchDrawHelper.java b/src/com/android/launcher3/graphics/NinePatchDrawHelper.java
deleted file mode 100644
index 5872689..0000000
--- a/src/com/android/launcher3/graphics/NinePatchDrawHelper.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2017 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.graphics;
-
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.graphics.RectF;
-
-/**
- * Utility class which draws a bitmap by dissecting it into 3 segments and stretching
- * the middle segment.
- */
-public class NinePatchDrawHelper {
-
-    // The extra width used for the bitmap. This portion of the bitmap is stretched to match the
-    // width of the draw region. Randomly chosen, any value > 4 will be sufficient.
-    public static final int EXTENSION_PX = 20;
-
-    private final Rect mSrc = new Rect();
-    private final RectF mDst = new RectF();
-    // Enable filtering to always get a nice edge. This avoids jagged line, when bitmap is
-    // translated by half pixel.
-    public final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
-
-    /**
-     * Draws the bitmap split into three parts horizontally, with the middle part having width
-     * as {@link #EXTENSION_PX} in the center of the bitmap.
-     */
-    public void draw(Bitmap bitmap, Canvas canvas, float left, float top, float right) {
-        int height = bitmap.getHeight();
-
-        mSrc.top = 0;
-        mSrc.bottom = height;
-        mDst.top = top;
-        mDst.bottom = top + height;
-        draw3Patch(bitmap, canvas, left, right);
-    }
-
-
-    /**
-     * Draws the bitmap split horizontally into 3 parts (same as {@link #draw}) and split
-     * vertically into two parts, bottom part of size {@link #EXTENSION_PX} / 2 which is
-     * stretched vertically.
-     */
-    public void drawVerticallyStretched(Bitmap bitmap, Canvas canvas, float left, float top,
-            float right, float bottom) {
-        draw(bitmap, canvas, left, top, right);
-
-        // Draw bottom stretched region.
-        int height = bitmap.getHeight();
-        mSrc.top = height - EXTENSION_PX / 4;
-        mSrc.bottom = height;
-        mDst.top = top + height;
-        mDst.bottom = bottom;
-        draw3Patch(bitmap, canvas, left, right);
-    }
-
-
-
-    private void draw3Patch(Bitmap bitmap, Canvas canvas, float left, float right) {
-        int width = bitmap.getWidth();
-        int halfWidth = width / 2;
-
-        // Draw left edge
-        drawRegion(bitmap, canvas, 0, halfWidth, left, left + halfWidth);
-
-        // Draw right edge
-        drawRegion(bitmap, canvas, halfWidth, width, right - halfWidth, right);
-
-        // Draw middle stretched region
-        int halfExt = EXTENSION_PX / 4;
-        drawRegion(bitmap, canvas, halfWidth - halfExt, halfWidth + halfExt,
-                left + halfWidth, right - halfWidth);
-    }
-
-    private void drawRegion(Bitmap bitmap, Canvas c,
-            int srcLeft, int srcRight, float dstLeft, float dstRight) {
-        mSrc.left = srcLeft;
-        mSrc.right = srcRight;
-
-        mDst.left = dstLeft;
-        mDst.right = dstRight;
-        c.drawBitmap(bitmap, mSrc, mDst, paint);
-    }
-}
diff --git a/src/com/android/launcher3/graphics/OverviewScrim.java b/src/com/android/launcher3/graphics/OverviewScrim.java
index 53303db..7d52744 100644
--- a/src/com/android/launcher3/graphics/OverviewScrim.java
+++ b/src/com/android/launcher3/graphics/OverviewScrim.java
@@ -25,6 +25,10 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import com.android.launcher3.R;
+import com.android.launcher3.uioverrides.WallpaperColorInfo;
+import com.android.launcher3.util.Themes;
+
 /**
  * View scrim which draws behind overview (recent apps).
  */
@@ -52,7 +56,7 @@
     public OverviewScrim(View view) {
         super(view);
 
-        onExtractedColorsChanged(mWallpaperColorInfo);
+        mScrimColor = Themes.getAttrColor(view.getContext(), R.attr.allAppsScrimColor);
     }
 
     /**
@@ -74,6 +78,11 @@
         }
     }
 
+    @Override
+    public void onExtractedColorsChanged(WallpaperColorInfo wallpaperColorInfo) {
+        // No super, don't respond to wallpaper colors, follow device ones instead
+    }
+
     /**
      * @return The view to draw the scrim behind, or null if all visible views should be scrimmed.
      */
diff --git a/src/com/android/launcher3/notification/NotificationListener.java b/src/com/android/launcher3/notification/NotificationListener.java
index 2905dc3..e58f5fa 100644
--- a/src/com/android/launcher3/notification/NotificationListener.java
+++ b/src/com/android/launcher3/notification/NotificationListener.java
@@ -16,9 +16,9 @@
 
 package com.android.launcher3.notification;
 
-import static com.android.launcher3.util.SettingsCache.NOTIFICATION_BADGING_URI;
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
 import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
+import static com.android.launcher3.util.SettingsCache.NOTIFICATION_BADGING_URI;
 
 import android.annotation.TargetApi;
 import android.app.Notification;
@@ -37,8 +37,8 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.WorkerThread;
 
-import com.android.launcher3.util.SettingsCache;
 import com.android.launcher3.util.PackageUserKey;
+import com.android.launcher3.util.SettingsCache;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -213,7 +213,7 @@
         mNotificationSettingsChangedListener = this::onNotificationSettingsChanged;
         mSettingsCache.register(NOTIFICATION_BADGING_URI,
                 mNotificationSettingsChangedListener);
-        mSettingsCache.dispatchOnChange(NOTIFICATION_BADGING_URI);
+        onNotificationSettingsChanged(mSettingsCache.getValue(NOTIFICATION_BADGING_URI));
 
         onNotificationFullRefresh();
     }
diff --git a/src/com/android/launcher3/settings/NotificationDotsPreference.java b/src/com/android/launcher3/settings/NotificationDotsPreference.java
index a354169..afcf882 100644
--- a/src/com/android/launcher3/settings/NotificationDotsPreference.java
+++ b/src/com/android/launcher3/settings/NotificationDotsPreference.java
@@ -17,6 +17,8 @@
 
 import static com.android.launcher3.settings.SettingsActivity.EXTRA_FRAGMENT_ARG_KEY;
 import static com.android.launcher3.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGS;
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.util.SettingsCache.NOTIFICATION_BADGING_URI;
 
 import android.app.AlertDialog;
 import android.app.Dialog;
@@ -24,6 +26,7 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
+import android.database.ContentObserver;
 import android.os.Bundle;
 import android.provider.Settings;
 import android.util.AttributeSet;
@@ -49,6 +52,14 @@
     /** Hidden field Settings.Secure.ENABLED_NOTIFICATION_LISTENERS */
     private static final String NOTIFICATION_ENABLED_LISTENERS = "enabled_notification_listeners";
 
+    private final ContentObserver mListenerListObserver =
+            new ContentObserver(MAIN_EXECUTOR.getHandler()) {
+        @Override
+        public void onChange(boolean selfChange) {
+            updateUI();
+        }
+    };
+
     public NotificationDotsPreference(
             Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
@@ -66,6 +77,29 @@
         super(context);
     }
 
+    @Override
+    public void onAttached() {
+        super.onAttached();
+        SettingsCache.INSTANCE.get(getContext()).register(NOTIFICATION_BADGING_URI, this);
+        getContext().getContentResolver().registerContentObserver(
+                Settings.Secure.getUriFor(NOTIFICATION_ENABLED_LISTENERS),
+                false, mListenerListObserver);
+        updateUI();
+    }
+
+    private void updateUI() {
+        onSettingsChanged(SettingsCache.INSTANCE.get(getContext())
+                .getValue(NOTIFICATION_BADGING_URI));
+    }
+
+    @Override
+    public void onDetached() {
+        super.onDetached();
+        SettingsCache.INSTANCE.get(getContext()).unregister(NOTIFICATION_BADGING_URI, this);
+        getContext().getContentResolver().unregisterContentObserver(mListenerListObserver);
+
+    }
+
     private void setWidgetFrameVisible(boolean isVisible) {
         if (mWidgetFrameVisible != isVisible) {
             mWidgetFrameVisible = isVisible;
diff --git a/src/com/android/launcher3/settings/SettingsActivity.java b/src/com/android/launcher3/settings/SettingsActivity.java
index f03065c..5b42ac7 100644
--- a/src/com/android/launcher3/settings/SettingsActivity.java
+++ b/src/com/android/launcher3/settings/SettingsActivity.java
@@ -18,8 +18,6 @@
 
 import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS;
 
-import static com.android.launcher3.util.SettingsCache.NOTIFICATION_BADGING_URI;
-import static com.android.launcher3.util.SettingsCache.NOTIFICATION_ENABLED_LISTENERS;
 import static com.android.launcher3.states.RotationHelper.ALLOW_ROTATION_PREFERENCE_KEY;
 import static com.android.launcher3.states.RotationHelper.getAllowRotationDefaultValue;
 
@@ -45,7 +43,6 @@
 import com.android.launcher3.Utilities;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.model.WidgetsModel;
-import com.android.launcher3.util.SettingsCache;
 import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
 
 /**
@@ -124,11 +121,8 @@
      */
     public static class LauncherSettingsFragment extends PreferenceFragmentCompat {
 
-        private SettingsCache mSettingsCache;
-
         private String mHighLightKey;
         private boolean mPreferenceHighlighted = false;
-        private NotificationDotsPreference mNotificationSettingsChangedListener;
         private Preference mDeveloperOptionPref;
 
         @Override
@@ -172,22 +166,7 @@
         protected boolean initPreference(Preference preference) {
             switch (preference.getKey()) {
                 case NOTIFICATION_DOTS_PREFERENCE_KEY:
-                    if (WidgetsModel.GO_DISABLE_NOTIFICATION_DOTS) {
-                        return false;
-                    }
-
-                    // Listen to system notification dot settings while this UI is active.
-                    mSettingsCache = SettingsCache.INSTANCE.get(getActivity());
-                    mNotificationSettingsChangedListener =
-                            ((NotificationDotsPreference) preference);
-                    mSettingsCache.register(NOTIFICATION_BADGING_URI,
-                            (NotificationDotsPreference) mNotificationSettingsChangedListener);
-                    // Also listen if notification permission changes
-                    mSettingsCache.register(NOTIFICATION_ENABLED_LISTENERS,
-                            mNotificationSettingsChangedListener);
-                    mSettingsCache.dispatchOnChange(NOTIFICATION_BADGING_URI);
-                    mSettingsCache.dispatchOnChange(NOTIFICATION_ENABLED_LISTENERS);
-                    return true;
+                    return !WidgetsModel.GO_DISABLE_NOTIFICATION_DOTS;
 
                 case ALLOW_ROTATION_PREFERENCE_KEY:
                     if (getResources().getBoolean(R.bool.allow_rotation)) {
@@ -269,16 +248,5 @@
                 }
             });
         }
-
-        @Override
-        public void onDestroy() {
-            if (mSettingsCache != null) {
-                mSettingsCache.unregister(NOTIFICATION_BADGING_URI,
-                        mNotificationSettingsChangedListener);
-                mSettingsCache.unregister(NOTIFICATION_ENABLED_LISTENERS,
-                        mNotificationSettingsChangedListener);
-            }
-            super.onDestroy();
-        }
     }
 }
diff --git a/src/com/android/launcher3/util/SettingsCache.java b/src/com/android/launcher3/util/SettingsCache.java
index 22b4d38..10611c7 100644
--- a/src/com/android/launcher3/util/SettingsCache.java
+++ b/src/com/android/launcher3/util/SettingsCache.java
@@ -39,12 +39,11 @@
  * {@link #unregister(Uri, OnChangeListener)} methods.
  *
  * This can be used as a normal cache without any listeners as well via the
- * {@link #getValue(Uri, int)} and {@link #dispatchOnChange(Uri)} to update (and subsequently call
+ * {@link #getValue(Uri, int)} and {@link #onChange)} to update (and subsequently call
  * get)
  *
  * The cache will be invalidated/updated through the normal
  * {@link ContentObserver#onChange(boolean)} calls
- * or can be force updated by calling {@link #dispatchOnChange(Uri)}.
  *
  * Cache will also be updated if a key queried is missing (even if it has no listeners registered).
  */
@@ -58,9 +57,6 @@
     /** Hidden field Settings.Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED */
     public static final String ONE_HANDED_SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED =
             "swipe_bottom_to_notification_enabled";
-    /** Hidden field Settings.Secure.ENABLED_NOTIFICATION_LISTENERS */
-    public static final Uri NOTIFICATION_ENABLED_LISTENERS =
-            Settings.Secure.getUriFor("enabled_notification_listeners");
     public static final Uri ROTATION_SETTING_URI =
             Settings.System.getUriFor(ACCELEROMETER_ROTATION);
 
@@ -103,6 +99,14 @@
      * Returns the value for this classes key from the cache. If not in cache, will call
      * {@link #updateValue(Uri, int)} to fetch.
      */
+    public boolean getValue(Uri keySetting) {
+        return getValue(keySetting, 1);
+    }
+
+    /**
+     * Returns the value for this classes key from the cache. If not in cache, will call
+     * {@link #updateValue(Uri, int)} to fetch.
+     */
     public boolean getValue(Uri keySetting, int defaultValue) {
         if (mKeyCache.containsKey(keySetting)) {
             return mKeyCache.get(keySetting);
@@ -140,14 +144,6 @@
     }
 
     /**
-     * Force update a change for a given URI and have all listeners for that URI receive callbacks
-     * even if the value is unchanged.
-     */
-    public void dispatchOnChange(Uri uri) {
-        onChange(true, uri);
-    }
-
-    /**
      * Call to stop receiving updates on the given {@param listener}.
      * This Uri/Listener pair must correspond to the same pair called with for
      * {@link #register(Uri, OnChangeListener)}
diff --git a/tests/src/com/android/launcher3/ui/WorkTabTest.java b/tests/src_disabled/WorkTabTest.java
similarity index 100%
rename from tests/src/com/android/launcher3/ui/WorkTabTest.java
rename to tests/src_disabled/WorkTabTest.java
diff --git a/tests/tapl/com/android/launcher3/tapl/Background.java b/tests/tapl/com/android/launcher3/tapl/Background.java
index d317783..4a666b1 100644
--- a/tests/tapl/com/android/launcher3/tapl/Background.java
+++ b/tests/tapl/com/android/launcher3/tapl/Background.java
@@ -122,7 +122,9 @@
                     endY = startY - swipeLength;
                 } else {
                     startX = getSwipeStartX();
-                    endX = startX - swipeLength;
+                    // TODO(b/184059820) make horizontal swipe use swipe width not height, for the
+                    // moment just double the swipe length.
+                    endX = startX - swipeLength * 2;
                     startY = endY = mLauncher.getDevice().getDisplayHeight() / 2;
                 }