Merge "Clearer diag for visible keyguard" into sc-dev
diff --git a/Android.bp b/Android.bp
index df0a96f..7e6a565 100644
--- a/Android.bp
+++ b/Android.bp
@@ -115,6 +115,9 @@
     manifest: "AndroidManifest-common.xml",
     sdk_version: "current",
     min_sdk_version: "26",
+    lint: {
+        baseline_filename: "lint-baseline-res-lib.xml",
+    },
 }
 
 //
@@ -127,6 +130,9 @@
     sdk_version: "current",
     min_sdk_version: "26",
     manifest: "AndroidManifest-common.xml",
+    lint: {
+        baseline_filename: "lint-baseline-common-deps-lib.xml",
+    },
 }
 
 //
@@ -171,6 +177,9 @@
     additional_manifests: [
         "AndroidManifest-common.xml",
     ],
+    lint: {
+        baseline_filename: "lint-baseline-launcher3.xml",
+    },
 }
 
 // Library with all the dependencies for building quickstep
@@ -236,5 +245,8 @@
         "AndroidManifest-common.xml",
     ],
     min_sdk_version: "29",
+    lint: {
+        baseline_filename: "lint-baseline-go-res-lib.xml",
+    },
 }
 
diff --git a/lint-baseline-common-deps-lib.xml b/lint-baseline-common-deps-lib.xml
new file mode 100644
index 0000000..e52f8fb
--- /dev/null
+++ b/lint-baseline-common-deps-lib.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+    <issue
+        id="NewApi"
+        message="`?android:attr/dialogCornerRadius` requires API level 28 (current min is 26)"
+        errorLine1="        android:topLeftRadius=&quot;?android:attr/dialogCornerRadius&quot;"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/res/drawable/add_item_dialog_background.xml"
+            line="6"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="`?android:attr/dialogCornerRadius` requires API level 28 (current min is 26)"
+        errorLine1="        android:topRightRadius=&quot;?android:attr/dialogCornerRadius&quot; />"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/res/drawable/add_item_dialog_background.xml"
+            line="7"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="`@android:style/Widget.DeviceDefault.Button.Colored` requires API level 28 (current min is 26)"
+        errorLine1="    &lt;style name=&quot;Widget.DeviceDefault.Button.Rounded.Colored&quot; parent=&quot;@android:style/Widget.DeviceDefault.Button.Colored&quot;>"
+        errorLine2="                                                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/res/values/styles.xml"
+            line="287"
+            column="63"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="`@android:dimen/system_app_widget_background_radius` requires API level 31 (current min is 26)"
+        errorLine1="    &lt;corners android:radius=&quot;@android:dimen/system_app_widget_background_radius&quot; />"
+        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/res/drawable/widget_resize_frame.xml"
+            line="20"
+            column="14"/>
+    </issue>
+
+</issues>
diff --git a/lint-baseline-go-res-lib.xml b/lint-baseline-go-res-lib.xml
new file mode 100644
index 0000000..c5669f2
--- /dev/null
+++ b/lint-baseline-go-res-lib.xml
@@ -0,0 +1,576 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 29): `android.view.View#getWindowInsetsController`"
+        errorLine1="        getWindowInsetsController().hide(WindowInsets.Type.ime());"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/allapps/AllAppsContainerView.java"
+            line="203"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 29): `android.view.WindowInsets.Type#ime`"
+        errorLine1="        getWindowInsetsController().hide(WindowInsets.Type.ime());"
+        errorLine2="                                                           ~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/allapps/AllAppsContainerView.java"
+            line="203"
+            column="60"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 29): `android.view.WindowInsetsController#hide`"
+        errorLine1="        getWindowInsetsController().hide(WindowInsets.Type.ime());"
+        errorLine2="                                    ~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/allapps/AllAppsContainerView.java"
+            line="203"
+            column="37"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 29): `android.view.View#getWindowInsetsController`"
+        errorLine1="                getWindowInsetsController().hide(WindowInsets.Type.ime());"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/allapps/AllAppsRecyclerView.java"
+            line="193"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 29): `android.view.WindowInsets.Type#ime`"
+        errorLine1="                getWindowInsetsController().hide(WindowInsets.Type.ime());"
+        errorLine2="                                                                   ~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/allapps/AllAppsRecyclerView.java"
+            line="193"
+            column="68"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 29): `android.view.WindowInsetsController#hide`"
+        errorLine1="                getWindowInsetsController().hide(WindowInsets.Type.ime());"
+        errorLine2="                                            ~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/allapps/AllAppsRecyclerView.java"
+            line="193"
+            column="45"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 29): `android.appwidget.AppWidgetHostView#updateAppWidgetSize`"
+        errorLine1="            widgetView.updateAppWidgetSize(new Bundle(), sizes);"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/AppWidgetResizeFrame.java"
+            line="399"
+            column="24"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 29): `android.graphics.Rect#inset`"
+        errorLine1="        potentialTaskRect.inset(insets.left, insets.top, insets.right, insets.bottom);"
+        errorLine2="                          ~~~~~">
+        <location
+            file="packages/apps/Launcher3/quickstep/src/com/android/quickstep/BaseActivityInterface.java"
+            line="248"
+            column="27"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 29): `android.graphics.Rect#inset`"
+        errorLine1="        potentialTaskRect.inset("
+        errorLine2="                          ~~~~~">
+        <location
+            file="packages/apps/Launcher3/quickstep/src/com/android/quickstep/BaseActivityInterface.java"
+            line="249"
+            column="27"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 29): `android.graphics.Rect#inset`"
+        errorLine1="        outRect.inset(Math.max(insets.left, sideMargin), Math.max(insets.top, topMargin),"
+        errorLine2="                ~~~~~">
+        <location
+            file="packages/apps/Launcher3/quickstep/src/com/android/quickstep/BaseActivityInterface.java"
+            line="291"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 29): `android.graphics.Rect#inset`"
+        errorLine1="        gridRect.inset(0, dp.overviewTaskThumbnailTopMarginPx, 0, 0);"
+        errorLine2="                 ~~~~~">
+        <location
+            file="packages/apps/Launcher3/quickstep/src/com/android/quickstep/BaseActivityInterface.java"
+            line="315"
+            column="18"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 29): `android.view.WindowManager#getCurrentWindowMetrics`"
+        errorLine1="                    .getCurrentWindowMetrics().getWindowInsets();"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/DeviceProfile.java"
+            line="236"
+            column="22"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 29): `android.view.WindowMetrics#getWindowInsets`"
+        errorLine1="                    .getCurrentWindowMetrics().getWindowInsets();"
+        errorLine2="                                               ~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/DeviceProfile.java"
+            line="236"
+            column="48"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 29): `android.content.Context#getDisplay`"
+        errorLine1="            if (mContext.getDisplay() != null) {"
+        errorLine2="                         ~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/quickstep/src/com/android/quickstep/interaction/EdgeBackGestureHandler.java"
+            line="115"
+            column="26"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 29): `android.content.Context#getDisplay`"
+        errorLine1="                mContext.getDisplay().getRealSize(mDisplaySize);"
+        errorLine2="                         ~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/quickstep/src/com/android/quickstep/interaction/EdgeBackGestureHandler.java"
+            line="116"
+            column="26"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 29): `android.content.ContextWrapper#getDisplay`"
+        errorLine1="        Display display = getDisplay();"
+        errorLine2="                          ~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java"
+            line="153"
+            column="27"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 29): `java.util.List#of`"
+        errorLine1="                    List.of(new Rect(0, 0, metrics.widthPixels, metrics.heightPixels)));"
+        errorLine2="                         ~~">
+        <location
+            file="packages/apps/Launcher3/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java"
+            line="158"
+            column="26"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 29): `android.appwidget.AppWidgetHostView#resetColorResources`"
+        errorLine1="            resetColorResources();"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java"
+            line="137"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 29): `java.util.List#of`"
+        errorLine1="            mColorExtractor.addLocation(List.of(mLastLocationRegistered));"
+        errorLine2="                                             ~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java"
+            line="367"
+            column="46"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 29): `java.util.List#of`"
+        errorLine1="                mColorExtractor.addLocation(List.of(mLastLocationRegistered));"
+        errorLine2="                                                 ~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java"
+            line="390"
+            column="50"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 31 (current min is 29): `android.appwidget.AppWidgetProviderInfo#maxResizeWidth`"
+        errorLine1="                (ATLEAST_S &amp;&amp; maxResizeWidth > 0)"
+        errorLine2="                              ~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java"
+            line="91"
+            column="31"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 31 (current min is 29): `android.appwidget.AppWidgetProviderInfo#maxResizeWidth`"
+        errorLine1="                        ? getSpanX(widgetPadding, maxResizeWidth, smallestCellWidth)"
+        errorLine2="                                                  ~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java"
+            line="92"
+            column="51"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 31 (current min is 29): `android.appwidget.AppWidgetProviderInfo#maxResizeHeight`"
+        errorLine1="                (ATLEAST_S &amp;&amp; maxResizeHeight > 0)"
+        errorLine2="                              ~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java"
+            line="95"
+            column="31"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 31 (current min is 29): `android.appwidget.AppWidgetProviderInfo#maxResizeHeight`"
+        errorLine1="                        ? getSpanY(widgetPadding, maxResizeHeight, smallestCellHeight)"
+        errorLine2="                                                  ~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java"
+            line="96"
+            column="51"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 31 (current min is 29): `android.appwidget.AppWidgetProviderInfo#targetCellWidth`"
+        errorLine1="        if (ATLEAST_S &amp;&amp; targetCellWidth >= minSpanX &amp;&amp; targetCellWidth &lt;= maxSpanX"
+        errorLine2="                         ~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java"
+            line="101"
+            column="26"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 31 (current min is 29): `android.appwidget.AppWidgetProviderInfo#targetCellWidth`"
+        errorLine1="        if (ATLEAST_S &amp;&amp; targetCellWidth >= minSpanX &amp;&amp; targetCellWidth &lt;= maxSpanX"
+        errorLine2="                                                        ~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java"
+            line="101"
+            column="57"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 31 (current min is 29): `android.appwidget.AppWidgetProviderInfo#targetCellHeight`"
+        errorLine1="                &amp;&amp; targetCellHeight >= minSpanY &amp;&amp; targetCellHeight &lt;= maxSpanY) {"
+        errorLine2="                   ~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java"
+            line="102"
+            column="20"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 31 (current min is 29): `android.appwidget.AppWidgetProviderInfo#targetCellHeight`"
+        errorLine1="                &amp;&amp; targetCellHeight >= minSpanY &amp;&amp; targetCellHeight &lt;= maxSpanY) {"
+        errorLine2="                                                   ~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java"
+            line="102"
+            column="52"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 31 (current min is 29): `android.appwidget.AppWidgetProviderInfo#targetCellWidth`"
+        errorLine1="            spanX = targetCellWidth;"
+        errorLine2="                    ~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java"
+            line="103"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 31 (current min is 29): `android.appwidget.AppWidgetProviderInfo#targetCellHeight`"
+        errorLine1="            spanY = targetCellHeight;"
+        errorLine2="                    ~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java"
+            line="104"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 29): `android.content.Context#getDisplay`"
+        errorLine1="        final Display display = mContext.getDisplay();"
+        errorLine2="                                         ~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java"
+            line="94"
+            column="42"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 29): `android.content.pm.LauncherActivityInfo#getLoadingProgress`"
+        errorLine1="            return (int) (100 * info.getLoadingProgress());"
+        errorLine2="                                     ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/util/PackageManagerHelper.java"
+            line="338"
+            column="38"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 29): `java.util.List#of`"
+        errorLine1="    private List&lt;WidgetsListBaseEntry> mAllWidgets = List.of();"
+        errorLine2="                                                          ~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/popup/PopupDataProvider.java"
+            line="64"
+            column="59"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 29): `java.util.List#of`"
+        errorLine1="    private List&lt;ItemInfo> mRecommendedWidgets = List.of();"
+        errorLine2="                                                      ~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/popup/PopupDataProvider.java"
+            line="66"
+            column="55"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 29): `new android.view.SurfaceControlViewHost`"
+        errorLine1="                    .submit(() -> new SurfaceControlViewHost(mContext, mDisplay, mHostToken))"
+        errorLine2="                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java"
+            line="91"
+            column="35"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 29): `android.view.SurfaceControlViewHost#getSurfacePackage`"
+        errorLine1="            surfacePackage = mSurfaceControlViewHost.getSurfacePackage();"
+        errorLine2="                                                     ~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java"
+            line="93"
+            column="54"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 29): `android.view.SurfaceControlViewHost#setView`"
+        errorLine1="                host.setView(view, view.getMeasuredWidth(), view.getMeasuredHeight());"
+        errorLine2="                     ~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java"
+            line="127"
+            column="22"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Cast from `SurfacePackage` to `Parcelable` requires API level 30 (current min is 29)"
+        errorLine1="        result.putParcelable(KEY_SURFACE_PACKAGE, surfacePackage);"
+        errorLine2="                                                  ~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java"
+            line="132"
+            column="51"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 29): `android.view.SurfaceControlViewHost#release`"
+        errorLine1="                mSurfaceControlViewHost.release();"
+        errorLine2="                                        ~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java"
+            line="149"
+            column="41"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 29): `android.graphics.Outline#setPath`"
+        errorLine1="        outline.setPath(mPath);"
+        errorLine2="                ~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/popup/RoundedArrowDrawable.java"
+            line="88"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 29): `new android.widget.EdgeEffect`"
+        errorLine1="                ? new EdgeEffect(context, attrs) : new EdgeEffect(context);"
+        errorLine2="                  ~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/views/SpringRelativeLayout.java"
+            line="49"
+            column="19"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 29): `new android.widget.EdgeEffect`"
+        errorLine1="                ? new EdgeEffect(context, attrs) : new EdgeEffect(context);"
+        errorLine2="                  ~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/views/SpringRelativeLayout.java"
+            line="51"
+            column="19"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 29): `android.view.WindowManager.LayoutParams#setFitInsetsTypes`"
+        errorLine1="        mWindowLayoutParams.setFitInsetsTypes(0);"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java"
+            line="316"
+            column="29"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 29): `android.view.WindowInsets#getInsets`"
+        errorLine1="            Insets systemInsets = insets.getInsets(WindowInsets.Type.systemBars());"
+        errorLine2="                                         ~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java"
+            line="118"
+            column="42"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 29): `android.view.WindowInsets.Type#systemBars`"
+        errorLine1="            Insets systemInsets = insets.getInsets(WindowInsets.Type.systemBars());"
+        errorLine2="                                                                     ~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java"
+            line="118"
+            column="70"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 29): `android.appwidget.AppWidgetProviderInfo#loadDescription`"
+        errorLine1="            CharSequence description = mItem.widgetInfo.loadDescription(getContext());"
+        errorLine2="                                                        ~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/WidgetCell.java"
+            line="193"
+            column="57"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 31 (current min is 29): `android.appwidget.AppWidgetProviderInfo#previewLayout`"
+        errorLine1="                &amp;&amp; item.widgetInfo.previewLayout != Resources.ID_NULL) {"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/WidgetCell.java"
+            line="214"
+            column="20"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 31 (current min is 29): `android.appwidget.AppWidgetProviderInfo#previewLayout`"
+        errorLine1="            launcherAppWidgetProviderInfo.initialLayout = item.widgetInfo.previewLayout;"
+        errorLine2="                                                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/WidgetCell.java"
+            line="222"
+            column="59"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 29): `android.view.View#getWindowInsetsController`"
+        errorLine1="        getWindowInsetsController().hide(WindowInsets.Type.ime());"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java"
+            line="558"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 29): `android.view.WindowInsets.Type#ime`"
+        errorLine1="        getWindowInsetsController().hide(WindowInsets.Type.ime());"
+        errorLine2="                                                           ~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java"
+            line="558"
+            column="60"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 29): `android.view.WindowInsetsController#hide`"
+        errorLine1="        getWindowInsetsController().hide(WindowInsets.Type.ime());"
+        errorLine2="                                    ~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java"
+            line="558"
+            column="37"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 29): `java.util.List#of`"
+        errorLine1="            return new RecommendationTableData(List.of(), previewScale);"
+        errorLine2="                                                    ~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java"
+            line="139"
+            column="53"/>
+    </issue>
+
+</issues>
diff --git a/lint-baseline-launcher3.xml b/lint-baseline-launcher3.xml
new file mode 100644
index 0000000..469ad94
--- /dev/null
+++ b/lint-baseline-launcher3.xml
@@ -0,0 +1,576 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 26): `android.view.View#getWindowInsetsController`"
+        errorLine1="        getWindowInsetsController().hide(WindowInsets.Type.ime());"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/allapps/AllAppsContainerView.java"
+            line="203"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 26): `android.view.WindowInsets.Type#ime`"
+        errorLine1="        getWindowInsetsController().hide(WindowInsets.Type.ime());"
+        errorLine2="                                                           ~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/allapps/AllAppsContainerView.java"
+            line="203"
+            column="60"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 26): `android.view.WindowInsetsController#hide`"
+        errorLine1="        getWindowInsetsController().hide(WindowInsets.Type.ime());"
+        errorLine2="                                    ~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/allapps/AllAppsContainerView.java"
+            line="203"
+            column="37"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 26): `android.view.View#getWindowInsetsController`"
+        errorLine1="                getWindowInsetsController().hide(WindowInsets.Type.ime());"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/allapps/AllAppsRecyclerView.java"
+            line="193"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 26): `android.view.WindowInsets.Type#ime`"
+        errorLine1="                getWindowInsetsController().hide(WindowInsets.Type.ime());"
+        errorLine2="                                                                   ~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/allapps/AllAppsRecyclerView.java"
+            line="193"
+            column="68"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 26): `android.view.WindowInsetsController#hide`"
+        errorLine1="                getWindowInsetsController().hide(WindowInsets.Type.ime());"
+        errorLine2="                                            ~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/allapps/AllAppsRecyclerView.java"
+            line="193"
+            column="45"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 26): `android.appwidget.AppWidgetHostView#updateAppWidgetSize`"
+        errorLine1="            widgetView.updateAppWidgetSize(new Bundle(), sizes);"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/AppWidgetResizeFrame.java"
+            line="399"
+            column="24"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 26): `android.view.WindowManager#getCurrentWindowMetrics`"
+        errorLine1="                    .getCurrentWindowMetrics().getWindowInsets();"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/DeviceProfile.java"
+            line="236"
+            column="22"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 26): `android.view.WindowMetrics#getWindowInsets`"
+        errorLine1="                    .getCurrentWindowMetrics().getWindowInsets();"
+        errorLine2="                                               ~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/DeviceProfile.java"
+            line="236"
+            column="48"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 26): `android.content.res.Resources#getFloat`"
+        errorLine1="        folderLabelTextScale = res.getFloat(R.dimen.folder_label_text_scale);"
+        errorLine2="                                   ~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/DeviceProfile.java"
+            line="256"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 26): `android.content.res.Resources#getFloat`"
+        errorLine1="        return mContext.getResources().getFloat(resId);"
+        errorLine2="                                       ~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/util/DynamicResource.java"
+            line="73"
+            column="40"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 26): `android.appwidget.AppWidgetHostView#resetColorResources`"
+        errorLine1="            resetColorResources();"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java"
+            line="137"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 26): `java.util.List#of`"
+        errorLine1="            mColorExtractor.addLocation(List.of(mLastLocationRegistered));"
+        errorLine2="                                             ~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java"
+            line="367"
+            column="46"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 26): `java.util.List#of`"
+        errorLine1="                mColorExtractor.addLocation(List.of(mLastLocationRegistered));"
+        errorLine2="                                                 ~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java"
+            line="390"
+            column="50"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 31 (current min is 26): `android.appwidget.AppWidgetProviderInfo#maxResizeWidth`"
+        errorLine1="                (ATLEAST_S &amp;&amp; maxResizeWidth > 0)"
+        errorLine2="                              ~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java"
+            line="91"
+            column="31"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 31 (current min is 26): `android.appwidget.AppWidgetProviderInfo#maxResizeWidth`"
+        errorLine1="                        ? getSpanX(widgetPadding, maxResizeWidth, smallestCellWidth)"
+        errorLine2="                                                  ~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java"
+            line="92"
+            column="51"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 31 (current min is 26): `android.appwidget.AppWidgetProviderInfo#maxResizeHeight`"
+        errorLine1="                (ATLEAST_S &amp;&amp; maxResizeHeight > 0)"
+        errorLine2="                              ~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java"
+            line="95"
+            column="31"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 31 (current min is 26): `android.appwidget.AppWidgetProviderInfo#maxResizeHeight`"
+        errorLine1="                        ? getSpanY(widgetPadding, maxResizeHeight, smallestCellHeight)"
+        errorLine2="                                                  ~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java"
+            line="96"
+            column="51"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 31 (current min is 26): `android.appwidget.AppWidgetProviderInfo#targetCellWidth`"
+        errorLine1="        if (ATLEAST_S &amp;&amp; targetCellWidth >= minSpanX &amp;&amp; targetCellWidth &lt;= maxSpanX"
+        errorLine2="                         ~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java"
+            line="101"
+            column="26"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 31 (current min is 26): `android.appwidget.AppWidgetProviderInfo#targetCellWidth`"
+        errorLine1="        if (ATLEAST_S &amp;&amp; targetCellWidth >= minSpanX &amp;&amp; targetCellWidth &lt;= maxSpanX"
+        errorLine2="                                                        ~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java"
+            line="101"
+            column="57"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 31 (current min is 26): `android.appwidget.AppWidgetProviderInfo#targetCellHeight`"
+        errorLine1="                &amp;&amp; targetCellHeight >= minSpanY &amp;&amp; targetCellHeight &lt;= maxSpanY) {"
+        errorLine2="                   ~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java"
+            line="102"
+            column="20"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 31 (current min is 26): `android.appwidget.AppWidgetProviderInfo#targetCellHeight`"
+        errorLine1="                &amp;&amp; targetCellHeight >= minSpanY &amp;&amp; targetCellHeight &lt;= maxSpanY) {"
+        errorLine2="                                                   ~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java"
+            line="102"
+            column="52"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 31 (current min is 26): `android.appwidget.AppWidgetProviderInfo#targetCellWidth`"
+        errorLine1="            spanX = targetCellWidth;"
+        errorLine2="                    ~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java"
+            line="103"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 31 (current min is 26): `android.appwidget.AppWidgetProviderInfo#targetCellHeight`"
+        errorLine1="            spanY = targetCellHeight;"
+        errorLine2="                    ~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java"
+            line="104"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 28 (current min is 26): `android.app.Person#getKey`"
+        errorLine1="        return people.stream().filter(person -> person.getKey() != null)"
+        errorLine2="                                                       ~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/notification/NotificationKeyData.java"
+            line="72"
+            column="56"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Method reference requires API level 28 (current min is 26): `Person::getKey`"
+        errorLine1="                .map(Person::getKey).sorted().toArray(String[]::new);"
+        errorLine2="                     ~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/notification/NotificationKeyData.java"
+            line="73"
+            column="22"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 26): `android.content.pm.LauncherActivityInfo#getLoadingProgress`"
+        errorLine1="            return (int) (100 * info.getLoadingProgress());"
+        errorLine2="                                     ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/util/PackageManagerHelper.java"
+            line="338"
+            column="38"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 29 (current min is 26): `android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_PAGE_LEFT`"
+        errorLine1="                AccessibilityNodeInfo.AccessibilityAction.ACTION_PAGE_LEFT"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/PagedView.java"
+            line="1752"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 29 (current min is 26): `android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_PAGE_RIGHT`"
+        errorLine1="                : AccessibilityNodeInfo.AccessibilityAction.ACTION_PAGE_RIGHT);"
+        errorLine2="                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/PagedView.java"
+            line="1753"
+            column="19"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 29 (current min is 26): `android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_PAGE_RIGHT`"
+        errorLine1="                AccessibilityNodeInfo.AccessibilityAction.ACTION_PAGE_RIGHT"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/PagedView.java"
+            line="1760"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 29 (current min is 26): `android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_PAGE_LEFT`"
+        errorLine1="                : AccessibilityNodeInfo.AccessibilityAction.ACTION_PAGE_LEFT);"
+        errorLine2="                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/PagedView.java"
+            line="1761"
+            column="19"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 26): `java.util.List#of`"
+        errorLine1="    private List&lt;WidgetsListBaseEntry> mAllWidgets = List.of();"
+        errorLine2="                                                          ~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/popup/PopupDataProvider.java"
+            line="64"
+            column="59"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 26): `java.util.List#of`"
+        errorLine1="    private List&lt;ItemInfo> mRecommendedWidgets = List.of();"
+        errorLine2="                                                      ~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/popup/PopupDataProvider.java"
+            line="66"
+            column="55"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 26): `new android.view.SurfaceControlViewHost`"
+        errorLine1="                    .submit(() -> new SurfaceControlViewHost(mContext, mDisplay, mHostToken))"
+        errorLine2="                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java"
+            line="91"
+            column="35"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 26): `android.view.SurfaceControlViewHost#getSurfacePackage`"
+        errorLine1="            surfacePackage = mSurfaceControlViewHost.getSurfacePackage();"
+        errorLine2="                                                     ~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java"
+            line="93"
+            column="54"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 26): `android.view.SurfaceControlViewHost#setView`"
+        errorLine1="                host.setView(view, view.getMeasuredWidth(), view.getMeasuredHeight());"
+        errorLine2="                     ~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java"
+            line="127"
+            column="22"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Cast from `SurfacePackage` to `Parcelable` requires API level 30 (current min is 26)"
+        errorLine1="        result.putParcelable(KEY_SURFACE_PACKAGE, surfacePackage);"
+        errorLine2="                                                  ~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java"
+            line="132"
+            column="51"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 26): `android.view.SurfaceControlViewHost#release`"
+        errorLine1="                mSurfaceControlViewHost.release();"
+        errorLine2="                                        ~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java"
+            line="149"
+            column="41"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 26): `android.graphics.Outline#setPath`"
+        errorLine1="        outline.setPath(mPath);"
+        errorLine2="                ~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/popup/RoundedArrowDrawable.java"
+            line="88"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 26): `new android.widget.EdgeEffect`"
+        errorLine1="                ? new EdgeEffect(context, attrs) : new EdgeEffect(context);"
+        errorLine2="                  ~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/views/SpringRelativeLayout.java"
+            line="49"
+            column="19"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 26): `new android.widget.EdgeEffect`"
+        errorLine1="                ? new EdgeEffect(context, attrs) : new EdgeEffect(context);"
+        errorLine2="                  ~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/views/SpringRelativeLayout.java"
+            line="51"
+            column="19"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 29 (current min is 26): `android.view.WindowInsets#getTappableElementInsets`"
+        errorLine1="            return windowInsets.getTappableElementInsets().bottom > 0;"
+        errorLine2="                                ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/graphics/SysUiScrim.java"
+            line="190"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 29 (current min is 26): `android.graphics.Insets#bottom`"
+        errorLine1="            return windowInsets.getTappableElementInsets().bottom > 0;"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/graphics/SysUiScrim.java"
+            line="190"
+            column="20"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 28 (current min is 26): `android.appwidget.AppWidgetProviderInfo#widgetFeatures`"
+        errorLine1="        int featureFlags = mProviderInfo.widgetFeatures;"
+        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/WidgetAddFlowHandler.java"
+            line="93"
+            column="28"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 26): `android.appwidget.AppWidgetProviderInfo#loadDescription`"
+        errorLine1="            CharSequence description = mItem.widgetInfo.loadDescription(getContext());"
+        errorLine2="                                                        ~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/WidgetCell.java"
+            line="193"
+            column="57"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 31 (current min is 26): `android.appwidget.AppWidgetProviderInfo#previewLayout`"
+        errorLine1="                &amp;&amp; item.widgetInfo.previewLayout != Resources.ID_NULL) {"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/WidgetCell.java"
+            line="214"
+            column="20"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Field requires API level 31 (current min is 26): `android.appwidget.AppWidgetProviderInfo#previewLayout`"
+        errorLine1="            launcherAppWidgetProviderInfo.initialLayout = item.widgetInfo.previewLayout;"
+        errorLine2="                                                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/WidgetCell.java"
+            line="222"
+            column="59"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 26): `android.view.View#getWindowInsetsController`"
+        errorLine1="        getWindowInsetsController().hide(WindowInsets.Type.ime());"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java"
+            line="558"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 26): `android.view.WindowInsets.Type#ime`"
+        errorLine1="        getWindowInsetsController().hide(WindowInsets.Type.ime());"
+        errorLine2="                                                           ~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java"
+            line="558"
+            column="60"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 26): `android.view.WindowInsetsController#hide`"
+        errorLine1="        getWindowInsetsController().hide(WindowInsets.Type.ime());"
+        errorLine2="                                    ~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java"
+            line="558"
+            column="37"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level R (current min is 26): `java.util.List#of`"
+        errorLine1="            return new RecommendationTableData(List.of(), previewScale);"
+        errorLine2="                                                    ~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java"
+            line="139"
+            column="53"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Method reference requires API level 28 (current min is 26): `Person::getKey`"
+        errorLine1="            : Arrays.stream(persons).map(Person::getKey).sorted().toArray(String[]::new);"
+        errorLine2="                                         ~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/src/com/android/launcher3/model/data/WorkspaceItemInfo.java"
+            line="178"
+            column="42"/>
+    </issue>
+
+</issues>
diff --git a/lint-baseline-res-lib.xml b/lint-baseline-res-lib.xml
new file mode 100644
index 0000000..e52f8fb
--- /dev/null
+++ b/lint-baseline-res-lib.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+    <issue
+        id="NewApi"
+        message="`?android:attr/dialogCornerRadius` requires API level 28 (current min is 26)"
+        errorLine1="        android:topLeftRadius=&quot;?android:attr/dialogCornerRadius&quot;"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/res/drawable/add_item_dialog_background.xml"
+            line="6"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="`?android:attr/dialogCornerRadius` requires API level 28 (current min is 26)"
+        errorLine1="        android:topRightRadius=&quot;?android:attr/dialogCornerRadius&quot; />"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/res/drawable/add_item_dialog_background.xml"
+            line="7"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="`@android:style/Widget.DeviceDefault.Button.Colored` requires API level 28 (current min is 26)"
+        errorLine1="    &lt;style name=&quot;Widget.DeviceDefault.Button.Rounded.Colored&quot; parent=&quot;@android:style/Widget.DeviceDefault.Button.Colored&quot;>"
+        errorLine2="                                                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/res/values/styles.xml"
+            line="287"
+            column="63"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="`@android:dimen/system_app_widget_background_radius` requires API level 31 (current min is 26)"
+        errorLine1="    &lt;corners android:radius=&quot;@android:dimen/system_app_widget_background_radius&quot; />"
+        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="packages/apps/Launcher3/res/drawable/widget_resize_frame.xml"
+            line="20"
+            column="14"/>
+    </issue>
+
+</issues>
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
index e9ded8a..4415b51 100644
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
@@ -219,7 +219,7 @@
         mSplitPlaceholderView = findViewById(R.id.split_placeholder);
         RecentsView overviewPanel = (RecentsView) getOverviewPanel();
         mSplitPlaceholderView.init(
-                new SplitSelectStateController(SystemUiProxy.INSTANCE.get(this))
+                new SplitSelectStateController(mHandler, SystemUiProxy.INSTANCE.get(this))
         );
         overviewPanel.init(mActionsView, mSplitPlaceholderView);
         mActionsView.updateVerticalMargin(SysUINavigationMode.getMode(this));
