Merge "Fix drag-n-drop from the pin widget flow" 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="?android:attr/dialogCornerRadius""
+ 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="?android:attr/dialogCornerRadius" />"
+ 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=" <style name="Widget.DeviceDefault.Button.Rounded.Colored" parent="@android:style/Widget.DeviceDefault.Button.Colored">"
+ 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=" <corners android:radius="@android:dimen/system_app_widget_background_radius" />"
+ 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 && 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 && 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 && targetCellWidth >= minSpanX && targetCellWidth <= 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 && targetCellWidth >= minSpanX && targetCellWidth <= 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=" && targetCellHeight >= minSpanY && targetCellHeight <= 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=" && targetCellHeight >= minSpanY && targetCellHeight <= 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<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<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=" && 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 && 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 && 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 && targetCellWidth >= minSpanX && targetCellWidth <= 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 && targetCellWidth >= minSpanX && targetCellWidth <= 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=" && targetCellHeight >= minSpanY && targetCellHeight <= 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=" && targetCellHeight >= minSpanY && targetCellHeight <= 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<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<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=" && 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="?android:attr/dialogCornerRadius""
+ 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="?android:attr/dialogCornerRadius" />"
+ 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=" <style name="Widget.DeviceDefault.Button.Rounded.Colored" parent="@android:style/Widget.DeviceDefault.Button.Colored">"
+ 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=" <corners android:radius="@android:dimen/system_app_widget_background_radius" />"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/apps/Launcher3/res/drawable/widget_resize_frame.xml"
+ line="20"
+ column="14"/>
+ </issue>
+
+</issues>
diff --git a/quickstep/res/layout/taskbar.xml b/quickstep/res/layout/taskbar.xml
index 84e2304..732222a 100644
--- a/quickstep/res/layout/taskbar.xml
+++ b/quickstep/res/layout/taskbar.xml
@@ -24,7 +24,6 @@
android:id="@+id/taskbar_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:background="@color/taskbar_background"
android:gravity="center"/>
</com.android.launcher3.taskbar.TaskbarContainerView>
\ No newline at end of file
diff --git a/quickstep/res/layout/taskbar_divider.xml b/quickstep/res/layout/taskbar_divider.xml
deleted file mode 100644
index 87649f7..0000000
--- a/quickstep/res/layout/taskbar_divider.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<View
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="@dimen/taskbar_divider_thickness"
- android:layout_height="@dimen/taskbar_divider_height"
- android:background="@color/taskbar_divider" />
\ No newline at end of file
diff --git a/quickstep/res/values/colors.xml b/quickstep/res/values/colors.xml
index 54730f1..3bc8ddc 100644
--- a/quickstep/res/values/colors.xml
+++ b/quickstep/res/values/colors.xml
@@ -27,5 +27,4 @@
<!-- Taskbar -->
<color name="taskbar_background">#101010</color>
- <color name="taskbar_divider">#C0C0C0</color>
</resources>
\ No newline at end of file
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 3e6c78f..99be502 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -134,7 +134,5 @@
<dimen name="taskbar_icon_drag_icon_size">54dp</dimen>
<!-- Note that this applies to both sides of all icons, so visible space is double this. -->
<dimen name="taskbar_icon_spacing">8dp</dimen>
- <dimen name="taskbar_divider_thickness">1dp</dimen>
- <dimen name="taskbar_divider_height">32dp</dimen>
<dimen name="taskbar_folder_margin">16dp</dimen>
</resources>
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
index 4415b51..0524b21 100644
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
@@ -108,6 +108,7 @@
SysUINavigationMode.INSTANCE.get(this).removeModeChangeListener(this);
if (mTaskbarController != null) {
mTaskbarController.cleanup();
+ mTaskbarController = null;
}
super.onDestroy();
diff --git a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduController.java b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
index 4451e7a..a6844e4 100644
--- a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
+++ b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
@@ -89,7 +89,7 @@
ArrayList<WorkspaceItemInfo> putIntoFolder = new ArrayList<>();
//separate folders and items that can get in folders
- for (int i = 0; i < mLauncher.getDeviceProfile().inv.numHotseatIcons; i++) {
+ for (int i = 0; i < mLauncher.getDeviceProfile().numShownHotseatIcons; i++) {
View view = mHotseat.getChildAt(i, 0);
if (view == null) continue;
ItemInfo info = (ItemInfo) view.getTag();
@@ -188,7 +188,7 @@
.getInt(LauncherSettings.Settings.EXTRA_VALUE);
mNewScreens = IntArray.wrap(pageId);
}
- for (int i = 0; i < mLauncher.getDeviceProfile().inv.numHotseatIcons; i++) {
+ for (int i = 0; i < mLauncher.getDeviceProfile().numShownHotseatIcons; i++) {
View child = mHotseat.getChildAt(i, 0);
if (child == null || child.getTag() == null) continue;
ItemInfo tag = (ItemInfo) child.getTag();
@@ -224,7 +224,7 @@
void showDimissTip() {
if (mHotseat.getShortcutsAndWidgets().getChildCount()
- < mLauncher.getDeviceProfile().inv.numHotseatIcons) {
+ < mLauncher.getDeviceProfile().numShownHotseatIcons) {
Snackbar.show(mLauncher, R.string.hotseat_tip_gaps_filled,
R.string.hotseat_prediction_settings, null,
() -> mLauncher.startActivity(getSettingsIntent()));
diff --git a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java
index c3677ea..a2ed211 100644
--- a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java
+++ b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java
@@ -88,7 +88,7 @@
Rect padding = grid.getHotseatLayoutPadding();
mSampleHotseat.getLayoutParams().height = grid.cellHeightPx;
- mSampleHotseat.setGridSize(grid.inv.numHotseatIcons, 1);
+ mSampleHotseat.setGridSize(grid.numShownHotseatIcons, 1);
mSampleHotseat.setPadding(padding.left, 0, padding.right, 0);
Button turnOnBtn = findViewById(R.id.turn_predictions_on);
@@ -178,7 +178,7 @@
}
private void populatePreview(List<WorkspaceItemInfo> predictions) {
- for (int i = 0; i < mLauncher.getDeviceProfile().inv.numHotseatIcons; i++) {
+ for (int i = 0; i < mLauncher.getDeviceProfile().numShownHotseatIcons; i++) {
WorkspaceItemInfo info = predictions.get(i);
PredictedAppIcon icon = PredictedAppIcon.createIcon(mSampleHotseat, info);
icon.setEnabled(false);
@@ -194,7 +194,7 @@
*/
public void show(List<WorkspaceItemInfo> predictions) {
if (getParent() != null
- || predictions.size() < mLauncher.getDeviceProfile().inv.numHotseatIcons
+ || predictions.size() < mLauncher.getDeviceProfile().numShownHotseatIcons
|| mHotseatEduController == null) {
return;
}
diff --git a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
index f297343..67ed5fb 100644
--- a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
+++ b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
@@ -33,10 +33,10 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.android.launcher3.DeviceProfile;
import com.android.launcher3.DragSource;
import com.android.launcher3.DropTarget;
import com.android.launcher3.Hotseat;
-import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.R;
import com.android.launcher3.anim.AnimationSuccessListener;
@@ -68,7 +68,7 @@
* pinning of predicted apps and manages replacement of predicted apps with user drag.
*/
public class HotseatPredictionController implements DragController.DragListener,
- SystemShortcut.Factory<QuickstepLauncher>, InvariantDeviceProfile.OnIDPChangeListener,
+ SystemShortcut.Factory<QuickstepLauncher>, DeviceProfile.OnDeviceProfileChangeListener,
DragSource, ViewGroup.OnHierarchyChangeListener {
private static final int FLAG_UPDATE_PAUSED = 1 << 0;
@@ -115,10 +115,10 @@
public HotseatPredictionController(QuickstepLauncher launcher) {
mLauncher = launcher;
mHotseat = launcher.getHotseat();
- mHotSeatItemsCount = mLauncher.getDeviceProfile().inv.numHotseatIcons;
+ mHotSeatItemsCount = mLauncher.getDeviceProfile().numShownHotseatIcons;
mLauncher.getDragController().addDragListener(this);
- launcher.getDeviceProfile().inv.addOnChangeListener(this);
+ launcher.addOnDeviceProfileChangeListener(this);
mHotseat.getShortcutsAndWidgets().setOnHierarchyChangeListener(this);
}
@@ -281,7 +281,7 @@
* Unregisters callbacks and frees resources
*/
public void destroy() {
- mLauncher.getDeviceProfile().inv.removeOnChangeListener(this);
+ mLauncher.removeOnDeviceProfileChangeListener(this);
}
/**
@@ -446,8 +446,8 @@
}
@Override
- public void onIdpChanged(int changeFlags, InvariantDeviceProfile profile) {
- this.mHotSeatItemsCount = profile.numHotseatIcons;
+ public void onDeviceProfileChanged(DeviceProfile profile) {
+ this.mHotSeatItemsCount = profile.numShownHotseatIcons;
}
@Override
diff --git a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatRestoreHelper.java b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatRestoreHelper.java
index 90f762e..4956fa1 100644
--- a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatRestoreHelper.java
+++ b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatRestoreHelper.java
@@ -44,7 +44,7 @@
.getBinder(LauncherSettings.Settings.EXTRA_VALUE)) {
InvariantDeviceProfile idp = LauncherAppState.getIDP(context);
GridBackupTable backupTable = new GridBackupTable(context,
- transaction.getDb(), idp.numHotseatIcons, idp.numColumns,
+ transaction.getDb(), idp.numDatabaseHotseatIcons, idp.numColumns,
idp.numRows);
backupTable.createCustomBackupTable(HYBRID_HOTSEAT_BACKUP_TABLE);
transaction.commit();
@@ -69,7 +69,7 @@
}
InvariantDeviceProfile idp = LauncherAppState.getIDP(context);
GridBackupTable backupTable = new GridBackupTable(context,
- transaction.getDb(), idp.numHotseatIcons, idp.numColumns,
+ transaction.getDb(), idp.numDatabaseHotseatIcons, idp.numColumns,
idp.numRows);
backupTable.restoreFromCustomBackupTable(HYBRID_HOTSEAT_BACKUP_TABLE, true);
transaction.commit();
diff --git a/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java b/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java
index df3657d..8c68872 100644
--- a/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java
+++ b/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java
@@ -111,7 +111,7 @@
mDataModel.extraItems.put(CONTAINER_PREDICTION, mAllAppsState.items);
WorkspaceItemFactory hotseatFactory =
- new WorkspaceItemFactory(mApp, ums, pinnedShortcuts, mIDP.numHotseatIcons);
+ new WorkspaceItemFactory(mApp, ums, pinnedShortcuts, mIDP.numDatabaseHotseatIcons);
mHotseatState.items.setItems(
mHotseatState.storage.read(mApp.getContext(), hotseatFactory, ums.allUsers::get));
mDataModel.extraItems.put(CONTAINER_HOTSEAT_PREDICTION, mHotseatState.items);
@@ -211,7 +211,7 @@
registerPredictor(mHotseatState, apm.createAppPredictionSession(
new AppPredictionContext.Builder(context)
.setUiSurface("hotseat")
- .setPredictedTargetCount(mIDP.numHotseatIcons)
+ .setPredictedTargetCount(mIDP.numDatabaseHotseatIcons)
.setExtras(convertDataModelToAppTargetBundle(context, mDataModel))
.build()));
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarAnimationController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarAnimationController.java
index 7c54e2d..46e4506 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarAnimationController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarAnimationController.java
@@ -50,6 +50,10 @@
private final AnimatedFloat mTaskbarScaleForLauncherState = new AnimatedFloat(
this::updateScale);
+ // TranslationY.
+ private final AnimatedFloat mTaskbarTranslationYForLauncherState = new AnimatedFloat(
+ this::updateTranslationY);
+
public TaskbarAnimationController(BaseQuickstepLauncher launcher,
TaskbarController.TaskbarAnimationControllerCallbacks taskbarCallbacks) {
mLauncher = launcher;
@@ -81,6 +85,10 @@
return mTaskbarScaleForLauncherState;
}
+ protected AnimatedFloat getTaskbarTranslationYForLauncherState() {
+ return mTaskbarTranslationYForLauncherState;
+ }
+
protected Animator createAnimToBackgroundAlpha(float toAlpha, long duration) {
return mTaskbarBackgroundAlpha.animateToValue(mTaskbarBackgroundAlpha.value, toAlpha)
.setDuration(duration);
@@ -95,6 +103,7 @@
mTaskbarCallbacks.updateTaskbarBackgroundAlpha(mTaskbarBackgroundAlpha.value);
updateVisibilityAlpha();
updateScale();
+ updateTranslationY();
}
private void updateVisibilityAlpha() {
@@ -120,6 +129,15 @@
mTaskbarCallbacks.updateTaskbarScale(scale);
}
+ private void updateTranslationY() {
+ // We use mTaskbarBackgroundAlpha as a proxy for whether Launcher is resumed/paused, the
+ // assumption being that Taskbar should always be at translationY 0f regardless of the
+ // current LauncherState if Launcher is paused.
+ float translationY = mTaskbarTranslationYForLauncherState.value;
+ translationY = Utilities.mapRange(mTaskbarBackgroundAlpha.value, translationY, 0f);
+ mTaskbarCallbacks.updateTaskbarTranslationY(translationY);
+ }
+
private void setNavBarButtonAlpha(float navBarAlpha) {
SystemUiProxy.INSTANCE.get(mLauncher).setNavBarButtonAlpha(navBarAlpha, false);
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarContainerView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarContainerView.java
index ccf6b41..621bba7 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarContainerView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarContainerView.java
@@ -19,6 +19,8 @@
import static com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo.TOUCHABLE_INSETS_REGION;
import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
@@ -38,6 +40,7 @@
private final int[] mTempLoc = new int[2];
private final int mFolderMargin;
+ private final Paint mTaskbarBackgroundPaint;
// Initialized in TaskbarController constructor.
private TaskbarController.TaskbarContainerViewCallbacks mControllerCallbacks;
@@ -63,6 +66,8 @@
int defStyleAttr, int defStyleRes) {
super(context, attrs, 1 /* alphaChannelCount */);
mFolderMargin = getResources().getDimensionPixelSize(R.dimen.taskbar_folder_margin);
+ mTaskbarBackgroundPaint = new Paint();
+ mTaskbarBackgroundPaint.setColor(getResources().getColor(R.color.taskbar_background));
}
protected void construct(TaskbarController.TaskbarContainerViewCallbacks callbacks) {
@@ -97,11 +102,14 @@
// mTaskbarView is, since its position never changes and insets rather than overlays.
int[] loc = mTempLoc;
float scale = mTaskbarView.getScaleX();
+ float translationY = mTaskbarView.getTranslationY();
mTaskbarView.setScaleX(1);
mTaskbarView.setScaleY(1);
+ mTaskbarView.setTranslationY(0);
mTaskbarView.getLocationInWindow(loc);
mTaskbarView.setScaleX(scale);
mTaskbarView.setScaleY(scale);
+ mTaskbarView.setTranslationY(translationY);
insetsInfo.contentInsets.left = loc[0];
insetsInfo.contentInsets.top = loc[1];
insetsInfo.contentInsets.right = getWidth() - (loc[0] + mTaskbarView.getWidth());
@@ -153,4 +161,20 @@
protected TaskbarActivityContext getTaskbarActivityContext() {
return mActivity;
}
+
+ @Override
+ protected void dispatchDraw(Canvas canvas) {
+ canvas.drawRect(0, canvas.getHeight() - mTaskbarView.getHeight(), canvas.getWidth(),
+ canvas.getHeight(), mTaskbarBackgroundPaint);
+ super.dispatchDraw(canvas);
+ }
+
+ /**
+ * Sets the alpha of the background color behind all the Taskbar contents.
+ * @param alpha 0 is fully transparent, 1 is fully opaque.
+ */
+ protected void setTaskbarBackgroundAlpha(float alpha) {
+ mTaskbarBackgroundPaint.setAlpha((int) (alpha * 255));
+ invalidate();
+ }
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java
index 559ede1..c93de00 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java
@@ -25,7 +25,6 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.ActivityOptions;
-import android.content.ComponentName;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
@@ -56,9 +55,6 @@
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.WindowManagerWrapper;
-import java.util.ArrayList;
-import java.util.List;
-
/**
* Interfaces with Launcher/WindowManager/SystemUI to determine what to show in TaskbarView.
*/
@@ -76,17 +72,11 @@
private final TaskbarStateHandler mTaskbarStateHandler;
private final TaskbarAnimationController mTaskbarAnimationController;
private final TaskbarHotseatController mHotseatController;
- private final TaskbarRecentsController mRecentsController;
private final TaskbarDragController mDragController;
// Initialized in init().
private WindowManager.LayoutParams mWindowLayoutParams;
- // Contains all loaded Tasks, not yet deduped from Hotseat items.
- private List<Task> mLatestLoadedRecentTasks;
- // Contains all loaded Hotseat items.
- private ItemInfo[] mLatestLoadedHotseatItems;
-
private @Nullable Animator mAnimator;
private boolean mIsAnimatingToLauncher;
@@ -106,8 +96,6 @@
createTaskbarAnimationControllerCallbacks());
mHotseatController = new TaskbarHotseatController(mLauncher,
createTaskbarHotseatControllerCallbacks());
- mRecentsController = new TaskbarRecentsController(mLauncher,
- createTaskbarRecentsControllerCallbacks());
mDragController = new TaskbarDragController(mLauncher);
}
@@ -115,7 +103,7 @@
return new TaskbarAnimationControllerCallbacks() {
@Override
public void updateTaskbarBackgroundAlpha(float alpha) {
- mTaskbarViewInApp.setBackgroundAlpha(alpha);
+ mTaskbarContainerView.setTaskbarBackgroundAlpha(alpha);
}
@Override
@@ -129,6 +117,18 @@
mTaskbarViewInApp.setScaleX(scale);
mTaskbarViewInApp.setScaleY(scale);
}
+
+ @Override
+ public void updateTaskbarTranslationY(float translationY) {
+ if (translationY < 0) {
+ // Resize to accommodate the max translation we'll reach.
+ setTaskbarWindowHeight(mTaskbarSize.y
+ + mLauncher.getHotseat().getTaskbarOffsetY());
+ } else {
+ setTaskbarWindowHeight(mTaskbarSize.y);
+ }
+ mTaskbarViewInApp.setTranslationY(translationY);
+ }
};
}
@@ -220,24 +220,6 @@
@Override
public void updateHotseatItems(ItemInfo[] hotseatItemInfos) {
mTaskbarViewInApp.updateHotseatItems(hotseatItemInfos);
- mLatestLoadedHotseatItems = hotseatItemInfos;
- dedupeAndUpdateRecentItems();
- }
- };
- }
-
- private TaskbarRecentsControllerCallbacks createTaskbarRecentsControllerCallbacks() {
- return new TaskbarRecentsControllerCallbacks() {
- @Override
- public void updateRecentItems(ArrayList<Task> recentTasks) {
- mLatestLoadedRecentTasks = recentTasks;
- dedupeAndUpdateRecentItems();
- }
-
- @Override
- public void updateRecentTaskAtIndex(int taskIndex, Task task) {
- mTaskbarViewInApp.updateRecentTaskAtIndex(taskIndex, task);
- mTaskbarViewOnHome.updateRecentTaskAtIndex(taskIndex, task);
}
};
}
@@ -246,16 +228,13 @@
* Initializes the Taskbar, including adding it to the screen.
*/
public void init() {
- mTaskbarViewInApp.init(mHotseatController.getNumHotseatIcons(),
- mRecentsController.getNumRecentIcons());
- mTaskbarViewOnHome.init(mHotseatController.getNumHotseatIcons(),
- mRecentsController.getNumRecentIcons());
+ mTaskbarViewInApp.init(mHotseatController.getNumHotseatIcons());
+ mTaskbarViewOnHome.init(mHotseatController.getNumHotseatIcons());
mTaskbarContainerView.init(mTaskbarViewInApp);
addToWindowManager();
mTaskbarStateHandler.setTaskbarCallbacks(createTaskbarStateHandlerCallbacks());
mTaskbarAnimationController.init();
mHotseatController.init();
- mRecentsController.init();
setWhichTaskbarViewIsVisible(mLauncher.hasBeenResumed()
? mTaskbarViewOnHome
@@ -273,6 +252,11 @@
public AnimatedFloat getScaleTarget() {
return mTaskbarAnimationController.getTaskbarScaleForLauncherState();
}
+
+ @Override
+ public AnimatedFloat getTranslationYTarget() {
+ return mTaskbarAnimationController.getTaskbarTranslationYForLauncherState();
+ }
};
}
@@ -292,7 +276,6 @@
mTaskbarStateHandler.setTaskbarCallbacks(null);
mTaskbarAnimationController.cleanup();
mHotseatController.cleanup();
- mRecentsController.cleanup();
setWhichTaskbarViewIsVisible(null);
}
@@ -425,53 +408,6 @@
return mTaskbarViewInApp.isDraggingItem() || mTaskbarViewOnHome.isDraggingItem();
}
- private void dedupeAndUpdateRecentItems() {
- if (mLatestLoadedRecentTasks == null || mLatestLoadedHotseatItems == null) {
- return;
- }
-
- final int numRecentIcons = mRecentsController.getNumRecentIcons();
-
- // From most recent to least recently opened.
- List<Task> dedupedTasksInDescendingOrder = new ArrayList<>();
- for (int i = mLatestLoadedRecentTasks.size() - 1; i >= 0; i--) {
- Task task = mLatestLoadedRecentTasks.get(i);
- boolean isTaskInHotseat = false;
- for (ItemInfo hotseatItem : mLatestLoadedHotseatItems) {
- if (hotseatItem == null) {
- continue;
- }
- ComponentName hotseatActivity = hotseatItem.getTargetComponent();
- if (hotseatActivity != null && task.key.sourceComponent.getPackageName()
- .equals(hotseatActivity.getPackageName())) {
- isTaskInHotseat = true;
- break;
- }
- }
- if (!isTaskInHotseat) {
- dedupedTasksInDescendingOrder.add(task);
- if (dedupedTasksInDescendingOrder.size() == numRecentIcons) {
- break;
- }
- }
- }
-
- // TaskbarView expects an array of all the recent tasks to show, in the order to show them.
- // So we create an array of the proper size, then fill it in such that the most recent items
- // are at the end. If there aren't enough elements to fill the array, leave them null.
- Task[] tasksArray = new Task[numRecentIcons];
- for (int i = 0; i < tasksArray.length; i++) {
- Task task = i >= dedupedTasksInDescendingOrder.size()
- ? null
- : dedupedTasksInDescendingOrder.get(i);
- tasksArray[tasksArray.length - 1 - i] = task;
- }
-
- mTaskbarViewInApp.updateRecentTasks(tasksArray);
- mTaskbarViewOnHome.updateRecentTasks(tasksArray);
- mRecentsController.loadIconsForTasks(tasksArray);
- }
-
/**
* @return Whether the given View is in the same window as Taskbar.
*/
@@ -487,13 +423,15 @@
Rect hotseatBounds = new Rect();
DeviceProfile grid = mLauncher.getDeviceProfile();
int hotseatHeight = grid.workspacePadding.bottom + grid.taskbarSize;
- int hotseatTopDiff = hotseatHeight - grid.taskbarSize;
+ int taskbarOffset = mLauncher.getHotseat().getTaskbarOffsetY();
+ int hotseatTopDiff = hotseatHeight - grid.taskbarSize - taskbarOffset;
+ int hotseatBottomDiff = taskbarOffset;
mTaskbarViewOnHome.getHotseatBounds().roundOut(hotseatBounds);
mLauncher.getHotseat().setPadding(hotseatBounds.left,
hotseatBounds.top + hotseatTopDiff,
mTaskbarViewOnHome.getWidth() - hotseatBounds.right,
- mTaskbarViewOnHome.getHeight() - hotseatBounds.bottom);
+ mTaskbarViewOnHome.getHeight() - hotseatBounds.bottom + hotseatBottomDiff);
}
private void setWhichTaskbarViewIsVisible(@Nullable TaskbarView visibleTaskbar) {
@@ -519,13 +457,15 @@
* Updates the TaskbarContainer to MATCH_PARENT vs original Taskbar size.
*/
private void setTaskbarWindowFullscreen(boolean fullscreen) {
- if (fullscreen) {
- mWindowLayoutParams.width = MATCH_PARENT;
- mWindowLayoutParams.height = MATCH_PARENT;
- } else {
- mWindowLayoutParams.width = mTaskbarSize.x;
- mWindowLayoutParams.height = mTaskbarSize.y;
- }
+ setTaskbarWindowHeight(fullscreen ? MATCH_PARENT : mTaskbarSize.y);
+ }
+
+ /**
+ * Updates the TaskbarContainer height (pass mTaskbarSize.y to reset).
+ */
+ private void setTaskbarWindowHeight(int height) {
+ mWindowLayoutParams.width = mTaskbarSize.x;
+ mWindowLayoutParams.height = height;
mWindowManager.updateViewLayout(mTaskbarContainerView, mWindowLayoutParams);
}
@@ -535,6 +475,7 @@
protected interface TaskbarStateHandlerCallbacks {
AnimatedFloat getAlphaTarget();
AnimatedFloat getScaleTarget();
+ AnimatedFloat getTranslationYTarget();
}
/**
@@ -545,6 +486,7 @@
void updateTaskbarBackgroundAlpha(float alpha);
void updateTaskbarVisibilityAlpha(float alpha);
void updateTaskbarScale(float scale);
+ void updateTaskbarTranslationY(float translationY);
}
/**
@@ -573,12 +515,4 @@
protected interface TaskbarHotseatControllerCallbacks {
void updateHotseatItems(ItemInfo[] hotseatItemInfos);
}
-
- /**
- * Contains methods that TaskbarRecentsController can call to interface with TaskbarController.
- */
- protected interface TaskbarRecentsControllerCallbacks {
- void updateRecentItems(ArrayList<Task> recentTasks);
- void updateRecentTaskAtIndex(int taskIndex, Task task);
- }
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarHotseatController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarHotseatController.java
index b1bafdb..68829cd 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarHotseatController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarHotseatController.java
@@ -52,7 +52,7 @@
mLauncher = launcher;
mHotseat = mLauncher.getHotseat();
mTaskbarCallbacks = taskbarCallbacks;
- mNumHotseatIcons = mLauncher.getDeviceProfile().inv.numHotseatIcons;
+ mNumHotseatIcons = mLauncher.getDeviceProfile().numShownHotseatIcons;
}
protected void init() {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentsController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentsController.java
deleted file mode 100644
index 4256d2b..0000000
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentsController.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * 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.taskbar;
-
-import com.android.launcher3.BaseQuickstepLauncher;
-import com.android.quickstep.RecentsModel;
-import com.android.quickstep.util.CancellableTask;
-import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.shared.system.TaskStackChangeListener;
-import com.android.systemui.shared.system.TaskStackChangeListeners;
-
-import java.util.ArrayList;
-
-/**
- * Works with TaskbarController to update the TaskbarView's Recent items.
- */
-public class TaskbarRecentsController {
-
- private final int mNumRecentIcons = 2;
- private final BaseQuickstepLauncher mLauncher;
- private final TaskbarController.TaskbarRecentsControllerCallbacks mTaskbarCallbacks;
- private final RecentsModel mRecentsModel;
-
- private final TaskStackChangeListener mTaskStackChangeListener = new TaskStackChangeListener() {
- @Override
- public void onTaskStackChanged() {
- reloadRecentTasksIfNeeded();
- }
- };
-
- // TODO: add TaskbarVisualsChangedListener as well (for calendar/clock?)
-
- // Used to keep track of the last requested task list id, so that we do not request to load the
- // tasks again if we have already requested it and the task list has not changed
- private int mTaskListChangeId = -1;
-
- // The current background requests to load the task icons
- private CancellableTask[] mIconLoadRequests = new CancellableTask[mNumRecentIcons];
-
- private boolean mIsAlive;
-
- public TaskbarRecentsController(BaseQuickstepLauncher launcher,
- TaskbarController.TaskbarRecentsControllerCallbacks taskbarCallbacks) {
- mLauncher = launcher;
- mTaskbarCallbacks = taskbarCallbacks;
- mRecentsModel = RecentsModel.INSTANCE.get(mLauncher);
- }
-
- protected void init() {
- mIsAlive = true;
- TaskStackChangeListeners.getInstance().registerTaskStackListener(mTaskStackChangeListener);
- reloadRecentTasksIfNeeded();
- }
-
- protected void cleanup() {
- mIsAlive = false;
- TaskStackChangeListeners.getInstance().unregisterTaskStackListener(
- mTaskStackChangeListener);
- cancelAllPendingIconLoadTasks();
- }
-
- private void reloadRecentTasksIfNeeded() {
- if (!mRecentsModel.isTaskListValid(mTaskListChangeId)) {
- mTaskListChangeId = mRecentsModel.getTasks(this::onRecentTasksChanged);
- }
- }
-
- private void cancelAllPendingIconLoadTasks() {
- for (int i = 0; i < mIconLoadRequests.length; i++) {
- if (mIconLoadRequests[i] != null) {
- mIconLoadRequests[i].cancel();
- }
- mIconLoadRequests[i] = null;
- }
- }
-
- private void onRecentTasksChanged(ArrayList<Task> tasks) {
- if (mIsAlive) {
- mTaskbarCallbacks.updateRecentItems(tasks);
- }
- }
-
- /**
- * For each Task, loads its icon from the cache in the background, then calls
- * {@link TaskbarController.TaskbarRecentsControllerCallbacks#updateRecentTaskAtIndex}.
- */
- protected void loadIconsForTasks(Task[] tasks) {
- cancelAllPendingIconLoadTasks();
- for (int i = 0; i < tasks.length; i++) {
- Task task = tasks[i];
- if (task == null) {
- continue;
- }
- final int taskIndex = i;
- mIconLoadRequests[i] = mRecentsModel.getIconCache().updateIconInBackground(
- task, updatedTask -> onTaskIconLoaded(task, taskIndex));
- }
- }
-
- private void onTaskIconLoaded(Task task, int taskIndex) {
- mTaskbarCallbacks.updateRecentTaskAtIndex(taskIndex, task);
- }
-
- protected int getNumRecentIcons() {
- return mNumRecentIcons;
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStateHandler.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStateHandler.java
index 9fc7d99..6ea51fa 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStateHandler.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStateHandler.java
@@ -16,6 +16,7 @@
package com.android.launcher3.taskbar;
import static com.android.launcher3.LauncherState.TASKBAR;
+import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import androidx.annotation.Nullable;
@@ -54,9 +55,11 @@
AnimatedFloat alphaTarget = mTaskbarCallbacks.getAlphaTarget();
AnimatedFloat scaleTarget = mTaskbarCallbacks.getScaleTarget();
+ AnimatedFloat translationYTarget = mTaskbarCallbacks.getTranslationYTarget();
boolean isTaskbarVisible = (state.getVisibleElements(mLauncher) & TASKBAR) != 0;
alphaTarget.updateValue(isTaskbarVisible ? 1f : 0f);
scaleTarget.updateValue(state.getTaskbarScale(mLauncher));
+ translationYTarget.updateValue(state.getTaskbarTranslationY(mLauncher));
}
@Override
@@ -68,9 +71,12 @@
AnimatedFloat alphaTarget = mTaskbarCallbacks.getAlphaTarget();
AnimatedFloat scaleTarget = mTaskbarCallbacks.getScaleTarget();
+ AnimatedFloat translationYTarget = mTaskbarCallbacks.getTranslationYTarget();
boolean isTaskbarVisible = (toState.getVisibleElements(mLauncher) & TASKBAR) != 0;
animation.setFloat(alphaTarget, AnimatedFloat.VALUE, isTaskbarVisible ? 1f : 0f, LINEAR);
animation.setFloat(scaleTarget, AnimatedFloat.VALUE, toState.getTaskbarScale(mLauncher),
LINEAR);
+ animation.setFloat(translationYTarget, AnimatedFloat.VALUE,
+ toState.getTaskbarTranslationY(mLauncher), ACCEL_DEACCEL);
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
index 21a2d51..60a7add 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
@@ -24,8 +24,6 @@
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.RectF;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.DragEvent;
import android.view.MotionEvent;
@@ -47,16 +45,12 @@
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.views.ActivityContext;
-import com.android.systemui.shared.recents.model.Task;
/**
* Hosts the Taskbar content such as Hotseat and Recent Apps. Drawn on top of other apps.
*/
public class TaskbarView extends LinearLayout implements FolderIcon.FolderIconParent, Insettable {
- private final ColorDrawable mBackgroundDrawable;
- private final int mDividerWidth;
- private final int mDividerHeight;
private final int mIconTouchSize;
private final boolean mIsRtl;
private final int mTouchSlop;
@@ -74,9 +68,6 @@
private LayoutTransition mLayoutTransition;
private int mHotseatStartIndex;
private int mHotseatEndIndex;
- private View mHotseatRecentsDivider;
- private int mRecentsStartIndex;
- private int mRecentsEndIndex;
// Delegate touches to the closest view if within mIconTouchSize.
private boolean mDelegateTargeted;
@@ -104,9 +95,6 @@
super(context, attrs, defStyleAttr, defStyleRes);
Resources resources = getResources();
- mBackgroundDrawable = (ColorDrawable) getBackground();
- mDividerWidth = resources.getDimensionPixelSize(R.dimen.taskbar_divider_thickness);
- mDividerHeight = resources.getDimensionPixelSize(R.dimen.taskbar_divider_height);
mIconTouchSize = resources.getDimensionPixelSize(R.dimen.taskbar_icon_touch_size);
mIsRtl = Utilities.isRtl(resources);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
@@ -119,18 +107,11 @@
mItemMarginLeftRight = Math.round(mItemMarginLeftRight * mNonIconScale);
}
- protected void init(int numHotseatIcons, int numRecentIcons) {
+ protected void init(int numHotseatIcons) {
mHotseatStartIndex = 0;
mHotseatEndIndex = mHotseatStartIndex + numHotseatIcons - 1;
updateHotseatItems(new ItemInfo[numHotseatIcons]);
- int dividerIndex = mHotseatEndIndex + 1;
- mHotseatRecentsDivider = addDivider(dividerIndex);
-
- mRecentsStartIndex = dividerIndex + 1;
- mRecentsEndIndex = mRecentsStartIndex + numRecentIcons - 1;
- updateRecentTasks(new Task[numRecentIcons]);
-
mLayoutTransition = new LayoutTransition();
addUpdateListenerForAllLayoutTransitions(() -> {
if (getLayoutTransition() == mLayoutTransition) {
@@ -165,7 +146,6 @@
endAllLayoutTransitionAnimators();
setLayoutTransition(null);
removeAllViews();
- mHotseatRecentsDivider = null;
}
private void endAllLayoutTransitionAnimators() {
@@ -177,14 +157,6 @@
}
/**
- * Sets the alpha of the background color behind all the Taskbar contents.
- * @param alpha 0 is fully transparent, 1 is fully opaque.
- */
- public void setBackgroundAlpha(float alpha) {
- mBackgroundDrawable.setAlpha((int) (alpha * 255));
- }
-
- /**
* Inflates/binds the Hotseat views to show in the Taskbar given their ItemInfos.
*/
protected void updateHotseatItems(ItemInfo[] hotseatItemInfos) {
@@ -248,8 +220,6 @@
}
updateHotseatItemVisibility(hotseatView);
}
-
- updateHotseatRecentsDividerVisibility();
}
protected void updateHotseatItemsVisibility() {
@@ -273,95 +243,6 @@
}
}
- private View addDivider(int dividerIndex) {
- View divider = inflate(R.layout.taskbar_divider);
- LayoutParams lp = new LayoutParams(mDividerWidth, mDividerHeight);
- lp.setMargins(mItemMarginLeftRight, 0, mItemMarginLeftRight, 0);
- divider.setScaleX(mNonIconScale);
- divider.setScaleY(mNonIconScale);
- addView(divider, dividerIndex, lp);
- return divider;
- }
-
- /**
- * Inflates/binds the Recents items to show in the Taskbar given their Tasks.
- */
- protected void updateRecentTasks(Task[] tasks) {
- for (int i = 0; i < tasks.length; i++) {
- Task task = tasks[i];
- int recentsIndex = mRecentsStartIndex + i;
- View recentsView = getChildAt(recentsIndex);
-
- // Inflate empty icon Views.
- if (recentsView == null) {
- BubbleTextView btv = (BubbleTextView) inflate(R.layout.taskbar_app_icon);
- LayoutParams lp = new LayoutParams(btv.getIconSize(), btv.getIconSize());
- lp.setMargins(mItemMarginLeftRight, 0, mItemMarginLeftRight, 0);
- recentsView = btv;
- addView(recentsView, recentsIndex, lp);
- }
-
- // Apply the Task, or hide the view if there is none for a given index.
- if (recentsView instanceof BubbleTextView && task != null) {
- applyTaskToBubbleTextView((BubbleTextView) recentsView, task);
- recentsView.setVisibility(VISIBLE);
- recentsView.setOnClickListener(mControllerCallbacks.getItemOnClickListener());
- recentsView.setOnLongClickListener(
- mControllerCallbacks.getItemOnLongClickListener());
- } else {
- recentsView.setVisibility(GONE);
- recentsView.setOnClickListener(null);
- recentsView.setOnLongClickListener(null);
- }
- }
-
- updateHotseatRecentsDividerVisibility();
- }
-
- private void applyTaskToBubbleTextView(BubbleTextView btv, Task task) {
- if (task.icon != null) {
- Drawable icon = task.icon.getConstantState().newDrawable().mutate();
- btv.applyIconAndLabel(icon, task.titleDescription);
- }
- btv.setTag(task);
- }
-
- protected void updateRecentTaskAtIndex(int taskIndex, Task task) {
- View taskView = getChildAt(mRecentsStartIndex + taskIndex);
- if (taskView instanceof BubbleTextView) {
- applyTaskToBubbleTextView((BubbleTextView) taskView, task);
- }
- }
-
- /**
- * Make the divider VISIBLE between the Hotseat and Recents if there is at least one icon in
- * each, otherwise make it GONE.
- */
- private void updateHotseatRecentsDividerVisibility() {
- if (mHotseatRecentsDivider == null) {
- return;
- }
-
- boolean hasAtLeastOneHotseatItem = false;
- for (int i = mHotseatStartIndex; i <= mHotseatEndIndex; i++) {
- if (getChildAt(i).getVisibility() != GONE) {
- hasAtLeastOneHotseatItem = true;
- break;
- }
- }
-
- boolean hasAtLeastOneRecentItem = false;
- for (int i = mRecentsStartIndex; i <= mRecentsEndIndex; i++) {
- if (getChildAt(i).getVisibility() != GONE) {
- hasAtLeastOneRecentItem = true;
- break;
- }
- }
-
- mHotseatRecentsDivider.setVisibility(hasAtLeastOneHotseatItem && hasAtLeastOneRecentItem
- ? VISIBLE : GONE);
- }
-
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean handled = delegateTouchIfNecessary(event);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
index 6cdeb0f..30c07b0 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
@@ -88,6 +88,11 @@
}
@Override
+ public float getTaskbarTranslationY(Launcher launcher) {
+ return 0f;
+ }
+
+ @Override
public PageAlphaProvider getWorkspacePageAlphaProvider(Launcher launcher) {
return new PageAlphaProvider(DEACCEL_2) {
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java b/quickstep/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java
index 965f474..53afd21 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java
@@ -35,7 +35,13 @@
float shiftRange = launcher.getAllAppsController().getShiftRange();
float shiftProgress = getVerticalProgress(launcher) - NORMAL.getVerticalProgress(launcher);
float translationY = shiftProgress * shiftRange;
- return new ScaleAndTranslation(1, 0, translationY);
+ return new ScaleAndTranslation(0.9f, 0, translationY);
+ }
+
+ @Override
+ public float getVerticalProgress(Launcher launcher) {
+ // Don't move all apps shelf while quick-switching (just let it fade).
+ return 1f;
}
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
index 697516d..77b0804 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
@@ -23,7 +23,7 @@
import static com.android.launcher3.LauncherState.QUICK_SWITCH;
import static com.android.launcher3.anim.AlphaUpdateListener.ALPHA_CUTOFF_THRESHOLD;
import static com.android.launcher3.anim.Interpolators.ACCEL_0_75;
-import static com.android.launcher3.anim.Interpolators.DEACCEL_5;
+import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
@@ -31,9 +31,10 @@
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_UNKNOWN_SWIPEUP;
import static com.android.launcher3.logging.StatsLogManager.getLauncherAtomEvent;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_DEPTH;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_TRANSLATE;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCALE;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_ALL_ANIMATIONS;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
import static com.android.launcher3.touch.BothAxesSwipeDetector.DIRECTION_RIGHT;
@@ -80,9 +81,8 @@
public class NoButtonQuickSwitchTouchController implements TouchController,
BothAxesSwipeDetector.Listener {
- /** The minimum progress of the scale/translationY animation until drag end. */
private static final float Y_ANIM_MIN_PROGRESS = 0.25f;
- private static final Interpolator FADE_OUT_INTERPOLATOR = DEACCEL_5;
+ private static final Interpolator FADE_OUT_INTERPOLATOR = DEACCEL_3;
private static final Interpolator TRANSLATE_OUT_INTERPOLATOR = ACCEL_0_75;
private static final Interpolator SCALE_DOWN_INTERPOLATOR = LINEAR;
private static final long ATOMIC_DURATION_FROM_PAUSED_TO_OVERVIEW = 300;
@@ -187,7 +187,8 @@
StateAnimationConfig nonOverviewBuilder = new StateAnimationConfig();
nonOverviewBuilder.setInterpolator(ANIM_WORKSPACE_FADE, FADE_OUT_INTERPOLATOR);
nonOverviewBuilder.setInterpolator(ANIM_ALL_APPS_FADE, FADE_OUT_INTERPOLATOR);
- nonOverviewBuilder.setInterpolator(ANIM_WORKSPACE_TRANSLATE, TRANSLATE_OUT_INTERPOLATOR);
+ nonOverviewBuilder.setInterpolator(ANIM_WORKSPACE_SCALE, FADE_OUT_INTERPOLATOR);
+ nonOverviewBuilder.setInterpolator(ANIM_DEPTH, FADE_OUT_INTERPOLATOR);
nonOverviewBuilder.setInterpolator(ANIM_VERTICAL_PROGRESS, TRANSLATE_OUT_INTERPOLATOR);
updateNonOverviewAnim(QUICK_SWITCH, nonOverviewBuilder);
mNonOverviewAnim.dispatchOnStart();
@@ -207,7 +208,7 @@
/** Create state animation to control non-overview components. */
private void updateNonOverviewAnim(LauncherState toState, StateAnimationConfig config) {
config.duration = (long) (Math.max(mXRange, mYRange) * 2);
- config.animFlags = config.animFlags | SKIP_OVERVIEW;
+ config.animFlags |= SKIP_OVERVIEW;
mNonOverviewAnim = mLauncher.getStateManager()
.createAnimationToNewWorkspace(toState, config);
mNonOverviewAnim.getTarget().addListener(mClearStateOnCancelListener);
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 2a903eb..c547d00 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -801,11 +801,9 @@
}
}
if (mParallelRunningAnim != null) {
- if (cancel) {
- mParallelRunningAnim.cancel();
- } else {
- mParallelRunningAnim.end();
- }
+ // Unlike the above animation, the parallel animation won't have anything to take up
+ // the work if it's canceled, so just end it instead.
+ mParallelRunningAnim.end();
}
}
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
index 23e35f6..4a191e1 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -138,7 +138,7 @@
mDisplayId = mDisplayHolder.getInfo().id;
mIsOneHandedModeSupported = SystemProperties.getBoolean(SUPPORT_ONE_HANDED_MODE, false);
runOnDestroy(() -> mDisplayHolder.removeChangeListener(this));
- mRotationTouchHelper = new RotationTouchHelper(context, mDisplayHolder);
+ mRotationTouchHelper = RotationTouchHelper.INSTANCE.get(context);
runOnDestroy(mRotationTouchHelper::destroy);
// Register for user unlocked if necessary
diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java
index ba24e6a..c786167 100644
--- a/quickstep/src/com/android/quickstep/RecentsModel.java
+++ b/quickstep/src/com/android/quickstep/RecentsModel.java
@@ -112,20 +112,19 @@
}
/**
- * Finds and returns the task key associated with the given task id.
+ * Checks if a task has been removed or not.
*
- * @param callback The callback to receive the task key if it is found or null. This is always
- * called on the UI thread.
+ * @param callback Receives true if task is removed, false otherwise
*/
- public void findTaskWithId(int taskId, Consumer<Task.TaskKey> callback) {
+ public void isTaskRemoved(int taskId, Consumer<Boolean> callback) {
mTaskList.getTasks(true /* loadKeysOnly */, (tasks) -> {
for (Task task : tasks) {
if (task.key.id == taskId) {
- callback.accept(task.key);
+ callback.accept(false);
return;
}
}
- callback.accept(null);
+ callback.accept(true);
});
}
diff --git a/quickstep/src/com/android/quickstep/RotationTouchHelper.java b/quickstep/src/com/android/quickstep/RotationTouchHelper.java
index 2cf3212..1155482 100644
--- a/quickstep/src/com/android/quickstep/RotationTouchHelper.java
+++ b/quickstep/src/com/android/quickstep/RotationTouchHelper.java
@@ -28,9 +28,11 @@
import android.view.OrientationEventListener;
import com.android.launcher3.testing.TestProtocol;
+import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.DisplayHolder;
import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener;
import com.android.launcher3.util.DisplayController.Info;
+import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.quickstep.util.RecentsOrientedState;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.QuickStepContract;
@@ -43,6 +45,9 @@
SysUINavigationMode.NavigationModeChangeListener,
DisplayInfoChangeListener {
+ public static final MainThreadInitializedObject<RotationTouchHelper> INSTANCE =
+ new MainThreadInitializedObject<>(RotationTouchHelper::new);
+
private final OrientationTouchTransformer mOrientationTouchTransformer;
private final DisplayHolder mDisplayHolder;
private final SysUINavigationMode mSysUiNavMode;
@@ -121,9 +126,9 @@
private final Context mContext;
- public RotationTouchHelper(Context context, DisplayHolder displayHolder) {
+ private RotationTouchHelper(Context context) {
mContext = context;
- mDisplayHolder = displayHolder;
+ mDisplayHolder = DisplayController.getDefaultDisplay(context);
Resources resources = mContext.getResources();
mSysUiNavMode = SysUINavigationMode.INSTANCE.get(context);
mDisplayId = mDisplayHolder.getInfo().id;
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index 0ee28bc..f6018d1 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -256,18 +256,6 @@
}
@Override
- public Bundle monitorGestureInput(String name, int displayId) {
- if (mSystemUiProxy != null) {
- try {
- return mSystemUiProxy.monitorGestureInput(name, displayId);
- } catch (RemoteException e) {
- Log.w(TAG, "Failed call monitorGestureInput: " + name, e);
- }
- }
- return null;
- }
-
- @Override
public void notifyAccessibilityButtonClicked(int displayId) {
if (mSystemUiProxy != null) {
try {
diff --git a/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java b/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java
index b336d2f..4c10822 100644
--- a/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java
+++ b/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java
@@ -149,6 +149,7 @@
SharedPreferences prefs = getPrefs(mContext);
StatsLogManager.LauncherEvent gridSizeChangedEvent = null;
+ // TODO(b/184981523): This doesn't work for 2-panel grid, which has 6 hotseat icons
switch (prefs.getInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, -1)) {
case 5:
gridSizeChangedEvent = LAUNCHER_GRID_SIZE_5;
diff --git a/quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java b/quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java
index 0436a1c..3b4fd31 100644
--- a/quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java
+++ b/quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java
@@ -15,8 +15,6 @@
*/
package com.android.quickstep.util;
-import static com.android.systemui.shared.system.TransactionCompat.deferTransactionUntil;
-
import android.annotation.TargetApi;
import android.os.Build;
import android.os.Handler;
@@ -90,11 +88,10 @@
for (int i = params.length - 1; i >= 0; i--) {
SurfaceParams surfaceParams = params[i];
if (surfaceParams.surface.isValid()) {
- deferTransactionUntil(t, surfaceParams.surface, mBarrierSurfaceControl, frame);
- surfaceParams.applyTo(t);
+ surfaceParams.applyTo(t);
}
}
- t.apply();
+ mTargetViewRootImpl.mergeWithNextTransaction(t, frame);
Message.obtain(mApplyHandler, MSG_UPDATE_SEQUENCE_NUMBER, toApplySeqNo, 0)
.sendToTarget();
});
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 524bae1..87c46bf 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -72,7 +72,6 @@
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Build;
-import android.os.Handler;
import android.os.UserHandle;
import android.text.Layout;
import android.text.StaticLayout;
@@ -96,6 +95,7 @@
import android.widget.ListView;
import androidx.annotation.Nullable;
+import androidx.annotation.UiThread;
import com.android.launcher3.BaseActivity;
import com.android.launcher3.BaseActivity.MultiWindowModeChangedListener;
@@ -111,6 +111,7 @@
import com.android.launcher3.anim.SpringProperty;
import com.android.launcher3.compat.AccessibilityManagerCompat;
import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.icons.cache.HandlerRunnable;
import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.statemanager.BaseState;
import com.android.launcher3.statemanager.StatefulActivity;
@@ -153,6 +154,7 @@
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
import com.android.systemui.shared.system.TaskStackChangeListener;
+import com.android.systemui.shared.system.TaskStackChangeListeners;
import com.android.wm.shell.pip.IPipAnimationListener;
import java.util.ArrayList;
@@ -394,34 +396,27 @@
return;
}
- UI_HELPER_EXECUTOR.execute(() -> {
- TaskView taskView = getTaskView(taskId);
- if (taskView == null) {
- return;
- }
- Handler handler = taskView.getHandler();
- if (handler == null) {
- return;
- }
-
- // TODO: Add callbacks from AM reflecting adding/removing from the recents list, and
- // remove all these checks
- Task.TaskKey taskKey = taskView.getTask().key;
- if (PackageManagerWrapper.getInstance().getActivityInfo(taskKey.getComponent(),
- taskKey.userId) == null) {
- // The package was uninstalled
- handler.post(() ->
- dismissTask(taskView, true /* animate */, false /* removeTask */));
- } else {
- mModel.findTaskWithId(taskKey.id, (key) -> {
- if (key == null) {
- // The task was removed from the recents list
- handler.post(() -> dismissTask(taskView, true /* animate */,
- false /* removeTask */));
+ TaskView taskView = getTaskView(taskId);
+ if (taskView == null) {
+ return;
+ }
+ Task.TaskKey taskKey = taskView.getTask().key;
+ UI_HELPER_EXECUTOR.execute(new HandlerRunnable<>(
+ UI_HELPER_EXECUTOR.getHandler(),
+ () -> PackageManagerWrapper.getInstance()
+ .getActivityInfo(taskKey.getComponent(), taskKey.userId) == null,
+ MAIN_EXECUTOR,
+ apkRemoved -> {
+ if (apkRemoved) {
+ dismissTask(taskId);
+ } else {
+ mModel.isTaskRemoved(taskKey.id, taskRemoved -> {
+ if (taskRemoved) {
+ dismissTask(taskId);
+ }
+ });
}
- });
- }
- });
+ }));
}
};
@@ -668,7 +663,7 @@
updateTaskStackListenerState();
mModel.getThumbnailCache().getHighResLoadingState().addCallback(this);
mActivity.addMultiWindowModeChangedListener(mMultiWindowModeChangedListener);
- ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
+ TaskStackChangeListeners.getInstance().registerTaskStackListener(mTaskStackListener);
mSyncTransactionApplier = new SurfaceTransactionApplier(this);
mLiveTileParams.setSyncTransactionApplier(mSyncTransactionApplier);
RecentsModel.INSTANCE.get(getContext()).addThumbnailChangeListener(this);
@@ -687,7 +682,7 @@
updateTaskStackListenerState();
mModel.getThumbnailCache().getHighResLoadingState().removeCallback(this);
mActivity.removeMultiWindowModeChangedListener(mMultiWindowModeChangedListener);
- ActivityManagerWrapper.getInstance().unregisterTaskStackListener(mTaskStackListener);
+ TaskStackChangeListeners.getInstance().unregisterTaskStackListener(mTaskStackListener);
mSyncTransactionApplier = null;
mLiveTileParams.setSyncTransactionApplier(null);
RecentsModel.INSTANCE.get(getContext()).removeThumbnailChangeListener(this);
@@ -2177,6 +2172,15 @@
controller.start();
}
+ @UiThread
+ private void dismissTask(int taskId) {
+ TaskView taskView = getTaskView(taskId);
+ if (taskView == null) {
+ return;
+ }
+ dismissTask(taskView, true /* animate */, false /* removeTask */);
+ }
+
public void dismissTask(TaskView taskView, boolean animateTaskView, boolean removeTask) {
runDismissAnimation(createTaskDismissAnimation(taskView, animateTaskView, removeTask,
DISMISS_TASK_DURATION));
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_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/attrs.xml b/res/values/attrs.xml
index 381b0fe..699c2e3 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -175,6 +175,9 @@
<!-- numAllAppsColumns defaults to GridDisplayOption.numColumns, if not specified -->
<attr name="numAllAppsColumns" format="integer" />
+
+ <!-- numShownHotseatIcons defaults to GridDisplayOption.numHotseatIcons, if not specified -->
+ <attr name="numShownHotseatIcons" format="integer" />
</declare-styleable>
<declare-styleable name="CellLayout">
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 51dddab..638eec7 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -140,6 +140,9 @@
<dimen name="widget_row_padding">8dp</dimen>
<dimen name="widget_row_divider">2dp</dimen>
+ <dimen name="widget_picker_education_tip_width">120dp</dimen>
+ <dimen name="widget_picker_education_tip_min_margin">4dp</dimen>
+
<!-- Padding applied to shortcut previews -->
<dimen name="shortcut_preview_padding_left">0dp</dimen>
<dimen name="shortcut_preview_padding_right">0dp</dimen>
diff --git a/robolectric_tests/src/com/android/launcher3/model/BackupRestoreTest.java b/robolectric_tests/src/com/android/launcher3/model/BackupRestoreTest.java
index adf720f..34a8025 100644
--- a/robolectric_tests/src/com/android/launcher3/model/BackupRestoreTest.java
+++ b/robolectric_tests/src/com/android/launcher3/model/BackupRestoreTest.java
@@ -127,7 +127,7 @@
{ APP_ICON, SHORTCUT, SHORTCUT, NO__ICON},
}}, 2, OLD_WORK_PROFILE_ID);
// simulates the creation of backup upon restore
- new GridBackupTable(RuntimeEnvironment.application, mDb, mIdp.numHotseatIcons,
+ new GridBackupTable(RuntimeEnvironment.application, mDb, mIdp.numDatabaseHotseatIcons,
mIdp.numColumns, mIdp.numRows).doBackup(
MY_OLD_PROFILE_ID, GridBackupTable.OPTION_REQUIRES_SANITIZATION);
// reset favorites table
diff --git a/robolectric_tests/src/com/android/launcher3/model/GridSizeMigrationTaskTest.java b/robolectric_tests/src/com/android/launcher3/model/GridSizeMigrationTaskTest.java
index 8e00dcb..d544a0b 100644
--- a/robolectric_tests/src/com/android/launcher3/model/GridSizeMigrationTaskTest.java
+++ b/robolectric_tests/src/com/android/launcher3/model/GridSizeMigrationTaskTest.java
@@ -64,7 +64,7 @@
mModelHelper.addItem(APP_ICON, 4, HOTSEAT, 0, 0),
};
- mIdp.numHotseatIcons = 3;
+ mIdp.numDatabaseHotseatIcons = 3;
new GridSizeMigrationTask(mContext, mDb, mValidPackages, false, 5, 3)
.migrateHotseat();
// First item is dropped as it has the least weight.
@@ -81,7 +81,7 @@
mModelHelper.addItem(10, 4, HOTSEAT, 0, 0),
};
- mIdp.numHotseatIcons = 3;
+ mIdp.numDatabaseHotseatIcons = 3;
new GridSizeMigrationTask(mContext, mDb, mValidPackages, false, 5, 3)
.migrateHotseat();
// First item is dropped as it has the least weight.
diff --git a/robolectric_tests/src/com/android/launcher3/model/GridSizeMigrationTaskV2Test.java b/robolectric_tests/src/com/android/launcher3/model/GridSizeMigrationTaskV2Test.java
index cca333c..8e49fae 100644
--- a/robolectric_tests/src/com/android/launcher3/model/GridSizeMigrationTaskV2Test.java
+++ b/robolectric_tests/src/com/android/launcher3/model/GridSizeMigrationTaskV2Test.java
@@ -120,7 +120,7 @@
};
mModelHelper.addItem(APP_ICON, 0, DESKTOP, 2, 2, testPackage7);
- mIdp.numHotseatIcons = 4;
+ mIdp.numDatabaseHotseatIcons = 4;
mIdp.numColumns = 4;
mIdp.numRows = 4;
GridSizeMigrationTaskV2.DbReader srcReader = new GridSizeMigrationTaskV2.DbReader(mDb,
@@ -128,16 +128,16 @@
srcHotseatItems.length);
GridSizeMigrationTaskV2.DbReader destReader = new GridSizeMigrationTaskV2.DbReader(mDb,
LauncherSettings.Favorites.TABLE_NAME, mContext, mValidPackages,
- mIdp.numHotseatIcons);
+ mIdp.numDatabaseHotseatIcons);
GridSizeMigrationTaskV2 task = new GridSizeMigrationTaskV2(mContext, mDb, srcReader,
- destReader, mIdp.numHotseatIcons, new Point(mIdp.numColumns, mIdp.numRows));
+ destReader, mIdp.numDatabaseHotseatIcons, new Point(mIdp.numColumns, mIdp.numRows));
task.migrate();
// Check hotseat items
Cursor c = mContext.getContentResolver().query(LauncherSettings.Favorites.CONTENT_URI,
new String[]{LauncherSettings.Favorites.SCREEN, LauncherSettings.Favorites.INTENT},
"container=" + CONTAINER_HOTSEAT, null, null, null);
- assertEquals(c.getCount(), mIdp.numHotseatIcons);
+ assertEquals(c.getCount(), mIdp.numDatabaseHotseatIcons);
int screenIndex = c.getColumnIndex(LauncherSettings.Favorites.SCREEN);
int intentIndex = c.getColumnIndex(LauncherSettings.Favorites.INTENT);
c.moveToNext();
@@ -186,5 +186,101 @@
assertTrue(c.getString(intentIndex).contains(testPackage8));
assertEquals(c.getInt(cellXIndex), 0);
assertEquals(c.getInt(cellYIndex), 2);
+
+ c.close();
+ }
+
+ @Test
+ public void migrateToLargerHotseat() {
+ int[] srcHotseatItems = {
+ mModelHelper.addItem(APP_ICON, 0, HOTSEAT, 0, 0, testPackage1, 1, TMP_CONTENT_URI),
+ mModelHelper.addItem(SHORTCUT, 1, HOTSEAT, 0, 0, testPackage2, 2, TMP_CONTENT_URI),
+ mModelHelper.addItem(APP_ICON, 2, HOTSEAT, 0, 0, testPackage3, 3, TMP_CONTENT_URI),
+ mModelHelper.addItem(SHORTCUT, 3, HOTSEAT, 0, 0, testPackage4, 4, TMP_CONTENT_URI),
+ };
+
+ int numSrcDatabaseHotseatIcons = srcHotseatItems.length;
+ mIdp.numDatabaseHotseatIcons = 6;
+ mIdp.numColumns = 4;
+ mIdp.numRows = 4;
+ GridSizeMigrationTaskV2.DbReader srcReader = new GridSizeMigrationTaskV2.DbReader(mDb,
+ LauncherSettings.Favorites.TMP_TABLE, mContext, mValidPackages,
+ numSrcDatabaseHotseatIcons);
+ GridSizeMigrationTaskV2.DbReader destReader = new GridSizeMigrationTaskV2.DbReader(mDb,
+ LauncherSettings.Favorites.TABLE_NAME, mContext, mValidPackages,
+ mIdp.numDatabaseHotseatIcons);
+ GridSizeMigrationTaskV2 task = new GridSizeMigrationTaskV2(mContext, mDb, srcReader,
+ destReader, mIdp.numDatabaseHotseatIcons, new Point(mIdp.numColumns, mIdp.numRows));
+ task.migrate();
+
+ // Check hotseat items
+ Cursor c = mContext.getContentResolver().query(LauncherSettings.Favorites.CONTENT_URI,
+ new String[]{LauncherSettings.Favorites.SCREEN, LauncherSettings.Favorites.INTENT},
+ "container=" + CONTAINER_HOTSEAT, null, null, null);
+ assertEquals(c.getCount(), numSrcDatabaseHotseatIcons);
+ int screenIndex = c.getColumnIndex(LauncherSettings.Favorites.SCREEN);
+ int intentIndex = c.getColumnIndex(LauncherSettings.Favorites.INTENT);
+ c.moveToNext();
+ assertEquals(c.getInt(screenIndex), 0);
+ assertTrue(c.getString(intentIndex).contains(testPackage1));
+ c.moveToNext();
+ assertEquals(c.getInt(screenIndex), 1);
+ assertTrue(c.getString(intentIndex).contains(testPackage2));
+ c.moveToNext();
+ assertEquals(c.getInt(screenIndex), 2);
+ assertTrue(c.getString(intentIndex).contains(testPackage3));
+ c.moveToNext();
+ assertEquals(c.getInt(screenIndex), 3);
+ assertTrue(c.getString(intentIndex).contains(testPackage4));
+
+ c.close();
+ }
+
+ @Test
+ public void migrateFromLargerHotseat() {
+ int[] srcHotseatItems = {
+ mModelHelper.addItem(APP_ICON, 0, HOTSEAT, 0, 0, testPackage1, 1, TMP_CONTENT_URI),
+ -1,
+ mModelHelper.addItem(SHORTCUT, 2, HOTSEAT, 0, 0, testPackage2, 2, TMP_CONTENT_URI),
+ mModelHelper.addItem(APP_ICON, 3, HOTSEAT, 0, 0, testPackage3, 3, TMP_CONTENT_URI),
+ mModelHelper.addItem(SHORTCUT, 4, HOTSEAT, 0, 0, testPackage4, 4, TMP_CONTENT_URI),
+ mModelHelper.addItem(APP_ICON, 5, HOTSEAT, 0, 0, testPackage5, 5, TMP_CONTENT_URI),
+ };
+
+ int numSrcDatabaseHotseatIcons = srcHotseatItems.length;
+ mIdp.numDatabaseHotseatIcons = 4;
+ mIdp.numColumns = 4;
+ mIdp.numRows = 4;
+ GridSizeMigrationTaskV2.DbReader srcReader = new GridSizeMigrationTaskV2.DbReader(mDb,
+ LauncherSettings.Favorites.TMP_TABLE, mContext, mValidPackages,
+ numSrcDatabaseHotseatIcons);
+ GridSizeMigrationTaskV2.DbReader destReader = new GridSizeMigrationTaskV2.DbReader(mDb,
+ LauncherSettings.Favorites.TABLE_NAME, mContext, mValidPackages,
+ mIdp.numDatabaseHotseatIcons);
+ GridSizeMigrationTaskV2 task = new GridSizeMigrationTaskV2(mContext, mDb, srcReader,
+ destReader, mIdp.numDatabaseHotseatIcons, new Point(mIdp.numColumns, mIdp.numRows));
+ task.migrate();
+
+ // Check hotseat items
+ Cursor c = mContext.getContentResolver().query(LauncherSettings.Favorites.CONTENT_URI,
+ new String[]{LauncherSettings.Favorites.SCREEN, LauncherSettings.Favorites.INTENT},
+ "container=" + CONTAINER_HOTSEAT, null, null, null);
+ assertEquals(c.getCount(), mIdp.numDatabaseHotseatIcons);
+ int screenIndex = c.getColumnIndex(LauncherSettings.Favorites.SCREEN);
+ int intentIndex = c.getColumnIndex(LauncherSettings.Favorites.INTENT);
+ c.moveToNext();
+ assertEquals(c.getInt(screenIndex), 0);
+ assertTrue(c.getString(intentIndex).contains(testPackage1));
+ c.moveToNext();
+ assertEquals(c.getInt(screenIndex), 1);
+ assertTrue(c.getString(intentIndex).contains(testPackage2));
+ c.moveToNext();
+ assertEquals(c.getInt(screenIndex), 2);
+ assertTrue(c.getString(intentIndex).contains(testPackage3));
+ c.moveToNext();
+ assertEquals(c.getInt(screenIndex), 3);
+ assertTrue(c.getString(intentIndex).contains(testPackage4));
+
+ c.close();
}
}
diff --git a/robolectric_tests/src/com/android/launcher3/model/LoaderCursorTest.java b/robolectric_tests/src/com/android/launcher3/model/LoaderCursorTest.java
index fb08c56..800311a 100644
--- a/robolectric_tests/src/com/android/launcher3/model/LoaderCursorTest.java
+++ b/robolectric_tests/src/com/android/launcher3/model/LoaderCursorTest.java
@@ -160,7 +160,7 @@
public void checkItemPlacement_outsideBounds() {
mIDP.numRows = 4;
mIDP.numColumns = 4;
- mIDP.numHotseatIcons = 3;
+ mIDP.numDatabaseHotseatIcons = 3;
// Item outside screen bounds are not placed
assertFalse(mLoaderCursor.checkItemPlacement(
@@ -171,7 +171,7 @@
public void checkItemPlacement_overlappingItems() {
mIDP.numRows = 4;
mIDP.numColumns = 4;
- mIDP.numHotseatIcons = 3;
+ mIDP.numDatabaseHotseatIcons = 3;
// Overlapping mItems are not placed
assertTrue(mLoaderCursor.checkItemPlacement(
@@ -197,7 +197,7 @@
public void checkItemPlacement_hotseat() {
mIDP.numRows = 4;
mIDP.numColumns = 4;
- mIDP.numHotseatIcons = 3;
+ mIDP.numDatabaseHotseatIcons = 3;
// Hotseat mItems are only placed based on screenId
assertTrue(mLoaderCursor.checkItemPlacement(
diff --git a/robolectric_tests/src/com/android/launcher3/util/LauncherModelHelper.java b/robolectric_tests/src/com/android/launcher3/util/LauncherModelHelper.java
index 849f98b..846e201 100644
--- a/robolectric_tests/src/com/android/launcher3/util/LauncherModelHelper.java
+++ b/robolectric_tests/src/com/android/launcher3/util/LauncherModelHelper.java
@@ -355,7 +355,7 @@
throws Exception {
Context context = RuntimeEnvironment.application;
InvariantDeviceProfile idp = InvariantDeviceProfile.INSTANCE.get(context);
- idp.numRows = idp.numColumns = idp.numHotseatIcons = DEFAULT_GRID_SIZE;
+ idp.numRows = idp.numColumns = idp.numDatabaseHotseatIcons = DEFAULT_GRID_SIZE;
idp.iconBitmapSize = DEFAULT_BITMAP_SIZE;
Settings.Secure.putString(context.getContentResolver(),
diff --git a/src/com/android/launcher3/AutoInstallsLayout.java b/src/com/android/launcher3/AutoInstallsLayout.java
index f61bc05..5b655a4 100644
--- a/src/com/android/launcher3/AutoInstallsLayout.java
+++ b/src/com/android/launcher3/AutoInstallsLayout.java
@@ -89,7 +89,7 @@
// Try with grid size and hotseat count
String layoutName = String.format(Locale.ENGLISH, FORMATTED_LAYOUT_RES_WITH_HOSTEAT,
- grid.numColumns, grid.numRows, grid.numHotseatIcons);
+ grid.numColumns, grid.numRows, grid.numDatabaseHotseatIcons);
int layoutId = targetRes.getIdentifier(layoutName, "xml", pkg);
// Try with only grid size
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 35b0f27..985a445 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -137,6 +137,7 @@
public int folderChildDrawablePaddingPx;
// Hotseat
+ public final int numShownHotseatIcons;
public int hotseatCellHeightPx;
// In portrait: size = height, in landscape: size = width
public int hotseatBarSizePx;
@@ -293,6 +294,7 @@
workspaceCellPaddingXPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_cell_padding_x);
+ numShownHotseatIcons = inv.numShownHotseatIcons;
hotseatBarTopPaddingPx =
res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_top_padding);
hotseatBarBottomPaddingPx = (isTallDevice ? 0
@@ -735,7 +737,7 @@
// for this, we pad the left and right of the hotseat with half of the difference of a
// workspace cell vs a hotseat cell.
float workspaceCellWidth = (float) widthPx / inv.numColumns;
- float hotseatCellWidth = (float) widthPx / inv.numHotseatIcons;
+ float hotseatCellWidth = (float) widthPx / inv.numShownHotseatIcons;
int hotseatAdjustment = Math.round((workspaceCellWidth - hotseatCellWidth) / 2);
mHotseatPadding.set(
hotseatAdjustment + workspacePadding.left + cellLayoutPaddingLeftRightPx
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 5429806..8496fd5 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -92,9 +92,9 @@
mHasVerticalHotseat = hasVerticalHotseat;
InvariantDeviceProfile idp = mActivity.getDeviceProfile().inv;
if (hasVerticalHotseat) {
- setGridSize(1, idp.numHotseatIcons);
+ setGridSize(1, idp.numShownHotseatIcons);
} else {
- setGridSize(idp.numHotseatIcons, 1);
+ setGridSize(idp.numShownHotseatIcons, 1);
}
}
@@ -199,25 +199,38 @@
int left = (r - l - qsbWidth) / 2;
int right = left + qsbWidth;
- DeviceProfile dp = mActivity.getDeviceProfile();
- int freeSpace = dp.isTaskbarPresent
- ? dp.workspacePadding.bottom
- : dp.hotseatBarSizePx - dp.hotseatCellHeightPx - mQsbHeight;
- int bottom = b - t
- - (int) (freeSpace * QSB_CENTER_FACTOR)
- - (dp.isTaskbarPresent ? dp.taskbarSize : dp.getInsets().bottom);
+ int bottom = b - t - getQsbOffsetY();
int top = bottom - mQsbHeight;
mQsb.layout(left, top, right, bottom);
int taskbarWidth = mTaskbarView.getMeasuredWidth();
left = (r - l - taskbarWidth) / 2;
right = left + taskbarWidth;
- bottom = b - t;
+ bottom = b - t - getTaskbarOffsetY();
top = bottom - mTaskbarViewHeight;
mTaskbarView.layout(left, top, right, bottom);
}
/**
+ * Returns the number of pixels the QSB is translated from the bottom of the screen.
+ */
+ private int getQsbOffsetY() {
+ DeviceProfile dp = mActivity.getDeviceProfile();
+ int freeSpace = dp.isTaskbarPresent
+ ? dp.workspacePadding.bottom
+ : dp.hotseatBarSizePx - dp.hotseatCellHeightPx - mQsbHeight;
+ return (int) (freeSpace * QSB_CENTER_FACTOR)
+ + (dp.isTaskbarPresent ? dp.taskbarSize : dp.getInsets().bottom);
+ }
+
+ /**
+ * Returns the number of pixels the taskbar is translated from the bottom of the screen.
+ */
+ public int getTaskbarOffsetY() {
+ return (getQsbOffsetY() - mTaskbarViewHeight) / 2;
+ }
+
+ /**
* Sets the alpha value of just our ShortcutAndWidgetContainer.
*/
public void setIconsAlpha(float alpha) {
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 5612daf..f198777 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -122,7 +122,14 @@
/**
* Number of icons inside the hotseat area.
*/
- public int numHotseatIcons;
+ protected int numShownHotseatIcons;
+
+ /**
+ * Number of icons inside the hotseat area that is stored in the database. This is greater than
+ * or equal to numnShownHotseatIcons, allowing for a seamless transition between two hotseat
+ * sizes that share the same DB.
+ */
+ public int numDatabaseHotseatIcons;
/**
* Number of columns in the all apps list.
@@ -165,7 +172,8 @@
iconBitmapSize = p.iconBitmapSize;
iconTextSize = p.iconTextSize;
landscapeIconTextSize = p.landscapeIconTextSize;
- numHotseatIcons = p.numHotseatIcons;
+ numShownHotseatIcons = p.numShownHotseatIcons;
+ numDatabaseHotseatIcons = p.numDatabaseHotseatIcons;
numAllAppsColumns = p.numAllAppsColumns;
isScalable = p.isScalable;
devicePaddingId = p.devicePaddingId;
@@ -190,7 +198,7 @@
Utilities.getPrefs(context).edit().putString(KEY_IDP_GRID_NAME, newGridName).apply();
}
Utilities.getPrefs(context).edit()
- .putInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, numHotseatIcons)
+ .putInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, numDatabaseHotseatIcons)
.putString(KEY_MIGRATION_SRC_WORKSPACE_SIZE, getPointString(numColumns, numRows))
.apply();
@@ -229,6 +237,7 @@
.add(myDisplayOption);
result.iconSize = defaultDisplayOption.iconSize;
result.landscapeIconSize = defaultDisplayOption.landscapeIconSize;
+ result.numShownHotseatIcons = myDisplayOption.numShownHotseatIcons;
if (defaultDisplayOption.allAppsIconSize < myDisplayOption.allAppsIconSize) {
result.allAppsIconSize = defaultDisplayOption.allAppsIconSize;
result.numAllAppsColumns = defaultDisplayOption.numAllAppsColumns;
@@ -279,7 +288,7 @@
GridOption closestProfile = displayOption.grid;
numRows = closestProfile.numRows;
numColumns = closestProfile.numColumns;
- numHotseatIcons = closestProfile.numHotseatIcons;
+ numDatabaseHotseatIcons = closestProfile.numDatabaseHotseatIcons;
dbFile = closestProfile.dbFile;
defaultLayoutId = closestProfile.defaultLayoutId;
demoModeLayoutId = closestProfile.demoModeLayoutId;
@@ -301,6 +310,7 @@
minCellHeight = displayOption.minCellHeight;
minCellWidth = displayOption.minCellWidth;
borderSpacing = displayOption.borderSpacing;
+ numShownHotseatIcons = Math.round(displayOption.numShownHotseatIcons);
numAllAppsColumns = Math.round(displayOption.numAllAppsColumns);
if (Utilities.isGridOptionsEnabled(context)) {
@@ -391,7 +401,7 @@
numColumns != oldProfile.numColumns ||
numFolderColumns != oldProfile.numFolderColumns ||
numFolderRows != oldProfile.numFolderRows ||
- numHotseatIcons != oldProfile.numHotseatIcons) {
+ numDatabaseHotseatIcons != oldProfile.numDatabaseHotseatIcons) {
changeFlags |= CHANGE_FLAG_GRID;
}
@@ -619,7 +629,7 @@
private final int numFolderRows;
private final int numFolderColumns;
- private final int numHotseatIcons;
+ private final int numDatabaseHotseatIcons;
private final String dbFile;
@@ -645,7 +655,7 @@
R.styleable.GridDisplayOption_defaultLayoutId, 0);
demoModeLayoutId = a.getResourceId(
R.styleable.GridDisplayOption_demoModeLayoutId, defaultLayoutId);
- numHotseatIcons = a.getInt(
+ numDatabaseHotseatIcons = a.getInt(
R.styleable.GridDisplayOption_numHotseatIcons, numColumns);
numFolderRows = a.getInt(
R.styleable.GridDisplayOption_numFolderRows, numRows);
@@ -673,6 +683,7 @@
private final float minHeightDps;
private final boolean canBeDefault;
+ private float numShownHotseatIcons;
private float numAllAppsColumns;
private float minCellHeight;
private float minCellWidth;
@@ -695,6 +706,8 @@
minHeightDps = a.getFloat(R.styleable.ProfileDisplayOption_minHeightDps, 0);
canBeDefault = a.getBoolean(
R.styleable.ProfileDisplayOption_canBeDefault, false);
+ numShownHotseatIcons = a.getInt(R.styleable.ProfileDisplayOption_numShownHotseatIcons,
+ grid.numDatabaseHotseatIcons);
numAllAppsColumns = a.getInt(R.styleable.ProfileDisplayOption_numAllAppsColumns,
grid.numColumns);
@@ -725,6 +738,7 @@
minWidthDps = 0;
minHeightDps = 0;
canBeDefault = false;
+ numShownHotseatIcons = 0;
numAllAppsColumns = 0;
minCellHeight = 0;
minCellWidth = 0;
@@ -732,6 +746,7 @@
}
private DisplayOption multiply(float w) {
+ numShownHotseatIcons *= w;
numAllAppsColumns *= w;
iconSize *= w;
landscapeIconSize *= w;
@@ -746,6 +761,7 @@
}
private DisplayOption add(DisplayOption p) {
+ numShownHotseatIcons += p.numShownHotseatIcons;
numAllAppsColumns += p.numAllAppsColumns;
iconSize += p.iconSize;
landscapeIconSize += p.landscapeIconSize;
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 699495c..eef3980 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -130,6 +130,10 @@
mModelDelegate = ModelDelegate.newInstance(context, app, mBgAllAppsList, mBgDataModel);
}
+ public ModelDelegate getModelDelegate() {
+ return mModelDelegate;
+ }
+
/**
* Adds the provided items to the workspace.
*/
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 2ec5e90..39b16fd 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -618,7 +618,7 @@
.appendQueryParameter("version", "1")
.appendQueryParameter("gridWidth", Integer.toString(grid.numColumns))
.appendQueryParameter("gridHeight", Integer.toString(grid.numRows))
- .appendQueryParameter("hotseatSize", Integer.toString(grid.numHotseatIcons))
+ .appendQueryParameter("hotseatSize", Integer.toString(grid.numDatabaseHotseatIcons))
.build();
}
diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java
index 0c509a1..58df9c8 100644
--- a/src/com/android/launcher3/LauncherState.java
+++ b/src/com/android/launcher3/LauncherState.java
@@ -184,6 +184,10 @@
return launcher.getNormalTaskbarScale();
}
+ public float getTaskbarTranslationY(Launcher launcher) {
+ return -launcher.getHotseat().getTaskbarOffsetY();
+ }
+
public float getOverviewFullscreenProgress() {
return 0;
}
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 406e785..41865ce 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -75,9 +75,9 @@
public class AllAppsContainerView extends SpringRelativeLayout implements DragSource,
Insettable, OnDeviceProfileChangeListener, OnActivePageChangedListener {
- private static final float FLING_VELOCITY_MULTIPLIER = 1000 * .8f;
+ private static final float FLING_VELOCITY_MULTIPLIER = 1000 * .2f;
// Starts the springs after at least 55% of the animation has passed.
- private static final float FLING_ANIMATION_THRESHOLD = 0.55f;
+ private static final float FLING_ANIMATION_THRESHOLD = 0.25f;
protected final BaseDraggingActivity mLauncher;
protected final AdapterHolder[] mAH;
diff --git a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
index a8185d6..2491217 100644
--- a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
+++ b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
@@ -106,7 +106,7 @@
- mAppsView.getActiveRecyclerView().getPaddingRight();
int cellWidth = DeviceProfile.calculateCellWidth(rowWidth, dp.cellLayoutBorderSpacingPx,
- dp.inv.numHotseatIcons);
+ dp.numShownHotseatIcons);
int iconVisibleSize = Math.round(ICON_VISIBLE_AREA_FACTOR * dp.iconSizePx);
int iconPadding = cellWidth - iconVisibleSize;
diff --git a/src/com/android/launcher3/anim/Interpolators.java b/src/com/android/launcher3/anim/Interpolators.java
index 7980138..7a38937 100644
--- a/src/com/android/launcher3/anim/Interpolators.java
+++ b/src/com/android/launcher3/anim/Interpolators.java
@@ -46,7 +46,6 @@
public static final Interpolator DEACCEL_2 = new DecelerateInterpolator(2);
public static final Interpolator DEACCEL_2_5 = new DecelerateInterpolator(2.5f);
public static final Interpolator DEACCEL_3 = new DecelerateInterpolator(3f);
- public static final Interpolator DEACCEL_5 = new DecelerateInterpolator(5f);
public static final Interpolator ACCEL_DEACCEL = new AccelerateDecelerateInterpolator();
diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
index 5e9b179..31764c5 100644
--- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
+++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
@@ -467,7 +467,7 @@
}
}
IntArray ranks = getMissingHotseatRanks(currentWorkspaceItems,
- mIdp.numHotseatIcons);
+ mDp.numShownHotseatIcons);
List<ItemInfo> predictions = workspaceResult.mHotseatPredictions == null
? Collections.emptyList() : workspaceResult.mHotseatPredictions.items;
int count = Math.min(ranks.size(), predictions.size());
@@ -484,7 +484,7 @@
}
} else {
// Add hotseat icons
- for (int i = 0; i < mIdp.numHotseatIcons; i++) {
+ for (int i = 0; i < mDp.numShownHotseatIcons; i++) {
WorkspaceItemInfo info = new WorkspaceItemInfo(mWorkspaceItemInfo);
info.container = Favorites.CONTAINER_HOTSEAT;
info.screenId = i;
diff --git a/src/com/android/launcher3/model/GridSizeMigrationTask.java b/src/com/android/launcher3/model/GridSizeMigrationTask.java
index 804e72e..6a75e62 100644
--- a/src/com/android/launcher3/model/GridSizeMigrationTask.java
+++ b/src/com/android/launcher3/model/GridSizeMigrationTask.java
@@ -893,7 +893,7 @@
String gridSizeString = getPointString(idp.numColumns, idp.numRows);
return !gridSizeString.equals(prefs.getString(KEY_MIGRATION_SRC_WORKSPACE_SIZE, ""))
- || idp.numHotseatIcons != prefs.getInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, -1);
+ || idp.numDatabaseHotseatIcons != prefs.getInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, -1);
}
/** See {@link #migrateGridIfNeeded(Context, InvariantDeviceProfile)} */
@@ -928,7 +928,7 @@
.getBinder(Settings.EXTRA_VALUE)) {
int srcHotseatCount = prefs.getInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT,
- idp.numHotseatIcons);
+ idp.numDatabaseHotseatIcons);
Point sourceSize = parsePoint(prefs.getString(
KEY_MIGRATION_SRC_WORKSPACE_SIZE, gridSizeString));
@@ -948,10 +948,10 @@
HashSet<String> validPackages = getValidPackages(context);
// Hotseat.
- if (srcHotseatCount != idp.numHotseatIcons
+ if (srcHotseatCount != idp.numDatabaseHotseatIcons
&& new GridSizeMigrationTask(context, transaction.getDb(), validPackages,
migrateForPreview, srcHotseatCount,
- idp.numHotseatIcons).migrateHotseat()) {
+ idp.numDatabaseHotseatIcons).migrateHotseat()) {
dbChanged = true;
}
@@ -991,7 +991,7 @@
// Save current configuration, so that the migration does not run again.
prefs.edit()
.putString(KEY_MIGRATION_SRC_WORKSPACE_SIZE, gridSizeString)
- .putInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, idp.numHotseatIcons)
+ .putInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, idp.numDatabaseHotseatIcons)
.apply();
}
}
diff --git a/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java b/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
index c6c0791..cee9304 100644
--- a/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
+++ b/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
@@ -110,7 +110,7 @@
String gridSizeString = getPointString(idp.numColumns, idp.numRows);
return !gridSizeString.equals(prefs.getString(KEY_MIGRATION_SRC_WORKSPACE_SIZE, ""))
- || idp.numHotseatIcons != prefs.getInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, -1);
+ || idp.numDatabaseHotseatIcons != prefs.getInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, -1);
}
/** See {@link #migrateGridIfNeeded(Context, InvariantDeviceProfile)} */
@@ -148,7 +148,8 @@
SharedPreferences prefs = Utilities.getPrefs(context);
String gridSizeString = getPointString(idp.numColumns, idp.numRows);
HashSet<String> validPackages = getValidPackages(context);
- int srcHotseatCount = prefs.getInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, idp.numHotseatIcons);
+ int srcHotseatCount = prefs.getInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT,
+ idp.numDatabaseHotseatIcons);
if (migrateForPreview) {
if (!LauncherSettings.Settings.call(
@@ -177,11 +178,11 @@
DbReader destReader = new DbReader(t.getDb(),
migrateForPreview ? LauncherSettings.Favorites.PREVIEW_TABLE_NAME
: LauncherSettings.Favorites.TABLE_NAME,
- context, validPackages, idp.numHotseatIcons);
+ context, validPackages, idp.numDatabaseHotseatIcons);
Point targetSize = new Point(idp.numColumns, idp.numRows);
GridSizeMigrationTaskV2 task = new GridSizeMigrationTaskV2(context, t.getDb(),
- srcReader, destReader, idp.numHotseatIcons, targetSize);
+ srcReader, destReader, idp.numDatabaseHotseatIcons, targetSize);
task.migrate();
if (!migrateForPreview) {
@@ -202,7 +203,7 @@
// Save current configuration, so that the migration does not run again.
prefs.edit()
.putString(KEY_MIGRATION_SRC_WORKSPACE_SIZE, gridSizeString)
- .putInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, idp.numHotseatIcons)
+ .putInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, idp.numDatabaseHotseatIcons)
.apply();
}
}
diff --git a/src/com/android/launcher3/model/LoaderCursor.java b/src/com/android/launcher3/model/LoaderCursor.java
index 19d9af9..897b02e 100644
--- a/src/com/android/launcher3/model/LoaderCursor.java
+++ b/src/com/android/launcher3/model/LoaderCursor.java
@@ -410,10 +410,10 @@
final GridOccupancy hotseatOccupancy =
occupied.get(LauncherSettings.Favorites.CONTAINER_HOTSEAT);
- if (item.screenId >= mIDP.numHotseatIcons) {
+ if (item.screenId >= mIDP.numDatabaseHotseatIcons) {
Log.e(TAG, "Error loading shortcut " + item
+ " into hotseat position " + item.screenId
- + ", position out of bounds: (0 to " + (mIDP.numHotseatIcons - 1)
+ + ", position out of bounds: (0 to " + (mIDP.numDatabaseHotseatIcons - 1)
+ ")");
return false;
}
@@ -429,7 +429,7 @@
return true;
}
} else {
- final GridOccupancy occupancy = new GridOccupancy(mIDP.numHotseatIcons, 1);
+ final GridOccupancy occupancy = new GridOccupancy(mIDP.numDatabaseHotseatIcons, 1);
occupancy.cells[item.screenId][0] = true;
occupied.put(LauncherSettings.Favorites.CONTAINER_HOTSEAT, occupancy);
return true;
diff --git a/src/com/android/launcher3/model/ModelWriter.java b/src/com/android/launcher3/model/ModelWriter.java
index 312435d..080ce20 100644
--- a/src/com/android/launcher3/model/ModelWriter.java
+++ b/src/com/android/launcher3/model/ModelWriter.java
@@ -91,7 +91,7 @@
// in the hotseat
if (container == Favorites.CONTAINER_HOTSEAT) {
item.screenId = mHasVerticalHotseat
- ? LauncherAppState.getIDP(mContext).numHotseatIcons - cellY - 1 : cellX;
+ ? LauncherAppState.getIDP(mContext).numDatabaseHotseatIcons - cellY - 1 : cellX;
} else {
item.screenId = screenId;
}
diff --git a/src/com/android/launcher3/provider/ImportDataTask.java b/src/com/android/launcher3/provider/ImportDataTask.java
index a5462a6..c9af2fe 100644
--- a/src/com/android/launcher3/provider/ImportDataTask.java
+++ b/src/com/android/launcher3/provider/ImportDataTask.java
@@ -284,8 +284,9 @@
insertOperations.clear();
}
- IntSparseArrayMap<Object> hotseatItems = GridSizeMigrationTask.removeBrokenHotseatItems(mContext);
- int myHotseatCount = LauncherAppState.getIDP(mContext).numHotseatIcons;
+ IntSparseArrayMap<Object> hotseatItems = GridSizeMigrationTask
+ .removeBrokenHotseatItems(mContext);
+ int myHotseatCount = LauncherAppState.getIDP(mContext).numDatabaseHotseatIcons;
if (hotseatItems.size() < myHotseatCount) {
// Insufficient hotseat items. Add a few more.
HotseatParserCallback parserCallback = new HotseatParserCallback(
diff --git a/src/com/android/launcher3/provider/RestoreDbTask.java b/src/com/android/launcher3/provider/RestoreDbTask.java
index 53183bf..223f4f1 100644
--- a/src/com/android/launcher3/provider/RestoreDbTask.java
+++ b/src/com/android/launcher3/provider/RestoreDbTask.java
@@ -103,7 +103,7 @@
*/
private void backupWorkspace(Context context, SQLiteDatabase db) throws Exception {
InvariantDeviceProfile idp = LauncherAppState.getIDP(context);
- new GridBackupTable(context, db, idp.numHotseatIcons, idp.numColumns, idp.numRows)
+ new GridBackupTable(context, db, idp.numDatabaseHotseatIcons, idp.numColumns, idp.numRows)
.doBackup(getDefaultProfileId(db), GridBackupTable.OPTION_REQUIRES_SANITIZATION);
}
@@ -111,7 +111,7 @@
@NonNull DatabaseHelper helper, @NonNull BackupManager backupManager)
throws Exception {
final InvariantDeviceProfile idp = LauncherAppState.getIDP(context);
- GridBackupTable backupTable = new GridBackupTable(context, db, idp.numHotseatIcons,
+ GridBackupTable backupTable = new GridBackupTable(context, db, idp.numDatabaseHotseatIcons,
idp.numColumns, idp.numRows);
if (backupTable.restoreFromRawBackupIfAvailable(getDefaultProfileId(db))) {
int itemsDeleted = sanitizeDB(helper, db, backupManager);
diff --git a/src/com/android/launcher3/views/ArrowTipView.java b/src/com/android/launcher3/views/ArrowTipView.java
index 1f12a2f..89ff821 100644
--- a/src/com/android/launcher3/views/ArrowTipView.java
+++ b/src/com/android/launcher3/views/ArrowTipView.java
@@ -21,6 +21,7 @@
import android.graphics.Paint;
import android.graphics.drawable.ShapeDrawable;
import android.os.Handler;
+import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
@@ -29,6 +30,8 @@
import android.widget.LinearLayout;
import android.widget.TextView;
+import androidx.annotation.Nullable;
+import androidx.annotation.Px;
import androidx.core.content.ContextCompat;
import com.android.launcher3.AbstractFloatingView;
@@ -43,6 +46,7 @@
*/
public class ArrowTipView extends AbstractFloatingView {
+ private static final String TAG = ArrowTipView.class.getSimpleName();
private static final long AUTO_CLOSE_TIMEOUT_MILLIS = 10 * 1000;
private static final long SHOW_DELAY_MS = 200;
private static final long SHOW_DURATION_MS = 300;
@@ -105,7 +109,8 @@
arrowLp.width, arrowLp.height, false));
Paint arrowPaint = arrowDrawable.getPaint();
TypedValue typedValue = new TypedValue();
- context.getTheme().resolveAttribute(android.R.attr.colorAccent, typedValue, true);
+ context.getTheme()
+ .resolveAttribute(android.R.attr.colorAccent, typedValue, true);
arrowPaint.setColor(ContextCompat.getColor(getContext(), typedValue.resourceId));
// The corner path effect won't be reflected in the shadow, but shouldn't be noticeable.
arrowPaint.setPathEffect(new CornerPathEffect(
@@ -165,6 +170,60 @@
}
/**
+ * Show the ArrowTipView (tooltip) custom aligned.
+ *
+ * @param text The text to be shown in the tooltip.
+ * @param arrowXCoord The X coordinate for the arrow on the tip. The arrow is usually in the
+ * center of ArrowTipView unless the ArrowTipView goes beyond screen margin.
+ * @param yCoord The Y coordinate of the bottom of the tooltip.
+ * @return The tool tip view.
+ */
+ @Nullable public ArrowTipView showAtLocation(String text, int arrowXCoord, int yCoord) {
+ ViewGroup parent = mActivity.getDragLayer();
+ @Px int parentViewWidth = parent.getWidth();
+ @Px int textViewWidth = getContext().getResources()
+ .getDimensionPixelSize(R.dimen.widget_picker_education_tip_width);
+ @Px int minViewMargin = getContext().getResources()
+ .getDimensionPixelSize(R.dimen.widget_picker_education_tip_min_margin);
+ if (parentViewWidth < textViewWidth + 2 * minViewMargin) {
+ Log.w(TAG, "Cannot display tip on a small screen of size: " + parentViewWidth);
+ return null;
+ }
+
+ TextView textView = findViewById(R.id.text);
+ textView.setText(text);
+ textView.setWidth(textViewWidth);
+ parent.addView(this);
+ requestLayout();
+
+ post(() -> setY(yCoord - getHeight()));
+ post(() -> {
+ float halfWidth = getWidth() / 2f;
+ float xCoord;
+ if (arrowXCoord - halfWidth < minViewMargin) {
+ xCoord = minViewMargin;
+ } else if (arrowXCoord + halfWidth > parentViewWidth - minViewMargin) {
+ xCoord = parentViewWidth - minViewMargin - getWidth();
+ } else {
+ xCoord = arrowXCoord - halfWidth;
+ }
+ setX(xCoord);
+ findViewById(R.id.arrow).setX(arrowXCoord - xCoord);
+ requestLayout();
+ });
+
+ setAlpha(0);
+ animate()
+ .alpha(1f)
+ .withLayer()
+ .setStartDelay(SHOW_DELAY_MS)
+ .setDuration(SHOW_DURATION_MS)
+ .setInterpolator(Interpolators.DEACCEL)
+ .start();
+ return this;
+ }
+
+ /**
* Register a callback fired when toast is hidden
*/
public ArrowTipView setOnClosedCallback(Runnable runnable) {
diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
index a4257a2..90cd515 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
@@ -41,6 +41,7 @@
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
+import androidx.core.view.ViewCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.android.launcher3.DeviceProfile;
@@ -51,6 +52,7 @@
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.compat.AccessibilityManagerCompat;
import com.android.launcher3.model.WidgetItem;
+import com.android.launcher3.views.ArrowTipView;
import com.android.launcher3.views.RecyclerViewFastScroller;
import com.android.launcher3.views.TopRoundedCornerView;
import com.android.launcher3.widget.BaseWidgetSheet;
@@ -66,6 +68,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
+import java.util.stream.IntStream;
/**
* Popup for showing the full list of available widgets
@@ -78,11 +81,13 @@
private static final long DEFAULT_OPEN_DURATION = 267;
private static final long FADE_IN_DURATION = 150;
+ private static final long EDUCATION_TIP_DELAY_MS = 200;
private static final float VERTICAL_START_POSITION = 0.3f;
// The widget recommendation table can easily take over the entire screen on devices with small
// resolution or landscape on phone. This ratio defines the max percentage of content area that
// the table can display.
private static final float RECOMMENDATION_TABLE_HEIGHT_RATIO = 0.75f;
+ private static final String WIDGETS_EDUCATION_TIP_SEEN = "launcher.widgets_education_tip_seen";
private final Rect mInsets = new Rect();
private final boolean mHasWorkProfile;
@@ -92,6 +97,35 @@
mCurrentUser.equals(entry.mPkgItem.user);
private final Predicate<WidgetsListBaseEntry> mWorkWidgetsFilter =
mPrimaryWidgetsFilter.negate();
+ private final OnLayoutChangeListener mLayoutChangeListenerToShowTips =
+ new OnLayoutChangeListener() {
+ @Override
+ public void onLayoutChange(View v, int left, int top, int right, int bottom,
+ int oldLeft, int oldTop, int oldRight, int oldBottom) {
+ if (hasSeenEducationTip()) {
+ removeOnLayoutChangeListener(this);
+ return;
+ }
+
+ // Widgets are loaded asynchronously, We are adding a delay because we only want
+ // to show the tip when the widget preview has finished loading and rendering in
+ // this view.
+ removeCallbacks(mShowEducationTipTask);
+ postDelayed(mShowEducationTipTask, EDUCATION_TIP_DELAY_MS);
+ }
+ };
+
+ private final Runnable mShowEducationTipTask = () -> {
+ if (hasSeenEducationTip()) {
+ removeOnLayoutChangeListener(mLayoutChangeListenerToShowTips);
+ return;
+ }
+ View viewForTip = getViewToShowEducationTip();
+ if (viewForTip != null && ViewCompat.isLaidOut(viewForTip)) {
+ removeOnLayoutChangeListener(mLayoutChangeListenerToShowTips);
+ showEducationTipOnView(viewForTip);
+ }
+ };
private final int mTabsHeight;
private final int mWidgetCellHorizontalPadding;
@@ -170,6 +204,10 @@
mSearchAndRecommendationViewHolder.mSearchBar.initialize(
mLauncher.getPopupDataProvider(), /* searchModeListener= */ this);
+
+ if (!hasSeenEducationTip()) {
+ addOnLayoutChangeListener(mLayoutChangeListenerToShowTips);
+ }
}
@Override
@@ -392,6 +430,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) {
@@ -563,6 +602,49 @@
mSearchAndRecommendationViewHolder.mSearchBar.clearSearchBarFocus();
}
+ private void showEducationTipOnView(View view) {
+ mLauncher.getSharedPrefs().edit().putBoolean(WIDGETS_EDUCATION_TIP_SEEN, true).apply();
+ int[] coords = new int[2];
+ view.getLocationOnScreen(coords);
+ ArrowTipView arrowTipView = new ArrowTipView(mLauncher);
+ arrowTipView.showAtLocation(
+ getContext().getString(R.string.long_press_widget_to_add),
+ /* arrowXCoord= */coords[0] + view.getWidth() / 2,
+ /* yCoord= */coords[1]);
+ }
+
+ @Nullable private View getViewToShowEducationTip() {
+ if (mSearchAndRecommendationViewHolder.mRecommendedWidgetsTable.getVisibility() == VISIBLE
+ && mSearchAndRecommendationViewHolder.mRecommendedWidgetsTable.getChildCount() > 0
+ ) {
+ return ((ViewGroup) mSearchAndRecommendationViewHolder.mRecommendedWidgetsTable
+ .getChildAt(0)).getChildAt(0);
+ }
+
+ AdapterHolder adapterHolder = mAdapters.get(mIsInSearchMode
+ ? AdapterHolder.SEARCH
+ : mViewPager == null
+ ? AdapterHolder.PRIMARY
+ : mViewPager.getCurrentPage());
+ WidgetsRowViewHolder viewHolderForTip =
+ (WidgetsRowViewHolder) IntStream.range(
+ 0, adapterHolder.mWidgetsListAdapter.getItemCount())
+ .mapToObj(adapterHolder.mWidgetsRecyclerView::
+ findViewHolderForAdapterPosition)
+ .filter(viewHolder -> viewHolder instanceof WidgetsRowViewHolder)
+ .findFirst()
+ .orElse(null);
+ if (viewHolderForTip != null) {
+ return ((ViewGroup) viewHolderForTip.mTableContainer.getChildAt(0)).getChildAt(0);
+ }
+
+ return null;
+ }
+
+ private boolean hasSeenEducationTip() {
+ return mLauncher.getSharedPrefs().getBoolean(WIDGETS_EDUCATION_TIP_SEEN, false);
+ }
+
/** A holder class for holding adapters & their corresponding recycler view. */
private final class AdapterHolder {
static final int PRIMARY = 0;
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/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index d4e8f1f..e7e245f 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -250,7 +250,7 @@
@Before
public void setUp() throws Exception {
- Assert.assertTrue("Keyguard is visible",
+ Assert.assertTrue("Keyguard is visible, which is likely caused by a crash in SysUI",
TestHelpers.wait(
Until.gone(By.res(SYSTEMUI_PACKAGE, "keyguard_status_view")), 60000));
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 475a4ff..cf935f3 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -365,7 +365,7 @@
if (hasSystemUiObject("keyguard_status_view")) return "Phone is locked";
- if (!mDevice.wait(Until.hasObject(By.textStartsWith("")), WAIT_TIME_MS)) {
+ if (!mDevice.wait(Until.hasObject(getAnyObjectSelector()), WAIT_TIME_MS)) {
return "Screen is empty";
}
@@ -388,7 +388,7 @@
}
private String getVisiblePackages() {
- return mDevice.findObjects(By.textStartsWith(""))
+ return mDevice.findObjects(getAnyObjectSelector())
.stream()
.map(LauncherInstrumentation::getApplicationPackageSafe)
.distinct()
@@ -692,6 +692,9 @@
try (LauncherInstrumentation.Closable c = addContextLayer(
"Swiped up from context menu to home")) {
waitUntilLauncherObjectGone(CONTEXT_MENU_RES_ID);
+ // Swiping up can temporarily bring Nexus Launcher if the current
+ // Launcher is a Launcher3 one. Wait for the current launcher to reappear.
+ waitForLauncherObject(getAnyObjectSelector());
}
}
if (hasLauncherObject(WORKSPACE_RES_ID)) {
@@ -736,9 +739,13 @@
}
}
+ private static BySelector getAnyObjectSelector() {
+ return By.textStartsWith("");
+ }
+
boolean isLauncherVisible() {
mDevice.waitForIdle();
- return hasLauncherObject(By.textStartsWith(""));
+ return hasLauncherObject(getAnyObjectSelector());
}
/**