Render user's actual workspace in ThemePicker preview (Part 5)

This change takes care of rendering widgets using widget provider's layout info.

Test: manual
Bug: 144052839

Change-Id: I7002d8bf653513cdd317736d550a47f61f0ee474
diff --git a/go/src/com/android/launcher3/model/WidgetsModel.java b/go/src/com/android/launcher3/model/WidgetsModel.java
index 7690b9d..3b3dc01 100644
--- a/go/src/com/android/launcher3/model/WidgetsModel.java
+++ b/go/src/com/android/launcher3/model/WidgetsModel.java
@@ -16,6 +16,7 @@
 
 package com.android.launcher3.model;
 
+import android.content.ComponentName;
 import android.content.Context;
 import android.os.UserHandle;
 
@@ -68,4 +69,9 @@
     public void onPackageIconsUpdated(Set<String> packageNames, UserHandle user,
             LauncherAppState app) {
     }
+
+    public WidgetItem getWidgetProviderInfoByProviderName(
+            ComponentName providerName) {
+        return null;
+    }
 }
\ No newline at end of file
diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
index def76e8..a429af2 100644
--- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
+++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
@@ -25,6 +25,7 @@
 
 import android.annotation.TargetApi;
 import android.app.Fragment;
+import android.appwidget.AppWidgetHostView;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.TypedArray;
@@ -55,6 +56,7 @@
 import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.ItemInfo;
 import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherAppWidgetInfo;
 import com.android.launcher3.LauncherModel;
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.LauncherSettings.Favorites;
@@ -72,6 +74,8 @@
 import com.android.launcher3.model.BgDataModel;
 import com.android.launcher3.model.BgDataModel.Callbacks;
 import com.android.launcher3.model.LoaderResults;
+import com.android.launcher3.model.WidgetItem;
+import com.android.launcher3.model.WidgetsModel;
 import com.android.launcher3.views.ActivityContext;
 import com.android.launcher3.views.BaseDragLayer;
 
@@ -248,6 +252,16 @@
             addInScreenFromBind(folderIcon, info);
         }
 
+        private void inflateAndAddWidgets(LauncherAppWidgetInfo info, WidgetsModel widgetsModel) {
+            WidgetItem widgetItem = widgetsModel.getWidgetProviderInfoByProviderName(
+                    info.providerName);
+            AppWidgetHostView view = new AppWidgetHostView(mContext);
+            view.setAppWidget(-1, widgetItem.widgetInfo);
+            view.updateAppWidget(null);
+            view.setTag(info);
+            addInScreenFromBind(view, info);
+        }
+
         private void dispatchVisibilityAggregated(View view, boolean isVisible) {
             // Similar to View.dispatchVisibilityAggregated implementation.
             final boolean thisVisible = view.getVisibility() == VISIBLE;
@@ -272,9 +286,9 @@
                         mContext).getModel();
                 final WorkspaceItemsInfoFetcher fetcher = new WorkspaceItemsInfoFetcher();
                 launcherModel.enqueueModelUpdateTask(fetcher);
-                ArrayList<ItemInfo> workspaceItems;
+                WorkspaceResult workspaceResult;
                 try {
-                    workspaceItems = fetcher.mTask.get(5, TimeUnit.SECONDS);
+                    workspaceResult = fetcher.mTask.get(5, TimeUnit.SECONDS);
                 } catch (InterruptedException | ExecutionException | TimeoutException e) {
                     Log.d(TAG, "Error fetching workspace items info", e);
                     return;
@@ -284,9 +298,14 @@
                 // items
                 ArrayList<ItemInfo> currentWorkspaceItems = new ArrayList<>();
                 ArrayList<ItemInfo> otherWorkspaceItems = new ArrayList<>();
+                ArrayList<LauncherAppWidgetInfo> currentAppWidgets = new ArrayList<>();
+                ArrayList<LauncherAppWidgetInfo> otherAppWidgets = new ArrayList<>();
 
-                filterCurrentWorkspaceItems(0 /* currentScreenId */, workspaceItems,
-                        currentWorkspaceItems, otherWorkspaceItems);
+                filterCurrentWorkspaceItems(0 /* currentScreenId */,
+                        workspaceResult.mWorkspaceItems, currentWorkspaceItems,
+                        otherWorkspaceItems);
+                filterCurrentWorkspaceItems(0 /* currentScreenId */, workspaceResult.mAppWidgets,
+                        currentAppWidgets, otherAppWidgets);
                 sortWorkspaceItemsSpatially(mIdp, currentWorkspaceItems);
 
                 for (ItemInfo itemInfo : currentWorkspaceItems) {
@@ -303,6 +322,17 @@
                             break;
                     }
                 }
