Don't clobber widgets with the same component - DO NOT MERGE

By not storing them in a HashMap keyed against ComponentName (which is
almost guaranteed to conflict with other widgets when managed profiles
are in play).

Bug: 19444068
Change-Id: I6ffce78e8aaf265196239670404cbdaff9fa09be
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index a7e32d3..a8fd79e 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -4371,7 +4371,7 @@
         final Workspace workspace = mWorkspace;
 
         LauncherAppWidgetProviderInfo appWidgetInfo =
-                LauncherModel.getProviderInfo(this, item.providerName);
+                LauncherModel.getProviderInfo(this, item.providerName, item.user);
 
         if (!mIsSafeModeEnabled
                 && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0)
diff --git a/src/com/android/launcher3/LauncherBackupHelper.java b/src/com/android/launcher3/LauncherBackupHelper.java
index 32bea5b..31b434c 100644
--- a/src/com/android/launcher3/LauncherBackupHelper.java
+++ b/src/com/android/launcher3/LauncherBackupHelper.java
@@ -650,7 +650,10 @@
                         if (DEBUG) Log.d(TAG, "saving widget " + backupKey);
                         previewLoader.setPreviewSize(spanX * profile.cellWidthPx,
                                 spanY * profile.cellHeightPx, widgetSpacingLayout);