diff --git a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
index e13d1a4..8168e88 100644
--- a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
@@ -27,6 +27,7 @@
 import androidx.annotation.Nullable;
 
 import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.statemanager.StateManager;
 import com.android.launcher3.touch.PagedOrientationHandler;
 import com.android.quickstep.fallback.RecentsState;
 import com.android.quickstep.util.ActivityInitListener;
@@ -139,7 +140,25 @@
 
     @Override
     public void onExitOverview(RotationTouchHelper deviceState, Runnable exitRunnable) {
-        // no-op, fake landscape not supported for 3P
+        final StateManager<RecentsState> stateManager = getCreatedActivity().getStateManager();
+        if (stateManager.getState() == HOME) {
+            exitRunnable.run();
+            notifyRecentsOfOrientation(deviceState);
+            return;
+        }
+
+        stateManager.addStateListener(
+                new StateManager.StateListener<RecentsState>() {
+                    @Override
+                    public void onStateTransitionComplete(RecentsState toState) {
+                        // Are we going from Recents to Workspace?
+                        if (toState == HOME) {
+                            exitRunnable.run();
+                            notifyRecentsOfOrientation(deviceState);
+                            stateManager.removeStateListener(this);
+                        }
+                    }
+                });
     }
 
     @Override
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
index 06137f2..7c453e7 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -108,8 +108,7 @@
 
         SplitPlaceholderView splitPlaceholderView = findViewById(R.id.split_placeholder);
         splitPlaceholderView.init(
-                new SplitSelectStateController(
-                        SystemUiProxy.INSTANCE.get(this))
+                new SplitSelectStateController(mUiHandler, SystemUiProxy.INSTANCE.get(this))
         );
 
         mDragLayer.recreateControllers();
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index 1f332c4..0ee28bc 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -35,6 +35,7 @@
 import android.view.MotionEvent;
 
 import com.android.launcher3.util.MainThreadInitializedObject;