+                for (ItemInfo itemInfo : currentAppWidgets) {
+                    switch (itemInfo.itemType) {
+                        case Favorites.ITEM_TYPE_APPWIDGET:
+                        case Favorites.ITEM_TYPE_CUSTOM_APPWIDGET:
+                            inflateAndAddWidgets((LauncherAppWidgetInfo) itemInfo,
+                                    workspaceResult.mWidgetsModel);
+                            break;
+                        default:
+                            break;
+                    }
+                }
             } else {
                 // Add hotseat icons
                 for (int i = 0; i < mIdp.numHotseatIcons; i++) {
@@ -349,10 +379,10 @@
         }
     }
 
-    private static class WorkspaceItemsInfoFetcher implements Callable<ArrayList<ItemInfo>>,
+    private static class WorkspaceItemsInfoFetcher implements Callable<WorkspaceResult>,
             LauncherModel.ModelUpdateTask {
 
-        private final FutureTask<ArrayList<ItemInfo>> mTask = new FutureTask<>(this);
+        private final FutureTask<WorkspaceResult> mTask = new FutureTask<>(this);
 
         private LauncherAppState mApp;
         private LauncherModel mModel;
@@ -374,14 +404,16 @@
         }
 
         @Override
-        public ArrayList<ItemInfo> call() throws Exception {
+        public WorkspaceResult call() throws Exception {
             if (!mModel.isModelLoaded()) {
                 Log.d(TAG, "Workspace not loaded, loading now");
                 mModel.startLoaderForResults(
                         new LoaderResults(mApp, mBgDataModel, mAllAppsList, new Callbacks[0]));
-                return new ArrayList<>();
+                return null;
             }
-            return mBgDataModel.workspaceItems;
+
+            return new WorkspaceResult(mBgDataModel.workspaceItems, mBgDataModel.appWidgets,
+                    mBgDataModel.widgetsModel);
         }
     }
 
@@ -389,4 +421,17 @@
         view.measure(makeMeasureSpec(width, EXACTLY), makeMeasureSpec(height, EXACTLY));
         view.layout(0, 0, width, height);
     }
+
+    private static class WorkspaceResult {
+        private final ArrayList<ItemInfo> mWorkspaceItems;
+        private final ArrayList<LauncherAppWidgetInfo> mAppWidgets;
+        private final WidgetsModel mWidgetsModel;
+
+        private WorkspaceResult(ArrayList<ItemInfo> workspaceItems,
+                ArrayList<LauncherAppWidgetInfo> appWidgets, WidgetsModel widgetsModel) {
+            mWorkspaceItems = workspaceItems;
+            mAppWidgets = appWidgets;
+            mWidgetsModel = widgetsModel;
+        }
+    }
 }
diff --git a/src/com/android/launcher3/model/PackageItemInfo.java b/src/com/android/launcher3/model/PackageItemInfo.java
index 3ef48cd..2fc064c 100644
--- a/src/com/android/launcher3/model/PackageItemInfo.java
+++ b/src/com/android/launcher3/model/PackageItemInfo.java
@@ -19,6 +19,8 @@
 import com.android.launcher3.ItemInfoWithIcon;
 import com.android.launcher3.LauncherSettings;
 
+import java.util.Objects;
+
 /**
  * Represents a {@link Package} in the widget tray section.
  */
@@ -48,4 +50,17 @@
     public PackageItemInfo clone() {
         return new PackageItemInfo(this);
     }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        PackageItemInfo that = (PackageItemInfo) o;
+        return Objects.equals(packageName, that.packageName);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(packageName);
+    }
 }
diff --git a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
index 5ebf8d3..2c6dce4 100644
--- a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
+++ b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
@@ -6,6 +6,7 @@
 import static com.android.launcher3.pm.ShortcutConfigActivityInfo.queryList;
 
 import android.appwidget.AppWidgetProviderInfo;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.os.Process;
@@ -243,4 +244,16 @@
             }
         }
     }
+
+    public WidgetItem getWidgetProviderInfoByProviderName(
+            ComponentName providerName) {
+        ArrayList<WidgetItem> widgetsList = mWidgetsList.get(
+                new PackageItemInfo(providerName.getPackageName()));
+        for (WidgetItem item : widgetsList) {
+            if (item.componentName.equals(providerName)) {
+                return item;
+            }
+        }
+        return null;
+    }
 }
\ No newline at end of file