diff --git a/res/values/strings.xml b/res/values/strings.xml index 986180c9af..9072907260 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -95,6 +95,9 @@ Work + + Conversations + Search apps diff --git a/src/com/android/launcher3/icons/IconCache.java b/src/com/android/launcher3/icons/IconCache.java index 988794ccb6..a2c0f5cdf4 100644 --- a/src/com/android/launcher3/icons/IconCache.java +++ b/src/com/android/launcher3/icons/IconCache.java @@ -39,6 +39,7 @@ import androidx.annotation.NonNull; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.LauncherFiles; +import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.icons.ComponentWithLabel.ComponentCachingLogic; @@ -304,6 +305,11 @@ public class IconCache extends BaseIconCache { CacheEntry entry = getEntryForPackageLocked( infoInOut.packageName, infoInOut.user, useLowResIcon); applyCacheEntry(entry, infoInOut); + if (infoInOut.category == PackageItemInfo.CONVERSATIONS) { + infoInOut.title = mContext.getString(R.string.widget_category_conversations); + infoInOut.contentDescription = mPackageManager.getUserBadgedLabel( + infoInOut.title, infoInOut.user); + } } protected void applyCacheEntry(CacheEntry entry, ItemInfoWithIcon info) { diff --git a/src/com/android/launcher3/model/data/PackageItemInfo.java b/src/com/android/launcher3/model/data/PackageItemInfo.java index 7617d7efd9..a81fe6a9d1 100644 --- a/src/com/android/launcher3/model/data/PackageItemInfo.java +++ b/src/com/android/launcher3/model/data/PackageItemInfo.java @@ -16,27 +16,47 @@ package com.android.launcher3.model.data; +import androidx.annotation.IntDef; + import com.android.launcher3.LauncherSettings; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.Objects; /** * Represents a {@link Package} in the widget tray section. */ public class PackageItemInfo extends ItemInfoWithIcon { + @Retention(RetentionPolicy.SOURCE) + @IntDef({NO_CATEGORY, CONVERSATIONS}) + public @interface Category{} + /** The package is not categorized in the widget tray. */ + public static final int NO_CATEGORY = 0; + /** The package is categorized to conversations widget in the widget tray. */ + public static final int CONVERSATIONS = 1; /** * Package name of the {@link PackageItemInfo}. */ - public String packageName; + public final String packageName; + + /** Represents a widget category shown in the widget tray section. */ + @Category public final int category; public PackageItemInfo(String packageName) { + this(packageName, NO_CATEGORY); + } + + public PackageItemInfo(String packageName, @Category int category) { this.packageName = packageName; + this.category = category; this.itemType = LauncherSettings.Favorites.ITEM_TYPE_NON_ACTIONABLE; } public PackageItemInfo(PackageItemInfo copy) { this.packageName = copy.packageName; + this.category = copy.category; this.itemType = LauncherSettings.Favorites.ITEM_TYPE_NON_ACTIONABLE; } diff --git a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java index f82f2cc47a..be18e546d2 100644 --- a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java +++ b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java @@ -36,6 +36,7 @@ import com.android.launcher3.widget.model.WidgetsListHeaderEntry; import com.android.launcher3.widget.picker.WidgetsDiffReporter; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -58,6 +59,9 @@ public class WidgetsModel { private static final String TAG = "WidgetsModel"; private static final boolean DEBUG = false; + private static final ComponentName CONVERSATION_WIDGET = ComponentName.createRelative( + "com.android.systemui", ".people.widget.PeopleSpaceWidgetProvider"); + /* Map of widgets and shortcuts that are tracked per package. */ private final Map> mWidgetsList = new HashMap<>(); @@ -156,7 +160,7 @@ public class WidgetsModel { // Temporary list for {@link PackageItemInfos} to avoid having to go through // {@link mPackageItemInfos} to locate the key to be used for {@link #mWidgetsList} - HashMap tmpPackageItemInfos = new HashMap<>(); + HashMap tmpPackageItemInfos = new HashMap<>(); // Clear the lists only if this is an update on all widgets and shortcuts. If packageUser // isn't null, only updates the shortcuts and widgets for the app represented in @@ -168,11 +172,11 @@ public class WidgetsModel { mWidgetsList.putAll(rawWidgetsShortcuts.stream() .filter(new WidgetValidityCheck(app)) .collect(Collectors.groupingBy(item -> { - PackageUserKey packageUserKey = new PackageUserKey( - item.componentName.getPackageName(), item.user); + WidgetPackageOrCategoryKey packageUserKey = getWidgetPackageOrCategoryKey(item); PackageItemInfo pInfo = tmpPackageItemInfos.get(packageUserKey); if (pInfo == null) { - pInfo = new PackageItemInfo(packageUserKey.mPackageName); + pInfo = new PackageItemInfo(item.componentName.getPackageName(), + packageUserKey.mCategory); pInfo.user = item.user; tmpPackageItemInfos.put(packageUserKey, pInfo); } @@ -224,6 +228,13 @@ public class WidgetsModel { return null; } + private WidgetPackageOrCategoryKey getWidgetPackageOrCategoryKey(WidgetItem item) { + if (CONVERSATION_WIDGET.equals(item.componentName)) { + return new WidgetPackageOrCategoryKey(PackageItemInfo.CONVERSATIONS, item.user); + } + return new WidgetPackageOrCategoryKey(item.componentName.getPackageName(), item.user); + } + private static class WidgetValidityCheck implements Predicate { private final InvariantDeviceProfile mIdp; @@ -265,4 +276,40 @@ public class WidgetsModel { return true; } } + + /** A hash key for grouping widgets by package name or category. */ + private static class WidgetPackageOrCategoryKey { + /** + * The package name of the widget provider. + * + *

This shouldn't be empty if {@link #mCategory} has a value, + * {@link PackageItemInfo#NO_CATEGORY}. + */ + public final String mPackage; + /** A widget category. */ + @PackageItemInfo.Category public final int mCategory; + public final UserHandle mUser; + private final int mHashCode; + + WidgetPackageOrCategoryKey(String packageName, UserHandle user) { + this(packageName, PackageItemInfo.NO_CATEGORY, user); + } + + WidgetPackageOrCategoryKey(@PackageItemInfo.Category int category, UserHandle user) { + this("", category, user); + } + + private WidgetPackageOrCategoryKey(String packageName, + @PackageItemInfo.Category int category, UserHandle user) { + mPackage = packageName; + mCategory = category; + mUser = user; + mHashCode = Arrays.hashCode(new Object[]{mPackage, mCategory, mUser}); + } + + @Override + public int hashCode() { + return mHashCode; + } + } } \ No newline at end of file