1 package com.android.launcher3.util;
2 
3 import static com.android.launcher3.widget.WidgetSections.NO_CATEGORY;
4 
5 import android.os.UserHandle;
6 import android.service.notification.StatusBarNotification;
7 import android.text.TextUtils;
8 
9 import androidx.annotation.NonNull;
10 import androidx.annotation.Nullable;
11 
12 import com.android.launcher3.model.data.ItemInfo;
13 import com.android.launcher3.model.data.PackageItemInfo;
14 
15 import java.util.Objects;
16 
17 /** Creates a hash key based on package name, widget category, and user. */
18 public class PackageUserKey {
19 
20     public String mPackageName;
21     public int mWidgetCategory;
22     public UserHandle mUser;
23     private int mHashCode;
24 
25     @Nullable
fromItemInfo(ItemInfo info)26     public static PackageUserKey fromItemInfo(ItemInfo info) {
27         if (info.getTargetComponent() == null) return null;
28         return new PackageUserKey(info.getTargetComponent().getPackageName(), info.user);
29     }
30 
fromNotification(StatusBarNotification notification)31     public static PackageUserKey fromNotification(StatusBarNotification notification) {
32         return new PackageUserKey(notification.getPackageName(), notification.getUser());
33     }
34 
35     /** Creates a {@link PackageUserKey} from {@link PackageItemInfo}. */
fromPackageItemInfo(PackageItemInfo info)36     public static PackageUserKey fromPackageItemInfo(PackageItemInfo info) {
37         if (TextUtils.isEmpty(info.packageName) && info.widgetCategory != NO_CATEGORY) {
38             return new PackageUserKey(info.widgetCategory, info.user);
39         }
40         return new PackageUserKey(info.packageName, info.user);
41     }
42 
PackageUserKey(String packageName, UserHandle user)43     public PackageUserKey(String packageName, UserHandle user) {
44         update(packageName, user);
45     }
46 
PackageUserKey(int widgetCategory, UserHandle user)47     public PackageUserKey(int widgetCategory, UserHandle user) {
48         update(/* packageName= */ "", widgetCategory, user);
49     }
50 
update(String packageName, UserHandle user)51     public void update(String packageName, UserHandle user) {
52         update(packageName, NO_CATEGORY, user);
53     }
54 
update(String packageName, int widgetCategory, UserHandle user)55     private void update(String packageName, int widgetCategory, UserHandle user) {
56         mPackageName = packageName;
57         mWidgetCategory = widgetCategory;
58         mUser = user;
59         mHashCode = Objects.hash(packageName, widgetCategory, user);
60     }
61 
62     /**
63      * This should only be called to avoid new object creations in a loop.
64      * @return Whether this PackageUserKey was successfully updated - it shouldn't be used if not.
65      */
updateFromItemInfo(ItemInfo info)66     public boolean updateFromItemInfo(ItemInfo info) {
67         if (info.getTargetComponent() == null) return false;
68         if (ShortcutUtil.supportsShortcuts(info)) {
69             update(info.getTargetComponent().getPackageName(), info.user);
70             return true;
71         }
72         return false;
73     }
74 
75     @Override
hashCode()76     public int hashCode() {
77         return mHashCode;
78     }
79 
80     @Override
equals(Object obj)81     public boolean equals(Object obj) {
82         if (!(obj instanceof PackageUserKey)) return false;
83         PackageUserKey otherKey = (PackageUserKey) obj;
84         return Objects.equals(mPackageName, otherKey.mPackageName)
85                 && mWidgetCategory == otherKey.mWidgetCategory
86                 && Objects.equals(mUser, otherKey.mUser);
87     }
88 
89     @NonNull
90     @Override
toString()91     public String toString() {
92         return mPackageName + "#" + mUser + ",category=" + mWidgetCategory;
93     }
94 }
95