+import com.android.launcher3.util.SplitConfigurationOptions;
 import com.android.systemui.shared.recents.ISystemUiProxy;
 import com.android.systemui.shared.recents.model.Task;
 import com.android.systemui.shared.system.RemoteTransitionCompat;
@@ -491,6 +492,20 @@
         }
     }
 
+    /** Start multiple tasks in split-screen simultaneously. */
+    public void startTasks(int mainTaskId, Bundle mainOptions, int sideTaskId, Bundle sideOptions,
+            @SplitConfigurationOptions.StagePosition int sidePosition,
+            RemoteTransitionCompat remoteTransition) {
+        if (mSystemUiProxy != null) {
+            try {
+                mSplitScreen.startTasks(mainTaskId, mainOptions, sideTaskId, sideOptions,
+                        sidePosition, remoteTransition.getTransition());
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call startTask");
+            }
+        }
+    }
+
     public void startShortcut(String packageName, String shortcutId, int stage, int position,
             Bundle options, UserHandle user) {
         if (mSplitScreen != null) {
diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java
index bea1250..cbb2a66 100644
--- a/quickstep/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java
@@ -15,6 +15,9 @@
  */
 package com.android.quickstep;
 
+import static android.view.WindowManager.TRANSIT_OPEN;
+import static android.view.WindowManager.TRANSIT_TO_FRONT;
+
 import static com.android.launcher3.LauncherAnimUtils.VIEW_ALPHA;
 import static com.android.launcher3.LauncherState.BACKGROUND_APP;
 import static com.android.launcher3.LauncherState.NORMAL;
@@ -47,7 +50,9 @@
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.os.Build;
+import android.view.SurfaceControl;
 import android.view.View;
+import android.window.TransitionInfo;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -352,7 +357,47 @@
      * device is considered in multiWindowMode and things like insets and stuff change
      * and calculations have to be adjusted in the animations for that
      */
-    public static void composeRecentsSplitLaunchAnimator(@NonNull AnimatorSet anim,
+    public static void composeRecentsSplitLaunchAnimator(@NonNull TaskView initialView,
+            @NonNull TaskView v, @NonNull TransitionInfo transitionInfo,
+            SurfaceControl.Transaction t, @NonNull Runnable finishCallback) {
+
+        final TransitionInfo.Change[] splitRoots = new TransitionInfo.Change[2];
+        for (int i = 0; i < transitionInfo.getChanges().size(); ++i) {
+            final TransitionInfo.Change change = transitionInfo.getChanges().get(i);
+            final int taskId = change.getTaskInfo() != null ? change.getTaskInfo().taskId : -1;
+            final int mode = change.getMode();
+            // Find the target tasks' root tasks since those are the split stages that need to
+            // be animated (the tasks themselves are children and thus inherit animation).
+            if (taskId == initialView.getTask().key.id || taskId == v.getTask().key.id) {
+                if (!(mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT)) {
+                    throw new IllegalStateException(
+                            "Expected task to be showing, but it is " + mode);
+                }
+                if (change.getParent() == null) {
+                    throw new IllegalStateException("Initiating multi-split launch but the split"
+                            + "root of " + taskId + " is already visible or has broken hierarchy.");
+                }
+                splitRoots[taskId == initialView.getTask().key.id ? 0 : 1] =
+                        transitionInfo.getChange(change.getParent());
+            }
+        }
+
+        // This is where we should animate the split roots. For now, though, just make them visible.
+        for (int i = 0; i < 2; ++i) {
+            t.show(splitRoots[i].getLeash());
+            t.setAlpha(splitRoots[i].getLeash(), 1.f);
+        }
+
+        // This contains the initial state (before animation), so apply this at the beginning of
+        // the animation.
+        t.apply();
+
+        // Once there is an animation, this should be called AFTER the animation completes.
+        finishCallback.run();
+    }
+
+    /** Legacy version (until shell transitions are enabled) */
+    public static void composeRecentsSplitLaunchAnimatorLegacy(@NonNull AnimatorSet anim,
             @NonNull TaskView v, @NonNull RemoteAnimationTargetCompat[] appTargets,
             @NonNull RemoteAnimationTargetCompat[] wallpaperTargets,
             @NonNull RemoteAnimationTargetCompat[] nonAppTargets, boolean launcherClosing,
diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
index e3f2925..9576eac 100644
--- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
@@ -16,11 +16,17 @@
 
 package com.android.quickstep.util;
 
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
+import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
+
 import android.animation.AnimatorSet;
 import android.app.ActivityOptions;
 import android.os.Handler;
 import android.os.Looper;
 import android.util.Pair;
+import android.view.SurfaceControl;
+import android.window.TransitionInfo;
 
 import androidx.annotation.Nullable;
 
@@ -31,12 +37,15 @@
 import com.android.launcher3.WrappedLauncherAnimationRunner;
 import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
 import com.android.quickstep.SystemUiProxy;
+import com.android.quickstep.TaskAnimationManager;
 import com.android.quickstep.TaskViewUtils;
 import com.android.quickstep.views.TaskView;
 import com.android.systemui.shared.system.ActivityOptionsCompat;
 import com.android.systemui.shared.system.RemoteAnimationAdapterCompat;
 import com.android.systemui.shared.system.RemoteAnimationRunnerCompat;
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
+import com.android.systemui.shared.system.RemoteTransitionCompat;
+import com.android.systemui.shared.system.RemoteTransitionRunner;
 
 /**
  * Represent data needed for the transient state when user has selected one app for split screen
@@ -47,9 +56,11 @@
     private final SystemUiProxy mSystemUiProxy;
     private TaskView mInitialTaskView;
     private SplitPositionOption mInitialPosition;
+    private final Handler mHandler;
 
-    public SplitSelectStateController(SystemUiProxy systemUiProxy) {
+    public SplitSelectStateController(Handler handler, SystemUiProxy systemUiProxy) {
         mSystemUiProxy = systemUiProxy;
+        mHandler = handler;
     }
 
     /**
@@ -64,6 +75,19 @@
      * To be called after second task selected
      */
     public void setSecondTaskId(TaskView taskView) {
+        if (TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) {
+            // Assume initial task is for top/left part of screen
+            final int[] taskIds = mInitialPosition.mStagePosition == STAGE_POSITION_TOP_OR_LEFT
+                    ? new int[]{mInitialTaskView.getTask().key.id, taskView.getTask().key.id}
+                    : new int[]{taskView.getTask().key.id, mInitialTaskView.getTask().key.id};
+
+            RemoteSplitLaunchAnimationRunner animationRunner =
+                    new RemoteSplitLaunchAnimationRunner(mInitialTaskView, taskView);
+            mSystemUiProxy.startTasks(taskIds[0], null /* mainOptions */, taskIds[1],
+                    null /* sideOptions */, STAGE_POSITION_BOTTOM_OR_RIGHT,
+                    new RemoteTransitionCompat(animationRunner, MAIN_EXECUTOR));
+            return;
+        }
         // Assume initial mInitialTaskId is for top/left part of screen
         WrappedAnimationRunnerImpl initialSplitRunnerWrapped =  new SplitLaunchAnimationRunner(
                 mInitialTaskView, 0);
@@ -96,6 +120,30 @@
     }
 
     /**
+     * Requires Shell Transitions
+     */
+    private class RemoteSplitLaunchAnimationRunner implements RemoteTransitionRunner {
+
+        private final TaskView mInitialTaskView;
+        private final TaskView mTaskView;
+
+        RemoteSplitLaunchAnimationRunner(TaskView initialTaskView, TaskView taskView) {
+            mInitialTaskView = initialTaskView;
+            mTaskView = taskView;
+        }
+
+        @Override
+        public void startAnimation(TransitionInfo info, SurfaceControl.Transaction t,
+                Runnable finishCallback) {
+            TaskViewUtils.composeRecentsSplitLaunchAnimator(mInitialTaskView, mTaskView,
+                    info, t, finishCallback);
+            // After successful launch, call resetState
+            resetState();
+        }
+    }
+
+    /**
+     * LEGACY
      * @return the opposite stage and position from the {@param position} provided as first and
      *         second object, respectively
      * Ex. If position is has stage = Main and position = Top/Left, this will return
@@ -109,6 +157,7 @@
     }
 
     /**
+     * LEGACY
      * Remote animation runner for animation to launch an app.
      */
     private class SplitLaunchAnimationRunner implements WrappedAnimationRunnerImpl {
@@ -129,7 +178,7 @@
                 LauncherAnimationRunner.AnimationResult result) {
             AnimatorSet anim = new AnimatorSet();
             BaseQuickstepLauncher activity = BaseActivity.fromContext(mV.getContext());
-            TaskViewUtils.composeRecentsSplitLaunchAnimator(anim, mV,
+            TaskViewUtils.composeRecentsSplitLaunchAnimatorLegacy(anim, mV,
                     appTargets, wallpaperTargets, nonAppTargets, true, activity.getStateManager(),
                     activity.getDepthController(), mTargetState);
             result.setAnimation(anim, activity);
diff --git a/res/drawable/ic_allapps_search.xml b/res/drawable/ic_allapps_search.xml
index c0e20f1..dbed824 100644
--- a/res/drawable/ic_allapps_search.xml
+++ b/res/drawable/ic_allapps_search.xml
@@ -17,7 +17,8 @@
     android:width="24dp"
     android:height="24dp"
     android:viewportHeight="24.0"
-    android:viewportWidth="24.0">
+    android:viewportWidth="24.0"
+    android:autoMirrored="true">
     <path
         android:fillColor="?android:attr/textColorTertiary"
         android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z" />
diff --git a/res/layout/widgets_list_row_header.xml b/res/layout/widgets_list_row_header.xml
index 598041c..8259c16 100644
--- a/res/layout/widgets_list_row_header.xml
+++ b/res/layout/widgets_list_row_header.xml
@@ -15,6 +15,7 @@
 -->
 <com.android.launcher3.widget.picker.WidgetsListHeader xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
     android:id="@+id/widgets_list_header"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
@@ -22,7 +23,8 @@
     android:background="@drawable/widgets_list_middle_ripple"
     android:layout_marginBottom="@dimen/widget_list_entry_bottom_margin"
     android:paddingVertical="@dimen/widget_list_header_view_vertical_padding"
-    android:orientation="horizontal">
+    android:orientation="horizontal"
+    launcher:appIconSize="48dp">
 
     <ImageView
         android:id="@+id/app_icon"
diff --git a/res/layout/widgets_search_bar.xml b/res/layout/widgets_search_bar.xml
index e3836df..c3dd19e 100644
--- a/res/layout/widgets_search_bar.xml
+++ b/res/layout/widgets_search_bar.xml
@@ -13,7 +13,9 @@
         android:id="@+id/widgets_search_bar_edit_text"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:padding="12dp"
+        android:paddingVertical="12dp"
+        android:paddingStart="12dp"
+        android:paddingEnd="0dp"
         android:drawablePadding="8dp"
         android:drawableStart="@drawable/ic_allapps_search"
         android:background="@null"
@@ -21,6 +23,7 @@
         android:maxLines="1"
         android:layout_weight="1"
         android:inputType="text"
+        android:imeOptions="actionSearch"
         android:textColor="?android:attr/textColorSecondary"
         android:textColorHint="?android:attr/textColorTertiary"/>
 
@@ -28,7 +31,9 @@
         android:id="@+id/widgets_search_cancel_button"
         android:layout_height="wrap_content"
         android:layout_width="wrap_content"
-        android:padding="8dp"
+        android:paddingVertical="12dp"
+        android:paddingStart="8dp"
+        android:paddingEnd="12dp"
         android:src="@drawable/ic_gm_close_24"
         android:background="?android:selectableItemBackground"
         android:layout_gravity="center"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 986180c..9072907 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -95,6 +95,9 @@
     <!-- Tab label. A user can tap this tab to access their work widgets. [CHAR_LIMIT=25] -->
     <string name="widgets_full_sheet_work_tab">Work</string>
 
+    <!-- A widget category label for grouping widgets related to conversations. [CHAR_LIMIT=30] -->
+    <string name="widget_category_conversations">Conversations</string>
+
     <!-- All Apps -->
     <!-- Search bar text in the apps view. [CHAR_LIMIT=50] -->
     <string name="all_apps_search_bar_hint">Search apps</string>
diff --git a/res/xml/launcher_preferences.xml b/res/xml/launcher_preferences.xml
index e4bea50..8195cc1 100644
--- a/res/xml/launcher_preferences.xml
+++ b/res/xml/launcher_preferences.xml
@@ -22,14 +22,7 @@
         android:key="pref_icon_badging"
         android:title="@string/notification_dots_title"
         android:persistent="false"
-        android:widgetLayout="@layout/notification_pref_warning" >
-        <intent android:action="android.settings.NOTIFICATION_SETTINGS">
-            <!-- This extra highlights the "Allow notification dots" field in Notification settings -->
-            <extra
-                android:name=":settings:fragment_args_key"
-                android:value="notification_badging" />
-        </intent>
-    </com.android.launcher3.settings.NotificationDotsPreference>
+        android:widgetLayout="@layout/notification_pref_warning" />
 
     <!--
       LAUNCHER_ADD_NEW_APPS_TO_HOME_SCREEN_ENABLED(613)
diff --git a/robolectric_tests/src/com/android/launcher3/model/BackupRestoreTest.java b/robolectric_tests/src/com/android/launcher3/model/BackupRestoreTest.java
index 8baf5a3..adf720f 100644
--- a/robolectric_tests/src/com/android/launcher3/model/BackupRestoreTest.java
+++ b/robolectric_tests/src/com/android/launcher3/model/BackupRestoreTest.java
@@ -35,6 +35,7 @@
 import android.content.pm.PackageInstaller;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
+import android.os.Process;
 import android.os.UserHandle;
 import android.os.UserManager;
 
@@ -64,17 +65,11 @@
     private static final long OLD_WORK_PROFILE_ID = 11;
     private static final int WORK_PROFILE_ID = 10;
 
-    private static final int SYSTEM_USER = 0;
-    private static final int FLAG_SYSTEM = 0x00000800;
-    private static final int FLAG_PROFILE = 0x00001000;
-
     private ShadowUserManager mUserManager;
     private BackupManager mBackupManager;
     private LauncherModelHelper mModelHelper;
     private SQLiteDatabase mDb;
     private InvariantDeviceProfile mIdp;
-    private UserHandle mMainProfileUser;
-    private UserHandle mWorkProfileUser;
 
     @Before
     public void setUp() {
@@ -90,17 +85,15 @@
         final UserManager userManager = RuntimeEnvironment.application.getSystemService(
                 UserManager.class);
         mUserManager = Shadow.extract(userManager);
-        // sign in to primary user
-        mMainProfileUser = mUserManager.addUser(SYSTEM_USER, "me", FLAG_SYSTEM);
         // sign in to work profile
-        mWorkProfileUser = mUserManager.addUser(WORK_PROFILE_ID, "work", FLAG_PROFILE);
+        mUserManager.addUser(WORK_PROFILE_ID, "work", ShadowUserManager.FLAG_MANAGED_PROFILE);
     }
 
     private void setupBackupManager() {
         mBackupManager = new BackupManager(RuntimeEnvironment.application);
         final LShadowBackupManager bm = Shadow.extract(mBackupManager);
-        bm.addProfile(MY_OLD_PROFILE_ID, mMainProfileUser);
-        bm.addProfile(OLD_WORK_PROFILE_ID, mWorkProfileUser);
+        bm.addProfile(MY_OLD_PROFILE_ID, Process.myUserHandle());
+        bm.addProfile(OLD_WORK_PROFILE_ID, UserHandle.of(WORK_PROFILE_ID));
     }
 
     @Test
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 01f7c71..7496703 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -926,8 +926,7 @@
         if (disallowIntercept) {
             // We need to make sure to cancel our long press if
             // a scrollable widget takes over touch events
-            final View currentPage = getPageAt(mCurrentPage);
-            currentPage.cancelLongPress();
+            cancelCurrentPageLongPress();
         }
         super.requestDisallowInterceptTouchEvent(disallowIntercept);
     }
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index a1b7997..cf1cb45 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -78,7 +78,6 @@
 import com.android.launcher3.R;
 import com.android.launcher3.ShortcutAndWidgetContainer;
 import com.android.launcher3.Utilities;
-import com.android.launcher3.Workspace;
 import com.android.launcher3.Workspace.ItemOperator;
 import com.android.launcher3.accessibility.AccessibleDragListenerAdapter;
 import com.android.launcher3.accessibility.FolderAccessibilityHelper;
@@ -534,9 +533,25 @@
     }
 
     private void startAnimation(final AnimatorSet a) {
-        final Workspace workspace = mLauncher.getWorkspace();
-        final CellLayout currentCellLayout =
-                (CellLayout) workspace.getChildAt(workspace.getCurrentPage());
+        mLauncher.getWorkspace().getVisiblePages()
+                .forEach(visiblePage -> addAnimatorListenerForPage(a, (CellLayout) visiblePage));
+
+        a.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationStart(Animator animation) {
+                mState = STATE_ANIMATING;
+                mCurrentAnimator = a;
+            }
+
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mCurrentAnimator = null;
+            }
+        });
+        a.start();
+    }
+
+    private void addAnimatorListenerForPage(AnimatorSet a, CellLayout currentCellLayout) {
         final boolean useHardware = shouldUseHardwareLayerForAnimation(currentCellLayout);
         final boolean wasHardwareAccelerated = currentCellLayout.isHardwareLayerEnabled();
 
@@ -546,8 +561,6 @@
                 if (useHardware) {
                     currentCellLayout.enableHardwareLayer(true);
                 }
-                mState = STATE_ANIMATING;
-                mCurrentAnimator = a;
             }
 
             @Override
@@ -555,10 +568,8 @@
                 if (useHardware) {
                     currentCellLayout.enableHardwareLayer(wasHardwareAccelerated);
                 }
-                mCurrentAnimator = null;
             }
         });