-                        writeRowToBackup(key, packWidget(dpi, previewLoader, mIconCache, provider), data);
+                        UserHandleCompat user = UserHandleCompat.myUserHandle();
+                        writeRowToBackup(key,
+                                packWidget(dpi, previewLoader, mIconCache, provider, user),
+                                data);
                         mKeys.add(key);
                         backupWidgetCount ++;
                     } else {
@@ -913,9 +916,9 @@
 
     /** Serialize a widget for persistence, including a checksum wrapper. */
     private Widget packWidget(int dpi, WidgetPreviewLoader previewLoader, IconCache iconCache,
-            ComponentName provider) {
+            ComponentName provider, UserHandleCompat user) {
         final LauncherAppWidgetProviderInfo info =
-                LauncherModel.getProviderInfo(mContext, provider);
+                LauncherModel.getProviderInfo(mContext, provider, user);
         Widget widget = new Widget();
         widget.provider = provider.flattenToShortString();
         widget.label = info.label;
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index c39bcee..b194961 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -59,6 +59,7 @@
 import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;
 import com.android.launcher3.compat.UserHandleCompat;
 import com.android.launcher3.compat.UserManagerCompat;
+import com.android.launcher3.util.ComponentKey;
 
 import java.lang.ref.WeakReference;
 import java.net.URISyntaxException;
@@ -174,7 +175,7 @@
     static final ArrayList<Long> sBgWorkspaceScreens = new ArrayList<Long>();
 
     // sBgWidgetProviders is the set of widget providers including custom internal widgets
-    public static HashMap<ComponentName, LauncherAppWidgetProviderInfo> sBgWidgetProviders;
+    public static HashMap<ComponentKey, LauncherAppWidgetProviderInfo> sBgWidgetProviders;
 
     // sPendingPackages is a set of packages which could be on sdcard and are not available yet
     static final HashMap<UserHandleCompat, HashSet<String>> sPendingPackages =
@@ -1958,6 +1959,7 @@
                     LauncherAppWidgetInfo appWidgetInfo;
                     int container;
                     long id;
+                    long serialNumber;
                     Intent intent;
                     UserHandleCompat user;
 
@@ -1972,7 +1974,7 @@
                             case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
                                 id = c.getLong(idIndex);
                                 intentDescription = c.getString(intentIndex);
-                                long serialNumber = c.getInt(profileIdIndex);
+                                serialNumber = c.getInt(profileIdIndex);
                                 user = mUserManager.getUserForSerialNumber(serialNumber);
                                 int promiseType = c.getInt(restoredIndex);
                                 int disabledState = 0;
@@ -2210,6 +2212,7 @@
                                     LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET;
 
                                 int appWidgetId = c.getInt(appWidgetIdIndex);
+                                serialNumber= c.getLong(profileIdIndex);
                                 String savedProvider = c.getString(appWidgetProviderIndex);
                                 id = c.getLong(idIndex);
                                 final ComponentName component =
@@ -2224,7 +2227,8 @@
 
                                 final LauncherAppWidgetProviderInfo provider =
                                         LauncherModel.getProviderInfo(context,
-                                                ComponentName.unflattenFromString(savedProvider));
+                                                ComponentName.unflattenFromString(savedProvider),
+                                                mUserManager.getUserForSerialNumber(serialNumber));
 
                                 final boolean isProviderReady = isValidProvider(provider);
                                 if (!isSafeMode && !customWidget &&
@@ -3344,33 +3348,36 @@
     public static List<LauncherAppWidgetProviderInfo> getWidgetProviders(Context context,
             boolean refresh) {
         synchronized (sBgLock) {
-            if (sBgWidgetProviders != null && !refresh) {
-                return new ArrayList<LauncherAppWidgetProviderInfo>(sBgWidgetProviders.values());
-            }
-            sBgWidgetProviders = new HashMap<ComponentName, LauncherAppWidgetProviderInfo>();
-            List<AppWidgetProviderInfo> widgets =
-                    AppWidgetManagerCompat.getInstance(context).getAllProviders();
-            LauncherAppWidgetProviderInfo info;
-            for (AppWidgetProviderInfo pInfo : widgets) {
-                info = LauncherAppWidgetProviderInfo.fromProviderInfo(context, pInfo);
-                sBgWidgetProviders.put(info.provider, info);
-            }
+            if (sBgWidgetProviders == null || refresh) {
+                sBgWidgetProviders = new HashMap<>();
+                AppWidgetManagerCompat wm = AppWidgetManagerCompat.getInstance(context);
+                LauncherAppWidgetProviderInfo info;
 
-            Collection<CustomAppWidget> customWidgets = Launcher.getCustomAppWidgets().values();
-            for (CustomAppWidget widget : customWidgets) {
-                info = new LauncherAppWidgetProviderInfo(context, widget);
-                sBgWidgetProviders.put(info.provider, info);
+                List<AppWidgetProviderInfo> widgets = wm.getAllProviders();
+                for (AppWidgetProviderInfo pInfo : widgets) {
+                    info = LauncherAppWidgetProviderInfo.fromProviderInfo(context, pInfo);
+                    UserHandleCompat user = wm.getUser(info);
+                    sBgWidgetProviders.put(new ComponentKey(info.provider, user), info);
+                }
+
+                Collection<CustomAppWidget> customWidgets = Launcher.getCustomAppWidgets().values();
+                for (CustomAppWidget widget : customWidgets) {
+                    info = new LauncherAppWidgetProviderInfo(context, widget);
+                    UserHandleCompat user = wm.getUser(info);
+                    sBgWidgetProviders.put(new ComponentKey(info.provider, user), info);
+                }
             }
             return new ArrayList<LauncherAppWidgetProviderInfo>(sBgWidgetProviders.values());
         }
     }
 
-    public static LauncherAppWidgetProviderInfo getProviderInfo(Context ctx, ComponentName name) {
+    public static LauncherAppWidgetProviderInfo getProviderInfo(Context ctx, ComponentName name,
+            UserHandleCompat user) {
         synchronized (sBgLock) {
             if (sBgWidgetProviders == null) {
                 getWidgetProviders(ctx, false /* refresh */);
             }
-            return sBgWidgetProviders.get(name);
+            return sBgWidgetProviders.get(new ComponentKey(name, user));
         }
     }
 
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 6cfb6b2..9521540 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -4974,7 +4974,8 @@
             DeferredWidgetRefresh widgetRefresh = new DeferredWidgetRefresh(changedInfo,
                     mLauncher.getAppWidgetHost());
             if (LauncherModel.getProviderInfo(getContext(),
-                    changedInfo.get(0).providerName) != null) {
+                    changedInfo.get(0).providerName,
+                    changedInfo.get(0).user) != null) {
                 // Re-inflate the widgets which have changed status
                 widgetRefresh.run();
             } else {
diff --git a/src/com/android/launcher3/util/ComponentKey.java b/src/com/android/launcher3/util/ComponentKey.java
new file mode 100644
index 0000000..0f17f00
--- /dev/null
+++ b/src/com/android/launcher3/util/ComponentKey.java
@@ -0,0 +1,51 @@
+package com.android.launcher3.util;
+
+/**
+ * Copyright (C) 2015 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.
+ */
+
+import android.content.ComponentName;
+
+import com.android.launcher3.compat.UserHandleCompat;
+
+import java.util.Arrays;
+
+public class ComponentKey {
+
+    public final ComponentName componentName;
+    public final UserHandleCompat user;
+
+    private final int mHashCode;
+
+    public ComponentKey(ComponentName componentName, UserHandleCompat user) {
+        assert (componentName != null);
+        assert (user != null);
+        this.componentName = componentName;
+        this.user = user;
+        mHashCode = Arrays.hashCode(new Object[] {componentName, user});
+
+    }
+
+    @Override
+    public int hashCode() {
+        return mHashCode;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        ComponentKey other = (ComponentKey) o;
+        return other.componentName.equals(componentName) && other.user.equals(user);
+    }
+}
\ No newline at end of file