Add QuickstepWidgetHolder for widget handling

Fix: 235358918
Test: Manual
1. Rebooted the device and verified that widgets are still updating properly
2. Changed the theme from dark to daylight, then from daylight back to dark and verified that widgets are working
3. Kept the device on for several days and verified that widgets are still updating
4. Turn on auto-rotate for the launcher, open any app then exit, verified that widgets will not vanish and reappear
5. Add & remove widgets from the screen, added widgets are still updating

Change-Id: I98ee902f7d16b47bd77626201a4fefc897ba17a0
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 5cce407..04934ac 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -1544,8 +1544,8 @@
     }
 
     protected LauncherWidgetHolder createAppWidgetHolder() {
-        return new LauncherWidgetHolder(this,
-                appWidgetId -> getWorkspace().removeWidget(appWidgetId));
+        return LauncherWidgetHolder.HolderFactory.newFactory(this).newInstance(
+                this, appWidgetId -> getWorkspace().removeWidget(appWidgetId));
     }
 
     public LauncherModel getModel() {
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index d002c2b..1a50ed6 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -1083,7 +1083,7 @@
          */
         @NonNull
         public LauncherWidgetHolder newLauncherWidgetHolder() {
-            return new LauncherWidgetHolder(mContext);
+            return LauncherWidgetHolder.newInstance(mContext);
         }
 
         @Override
diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java
index 5a49f4a..404ea4e 100644
--- a/src/com/android/launcher3/dragndrop/AddItemActivity.java
+++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java
@@ -287,7 +287,7 @@
         mWidgetCell.setRemoteViewsPreview(PinItemDragListener.getPreview(mRequest));
 
         mAppWidgetManager = new WidgetManagerHelper(this);
-        mAppWidgetHolder = new LauncherWidgetHolder(this);
+        mAppWidgetHolder = LauncherWidgetHolder.newInstance(this);
 
         PendingAddWidgetInfo pendingInfo =
                 new PendingAddWidgetInfo(widgetInfo, CONTAINER_PIN_WIDGETS);
diff --git a/src/com/android/launcher3/provider/RestoreDbTask.java b/src/com/android/launcher3/provider/RestoreDbTask.java
index a45e835..5e97b2d 100644
--- a/src/com/android/launcher3/provider/RestoreDbTask.java
+++ b/src/com/android/launcher3/provider/RestoreDbTask.java
@@ -355,7 +355,7 @@
     private void restoreAppWidgetIdsIfExists(Context context) {
         SharedPreferences prefs = LauncherPrefs.getPrefs(context);
         if (prefs.contains(APPWIDGET_OLD_IDS) && prefs.contains(APPWIDGET_IDS)) {
-            LauncherWidgetHolder holder = new LauncherWidgetHolder(context);
+            LauncherWidgetHolder holder = LauncherWidgetHolder.newInstance(context);
             AppWidgetsRestoredReceiver.restoreAppWidgetIds(context,
                     IntArray.fromConcatString(prefs.getString(APPWIDGET_OLD_IDS, "")).toArray(),
                     IntArray.fromConcatString(prefs.getString(APPWIDGET_IDS, "")).toArray(),
diff --git a/src/com/android/launcher3/widget/LauncherWidgetHolder.java b/src/com/android/launcher3/widget/LauncherWidgetHolder.java
index 5497729..d7235ad 100644
--- a/src/com/android/launcher3/widget/LauncherWidgetHolder.java
+++ b/src/com/android/launcher3/widget/LauncherWidgetHolder.java
@@ -19,7 +19,6 @@
 
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
 
-import android.app.PendingIntent;
 import android.appwidget.AppWidgetHost;
 import android.appwidget.AppWidgetHostView;
 import android.appwidget.AppWidgetManager;
@@ -29,7 +28,6 @@
 import android.content.Intent;
 import android.os.Bundle;
 import android.util.SparseArray;
-import android.view.View;
 import android.widget.RemoteViews;
 import android.widget.Toast;
 
@@ -45,7 +43,7 @@
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.testing.TestLogging;
 import com.android.launcher3.testing.shared.TestProtocol;
-import com.android.launcher3.uioverrides.ApiWrapper;
+import com.android.launcher3.util.ResourceBasedOverride;
 import com.android.launcher3.widget.custom.CustomWidgetManager;
 
 import java.util.function.IntConsumer;
@@ -86,11 +84,7 @@
     // TODO(b/191735836): Replace with SplashScreen.SPLASH_SCREEN_STYLE_EMPTY when un-hidden
     private static final int SPLASH_SCREEN_STYLE_EMPTY = 0;
 
-    public LauncherWidgetHolder(@NonNull Context context) {
-        this(context, null);
-    }
-
-    public LauncherWidgetHolder(@NonNull Context context,
+    protected LauncherWidgetHolder(@NonNull Context context,
             @Nullable IntConsumer appWidgetRemovedCallback) {
         mContext = context;
         mWidgetHost = createHost(context, appWidgetRemovedCallback);
@@ -321,15 +315,6 @@
     }
 
     /**
-     * Set the interaction handler for the widget host
-     * @param handler The interaction handler
-     */
-    public void setInteractionHandler(
-            @Nullable LauncherWidgetInteractionHandler handler) {
-        ApiWrapper.setHostInteractionHandler(mWidgetHost, handler);
-    }
-
-    /**
      * Delete the host
      */
     public void deleteHost() {
@@ -489,20 +474,35 @@
     }
 
     /**
-     * Set as a substitution for the hidden interaction handler in RemoteViews
+     * Returns the new LauncherWidgetHolder instance
      */
-    public interface LauncherWidgetInteractionHandler {
+    public static LauncherWidgetHolder newInstance(Context context) {
+        return HolderFactory.newFactory(context).newInstance(context, null);
+    }
+
+    /**
+     * A factory class that generates new instances of {@code LauncherWidgetHolder}
+     */
+    public static class HolderFactory implements ResourceBasedOverride {
+
         /**
-         * Invoked when the user performs an interaction on the View.
-         *
-         * @param view the View with which the user interacted
-         * @param pendingIntent the base PendingIntent associated with the view
-         * @param response the response to the interaction, which knows how to fill in the
-         *                 attached PendingIntent
+         * @param context The context of the caller
+         * @param appWidgetRemovedCallback The callback that is called when widgets are removed
+         * @return A new instance of {@code LauncherWidgetHolder}
          */
-        boolean onInteraction(
-                View view,
-                PendingIntent pendingIntent,
-                RemoteViews.RemoteResponse response);
+        public LauncherWidgetHolder newInstance(@NonNull Context context,
+                @Nullable IntConsumer appWidgetRemovedCallback) {
+            return new LauncherWidgetHolder(context, appWidgetRemovedCallback);
+        }
+
+        /**
+         * @param context The context of the caller
+         * @return A new instance of factory class for widget holders. If not specified, returning
+         * {@code HolderFactory} by default.
+         */
+        public static HolderFactory newFactory(Context context) {
+            return Overrides.getObject(
+                    HolderFactory.class, context, R.string.widget_holder_factory_class);
+        }
     }
 }