-        a.start();
     }
 
     private boolean shouldUseHardwareLayerForAnimation(CellLayout currentCellLayout) {
diff --git a/src/com/android/launcher3/icons/IconCache.java b/src/com/android/launcher3/icons/IconCache.java
index 988794c..a2c0f5c 100644
--- a/src/com/android/launcher3/icons/IconCache.java
+++ b/src/com/android/launcher3/icons/IconCache.java
@@ -39,6 +39,7 @@
 
 import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.LauncherFiles;
+import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.icons.ComponentWithLabel.ComponentCachingLogic;
@@ -304,6 +305,11 @@
         CacheEntry entry = getEntryForPackageLocked(
                 infoInOut.packageName, infoInOut.user, useLowResIcon);
         applyCacheEntry(entry, infoInOut);
+        if (infoInOut.category == PackageItemInfo.CONVERSATIONS) {
+            infoInOut.title = mContext.getString(R.string.widget_category_conversations);
+            infoInOut.contentDescription = mPackageManager.getUserBadgedLabel(
+                    infoInOut.title, infoInOut.user);
+        }
     }
 
     protected void applyCacheEntry(CacheEntry entry, ItemInfoWithIcon info) {
diff --git a/src/com/android/launcher3/model/data/PackageItemInfo.java b/src/com/android/launcher3/model/data/PackageItemInfo.java
index 7617d7e..a81fe6a 100644
--- a/src/com/android/launcher3/model/data/PackageItemInfo.java
+++ b/src/com/android/launcher3/model/data/PackageItemInfo.java
@@ -16,27 +16,47 @@
 
 package com.android.launcher3.model.data;
 
+import androidx.annotation.IntDef;
+
 import com.android.launcher3.LauncherSettings;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.Objects;
 
 /**
  * Represents a {@link Package} in the widget tray section.
  */
 public class PackageItemInfo extends ItemInfoWithIcon {
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({NO_CATEGORY, CONVERSATIONS})
+    public @interface Category{}
+    /** The package is not categorized in the widget tray. */
+    public static final int NO_CATEGORY = 0;
+    /** The package is categorized to conversations widget in the widget tray. */
+    public static final int CONVERSATIONS = 1;
 
     /**
      * Package name of the {@link PackageItemInfo}.
      */
-    public String packageName;
+    public final String packageName;
+
+    /** Represents a widget category shown in the widget tray section. */
+    @Category public final int category;
 
     public PackageItemInfo(String packageName) {
+        this(packageName, NO_CATEGORY);
+    }
+
+    public PackageItemInfo(String packageName, @Category int category) {
         this.packageName = packageName;
+        this.category = category;
         this.itemType = LauncherSettings.Favorites.ITEM_TYPE_NON_ACTIONABLE;
     }
 
     public PackageItemInfo(PackageItemInfo copy) {
         this.packageName = copy.packageName;
+        this.category = copy.category;
         this.itemType = LauncherSettings.Favorites.ITEM_TYPE_NON_ACTIONABLE;
     }
 
diff --git a/src/com/android/launcher3/settings/NotificationDotsPreference.java b/src/com/android/launcher3/settings/NotificationDotsPreference.java
index afcf882..0ee2744 100644
--- a/src/com/android/launcher3/settings/NotificationDotsPreference.java
+++ b/src/com/android/launcher3/settings/NotificationDotsPreference.java
@@ -85,6 +85,12 @@
                 Settings.Secure.getUriFor(NOTIFICATION_ENABLED_LISTENERS),
                 false, mListenerListObserver);
         updateUI();
+
+        // Update intent
+        Bundle extras = new Bundle();
+        extras.putString(EXTRA_FRAGMENT_ARG_KEY, "notification_badging");
+        setIntent(new Intent("android.settings.NOTIFICATION_SETTINGS")
+                .putExtra(EXTRA_SHOW_FRAGMENT_ARGS, extras));
     }
 
     private void updateUI() {
diff --git a/src/com/android/launcher3/settings/PreferenceHighlighter.java b/src/com/android/launcher3/settings/PreferenceHighlighter.java
index 8ba8146..96ee216 100644
--- a/src/com/android/launcher3/settings/PreferenceHighlighter.java
+++ b/src/com/android/launcher3/settings/PreferenceHighlighter.java
@@ -24,16 +24,18 @@
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
+import android.graphics.RectF;
 import android.util.Property;
 import android.view.View;
 
-import com.android.launcher3.util.Themes;
-
+import androidx.preference.Preference;
 import androidx.recyclerview.widget.RecyclerView;
 import androidx.recyclerview.widget.RecyclerView.ItemDecoration;
 import androidx.recyclerview.widget.RecyclerView.State;
 import androidx.recyclerview.widget.RecyclerView.ViewHolder;
 
+import com.android.launcher3.util.Themes;
+
 /**
  * Utility class for highlighting a preference
  */
@@ -62,14 +64,16 @@
     private final Paint mPaint = new Paint();
     private final RecyclerView mRv;
     private final int mIndex;
+    private final Preference mPreference;
+    private final RectF mDrawRect = new RectF();
 
     private boolean mHighLightStarted = false;
     private int mHighlightColor = END_COLOR;
 
-
-    public PreferenceHighlighter(RecyclerView rv, int index) {
+    public PreferenceHighlighter(RecyclerView rv, int index, Preference preference) {
         mRv = rv;
         mIndex = index;
+        mPreference = preference;
     }
 
     @Override
@@ -92,7 +96,8 @@
         if (!mHighLightStarted) {
             // Start highlight
             int colorTo = setColorAlphaBound(Themes.getColorAccent(mRv.getContext()), 66);
-            ObjectAnimator anim = ObjectAnimator.ofArgb(this, HIGHLIGHT_COLOR, END_COLOR, colorTo);
+            ObjectAnimator anim = ObjectAnimator.ofArgb(this, HIGHLIGHT_COLOR, END_COLOR,
+                    colorTo);
             anim.setDuration(HIGHLIGHT_FADE_IN_DURATION);
             anim.setRepeatMode(ValueAnimator.REVERSE);
             anim.setRepeatCount(4);
@@ -108,7 +113,11 @@
 
         View view = holder.itemView;
         mPaint.setColor(mHighlightColor);
-        c.drawRect(0, view.getY(), parent.getWidth(), view.getY() + view.getHeight(), mPaint);
+        mDrawRect.set(0, view.getY(), parent.getWidth(), view.getY() + view.getHeight());
+        if (mPreference instanceof HighlightDelegate) {
+            ((HighlightDelegate) mPreference).offsetHighlight(view, mDrawRect);
+        }
+        c.drawRect(mDrawRect, mPaint);
     }
 
     private void removeHighlight() {
@@ -124,4 +133,16 @@
         });
         anim.start();
     }
+
+    /**
+     * Interface to be implemented by a preference to customize the highlight are
+     */
+    public interface HighlightDelegate {
+
+        /**
+         * Allows the preference to update the highlight area
+         */
+        void offsetHighlight(View prefView, RectF bounds);
+
+    }
 }
diff --git a/src/com/android/launcher3/settings/SettingsActivity.java b/src/com/android/launcher3/settings/SettingsActivity.java
index 5b42ac7..216510b 100644
--- a/src/com/android/launcher3/settings/SettingsActivity.java
+++ b/src/com/android/launcher3/settings/SettingsActivity.java
@@ -237,7 +237,9 @@
             RecyclerView list = getListView();
             PreferencePositionCallback callback = (PreferencePositionCallback) list.getAdapter();
             int position = callback.getPreferenceAdapterPosition(mHighLightKey);
-            return position >= 0 ? new PreferenceHighlighter(list, position) : null;
+            return position >= 0 ? new PreferenceHighlighter(
+                    list, position, screen.findPreference(mHighLightKey))
+                    : null;
         }
 
         private void requestAccessibilityFocus(@NonNull final RecyclerView rv) {
diff --git a/src/com/android/launcher3/shortcuts/DeepShortcutView.java b/src/com/android/launcher3/shortcuts/DeepShortcutView.java
index 1c1418c..cc658c9 100644
--- a/src/com/android/launcher3/shortcuts/DeepShortcutView.java
+++ b/src/com/android/launcher3/shortcuts/DeepShortcutView.java
@@ -30,12 +30,13 @@
 import com.android.launcher3.Utilities;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
 import com.android.launcher3.popup.PopupContainerWithArrow;
+import com.android.launcher3.views.BubbleTextHolder;
 
 /**
  * A {@link android.widget.FrameLayout} that contains a {@link DeepShortcutView}.
  * This lets us animate the DeepShortcutView (icon and text) separately from the background.
  */
-public class DeepShortcutView extends FrameLayout {
+public class DeepShortcutView extends FrameLayout implements BubbleTextHolder {
 
     private static final Point sTempPoint = new Point();
 
@@ -64,6 +65,7 @@
         mIconView = findViewById(R.id.icon);
     }
 
+    @Override
     public BubbleTextView getBubbleText() {
         return mBubbleText;
     }
diff --git a/src/com/android/launcher3/views/BubbleTextHolder.java b/src/com/android/launcher3/views/BubbleTextHolder.java
new file mode 100644
index 0000000..47d3563
--- /dev/null
+++ b/src/com/android/launcher3/views/BubbleTextHolder.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2021 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.views;
+
+import com.android.launcher3.BubbleTextView;
+
+/**
+ * Views that contain {@link BubbleTextView} should implement this interface.
+ */
+public interface BubbleTextHolder {
+    BubbleTextView getBubbleText();
+}
diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java
index 23c3722..96268ce 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -210,8 +210,8 @@
     public static void getLocationBoundsForView(Launcher launcher, View v, boolean isOpening,
             RectF outRect, Rect outViewBounds) {
         boolean ignoreTransform = !isOpening;
-        if (v instanceof DeepShortcutView) {
-            v = ((DeepShortcutView) v).getBubbleText();
+        if (v instanceof BubbleTextHolder) {
+            v = ((BubbleTextHolder) v).getBubbleText();
             ignoreTransform = false;
         } else if (v.getParent() instanceof DeepShortcutView) {
             v = ((DeepShortcutView) v.getParent()).getIconView();
diff --git a/src/com/android/launcher3/widget/WidgetsBottomSheet.java b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
index bbb0d92..0670928 100644
--- a/src/com/android/launcher3/widget/WidgetsBottomSheet.java
+++ b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
@@ -170,9 +170,9 @@
         WidgetCell widget = (WidgetCell) LayoutInflater.from(getContext())
                 .inflate(R.layout.widget_cell, parent, false);
 
-        WidgetImageView preview = widget.findViewById(R.id.widget_preview);
-        preview.setOnClickListener(this);
-        preview.setOnLongClickListener(this);
+        View preview_container = widget.findViewById(R.id.widget_preview_container);
+        preview_container.setOnClickListener(this);
+        preview_container.setOnLongClickListener(this);
         widget.setAnimatePreview(false);
 
         parent.addView(widget);
diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
index a4257a2..f6ff87b 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
@@ -392,6 +392,7 @@
         mAdapters.get(AdapterHolder.SEARCH).mWidgetsListAdapter.setWidgetsOnSearch(entries);
         updateNoSearchResultsView(
                 mAdapters.get(AdapterHolder.SEARCH).mWidgetsListAdapter.getItemCount() == 0);
+        mAdapters.get(AdapterHolder.SEARCH).mWidgetsRecyclerView.scrollToTop();
     }
 
     private void setViewVisibilityBasedOnSearch(boolean isInSearchMode) {
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListHeader.java b/src/com/android/launcher3/widget/picker/WidgetsListHeader.java
index 497c72e..8794a4a 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsListHeader.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsListHeader.java
@@ -156,6 +156,11 @@
     private void applyDrawables(Drawable icon) {
         icon.setBounds(0, 0, mIconSize, mIconSize);
 
+        LinearLayout.LayoutParams layoutParams =
+                (LinearLayout.LayoutParams) mAppIcon.getLayoutParams();
+        layoutParams.width = mIconSize;
+        layoutParams.height = mIconSize;
+        mAppIcon.setLayoutParams(layoutParams);
         mAppIcon.setImageDrawable(icon);
 
         // If the current icon is a placeholder color, animate its update.
diff --git a/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java b/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java
index b016b4f..69672f2 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java
@@ -243,4 +243,19 @@
          */
         int getHeaderViewHeight();
     }
+
+    @Override
+    public void scrollToTop() {
+        if (mScrollbar != null) {
+            mScrollbar.reattachThumbToScroll();
+        }
+
+        if (getLayoutManager() instanceof LinearLayoutManager) {
+            if (getCurrentScrollY() == 0) {
+                // We are at the top, so don't scrollToPosition (would cause unnecessary relayout).
+                return;
+            }
+        }
+        scrollToPosition(0);
+    }
 }
diff --git a/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarController.java b/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarController.java
index d35a75b..a8294c0 100644
--- a/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarController.java
+++ b/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarController.java
@@ -102,7 +102,7 @@
     @Override
     public void clearSearchResult() {
         mSearchAlgorithm.cancel(/* interruptActiveRequests= */ true);
-        mInput.getText().clear();
+        mInput.setText("");
         clearFocus();
         mSearchModeListener.exitSearchMode();
     }
diff --git a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
index f82f2cc..be18e54 100644
--- a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
+++ b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
@@ -36,6 +36,7 @@
 import com.android.launcher3.widget.picker.WidgetsDiffReporter;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -58,6 +59,9 @@
     private static final String TAG = "WidgetsModel";
     private static final boolean DEBUG = false;
 
+    private static final ComponentName CONVERSATION_WIDGET = ComponentName.createRelative(
+            "com.android.systemui", ".people.widget.PeopleSpaceWidgetProvider");
+
     /* Map of widgets and shortcuts that are tracked per package. */
     private final Map<PackageItemInfo, List<WidgetItem>> mWidgetsList = new HashMap<>();
 
@@ -156,7 +160,7 @@
 
         // Temporary list for {@link PackageItemInfos} to avoid having to go through
         // {@link mPackageItemInfos} to locate the key to be used for {@link #mWidgetsList}
-        HashMap<PackageUserKey, PackageItemInfo> tmpPackageItemInfos = new HashMap<>();
+        HashMap<WidgetPackageOrCategoryKey, PackageItemInfo> tmpPackageItemInfos = new HashMap<>();
 
         // Clear the lists only if this is an update on all widgets and shortcuts. If packageUser
         // isn't null, only updates the shortcuts and widgets for the app represented in
@@ -168,11 +172,11 @@
         mWidgetsList.putAll(rawWidgetsShortcuts.stream()
                 .filter(new WidgetValidityCheck(app))
                 .collect(Collectors.groupingBy(item -> {
-                    PackageUserKey packageUserKey = new PackageUserKey(
-                            item.componentName.getPackageName(), item.user);
+                    WidgetPackageOrCategoryKey packageUserKey = getWidgetPackageOrCategoryKey(item);
                     PackageItemInfo pInfo = tmpPackageItemInfos.get(packageUserKey);
                     if (pInfo == null) {
-                        pInfo = new PackageItemInfo(packageUserKey.mPackageName);
+                        pInfo = new PackageItemInfo(item.componentName.getPackageName(),
+                                packageUserKey.mCategory);
                         pInfo.user = item.user;
                         tmpPackageItemInfos.put(packageUserKey,  pInfo);
                     }
@@ -224,6 +228,13 @@
         return null;
     }
 
+    private WidgetPackageOrCategoryKey getWidgetPackageOrCategoryKey(WidgetItem item) {
+        if (CONVERSATION_WIDGET.equals(item.componentName)) {
+            return new WidgetPackageOrCategoryKey(PackageItemInfo.CONVERSATIONS, item.user);
+        }
+        return new WidgetPackageOrCategoryKey(item.componentName.getPackageName(), item.user);
+    }
+
     private static class WidgetValidityCheck implements Predicate<WidgetItem> {
 
         private final InvariantDeviceProfile mIdp;
@@ -265,4 +276,40 @@
             return true;
         }
     }
+
+    /** A hash key for grouping widgets by package name or category. */
+    private static class WidgetPackageOrCategoryKey {
+        /**
+         * The package name of the widget provider.
+         *
+         * <p>This shouldn't be empty if {@link #mCategory} has a value,
+         * {@link PackageItemInfo#NO_CATEGORY}.
+         */
+        public final String mPackage;
+        /** A widget category. */
+        @PackageItemInfo.Category public final int mCategory;
+        public final UserHandle mUser;
+        private final int mHashCode;
+
+        WidgetPackageOrCategoryKey(String packageName, UserHandle user) {
+            this(packageName,  PackageItemInfo.NO_CATEGORY, user);
+        }
+
+        WidgetPackageOrCategoryKey(@PackageItemInfo.Category int category, UserHandle user) {
+            this("", category, user);
+        }
+
+        private WidgetPackageOrCategoryKey(String packageName,
+                @PackageItemInfo.Category int category, UserHandle user) {
+            mPackage = packageName;
+            mCategory = category;
+            mUser = user;
+            mHashCode = Arrays.hashCode(new Object[]{mPackage, mCategory, mUser});
+        }
+
+        @Override
+        public int hashCode() {
+            return mHashCode;
+        }
+    }
 }
\ No newline at end of file