Merge "Add QuickstepWidgetHolder for widget handling" into tm-qpr-dev
diff --git a/quickstep/res/values/config.xml b/quickstep/res/values/config.xml
index 198a676..a91507c 100644
--- a/quickstep/res/values/config.xml
+++ b/quickstep/res/values/config.xml
@@ -25,6 +25,7 @@
<string name="stats_log_manager_class" translatable="false">com.android.quickstep.logging.StatsLogCompatManager</string>
<string name="test_information_handler_class" translatable="false">com.android.quickstep.QuickstepTestInformationHandler</string>
<string name="window_manager_proxy_class" translatable="false">com.android.quickstep.util.SystemWindowManagerProxy</string>
+ <string name="widget_holder_factory_class" translatable="false">com.android.launcher3.uioverrides.QuickstepWidgetHolder$QuickstepHolderFactory</string>
<!-- The number of thumbnails and icons to keep in the cache. The thumbnail cache size also
determines how many thumbnails will be fetched in the background. -->
diff --git a/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java b/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java
index 379a6cd..ca7ce74 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java
@@ -17,14 +17,9 @@
package com.android.launcher3.uioverrides;
import android.app.Person;
-import android.appwidget.AppWidgetHost;
import android.content.pm.ShortcutInfo;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
import com.android.launcher3.Utilities;
-import com.android.launcher3.widget.LauncherWidgetHolder;
/**
* A wrapper for the hidden API calls
@@ -37,14 +32,4 @@
Person[] persons = si.getPersons();
return persons == null ? Utilities.EMPTY_PERSON_ARRAY : persons;
}
-
- /**
- * Set the interaction handler for the host
- * @param host AppWidgetHost that needs the interaction handler
- * @param handler InteractionHandler for the views in the host
- */
- public static void setHostInteractionHandler(@NonNull AppWidgetHost host,
- @Nullable LauncherWidgetHolder.LauncherWidgetInteractionHandler handler) {
- host.setInteractionHandler(handler::onInteraction);
- }
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepAppWidgetHost.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepAppWidgetHost.java
new file mode 100644
index 0000000..6659fa0
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepAppWidgetHost.java
@@ -0,0 +1,70 @@
+/**
+ * Copyright (C) 2022 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.
+ */
+package com.android.launcher3.uioverrides;
+
+import static com.android.launcher3.widget.LauncherWidgetHolder.APPWIDGET_HOST_ID;
+
+import android.appwidget.AppWidgetHost;
+import android.appwidget.AppWidgetProviderInfo;
+import android.content.Context;
+import android.os.Looper;
+
+import androidx.annotation.NonNull;
+
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
+import com.android.launcher3.widget.LauncherWidgetHolder;
+
+import java.util.function.IntConsumer;
+
+/**
+ * {@link AppWidgetHost} that is used to receive the changes to the widgets without
+ * storing any {@code Activity} info like that of the launcher.
+ */
+final class QuickstepAppWidgetHost extends AppWidgetHost {
+ private final @NonNull Context mContext;
+ private final @NonNull IntConsumer mAppWidgetRemovedCallback;
+ private final @NonNull LauncherWidgetHolder.ProviderChangedListener mProvidersChangedListener;
+
+ QuickstepAppWidgetHost(@NonNull Context context, @NonNull IntConsumer appWidgetRemovedCallback,
+ @NonNull LauncherWidgetHolder.ProviderChangedListener listener,
+ @NonNull Looper looper) {
+ super(context, APPWIDGET_HOST_ID, null, looper);
+ mContext = context;
+ mAppWidgetRemovedCallback = appWidgetRemovedCallback;
+ mProvidersChangedListener = listener;
+ }
+
+ @Override
+ protected void onProvidersChanged() {
+ mProvidersChangedListener.notifyWidgetProvidersChanged();
+ }
+
+ @Override
+ public void onAppWidgetRemoved(int appWidgetId) {
+ mAppWidgetRemovedCallback.accept(appWidgetId);
+ }
+
+ @Override
+ protected void onProviderChanged(int appWidgetId, @NonNull AppWidgetProviderInfo appWidget) {
+ LauncherAppWidgetProviderInfo info = LauncherAppWidgetProviderInfo.fromProviderInfo(
+ mContext, appWidget);
+ super.onProviderChanged(appWidgetId, info);
+ // The super method updates the dimensions of the providerInfo. Update the
+ // launcher spans accordingly.
+ info.initSpans(mContext, LauncherAppState.getIDP(mContext));
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
index 353d817..08d147f 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
@@ -34,11 +34,9 @@
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.util.ActivityOptionsWrapper;
import com.android.launcher3.widget.LauncherAppWidgetHostView;
-import com.android.launcher3.widget.LauncherWidgetHolder;
/** Provides a Quickstep specific animation when launching an activity from an app widget. */
-class QuickstepInteractionHandler
- implements LauncherWidgetHolder.LauncherWidgetInteractionHandler {
+class QuickstepInteractionHandler implements RemoteViews.InteractionHandler {
private static final String TAG = "QuickstepInteractionHandler";
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 13d0be5..a07e4d7 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -96,7 +96,6 @@
import com.android.launcher3.model.BgDataModel.FixedContainerItems;
import com.android.launcher3.model.WellbeingModel;
import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.popup.SystemShortcut;
import com.android.launcher3.proxy.ProxyActivityStarter;
import com.android.launcher3.proxy.StartActivityParams;
@@ -106,6 +105,7 @@
import com.android.launcher3.statemanager.StateManager.StateHandler;
import com.android.launcher3.taskbar.LauncherTaskbarUIController;
import com.android.launcher3.taskbar.TaskbarManager;
+import com.android.launcher3.uioverrides.QuickstepWidgetHolder.QuickstepHolderFactory;
import com.android.launcher3.uioverrides.states.QuickstepAtomicAnimationFactory;
import com.android.launcher3.uioverrides.touchcontrollers.NavBarToHomeTouchController;
import com.android.launcher3.uioverrides.touchcontrollers.NoButtonNavbarToOverviewTouchController;
@@ -517,9 +517,11 @@
@Override
protected LauncherWidgetHolder createAppWidgetHolder() {
- LauncherWidgetHolder appWidgetHolder = super.createAppWidgetHolder();
- appWidgetHolder.setInteractionHandler(new QuickstepInteractionHandler(this));
- return appWidgetHolder;
+ final QuickstepHolderFactory factory =
+ (QuickstepHolderFactory) LauncherWidgetHolder.HolderFactory.newFactory(this);
+ return factory.newInstance(this,
+ appWidgetId -> getWorkspace().removeWidget(appWidgetId),
+ new QuickstepInteractionHandler(this));
}
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepWidgetHolder.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepWidgetHolder.java
new file mode 100644
index 0000000..a8edd51
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepWidgetHolder.java
@@ -0,0 +1,270 @@
+/**
+ * Copyright (C) 2022 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.
+ */
+package com.android.launcher3.uioverrides;
+
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+
+import android.appwidget.AppWidgetHost;
+import android.appwidget.AppWidgetHostView;
+import android.appwidget.AppWidgetProviderInfo;
+import android.content.Context;
+import android.util.SparseArray;
+import android.widget.RemoteViews;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.UiThread;
+import androidx.annotation.WorkerThread;
+
+import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.model.WidgetsModel;
+import com.android.launcher3.util.Thunk;
+import com.android.launcher3.widget.LauncherAppWidgetHostView;
+import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
+import com.android.launcher3.widget.LauncherWidgetHolder;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.WeakHashMap;
+import java.util.function.Consumer;
+import java.util.function.IntConsumer;
+
+/**
+ * {@link LauncherWidgetHolder} that puts the app widget host in the background
+ */
+public final class QuickstepWidgetHolder extends LauncherWidgetHolder {
+ private static final List<QuickstepWidgetHolder> sHolders = new ArrayList<>();
+ private static final SparseArray<QuickstepWidgetHolderListener> sListeners =
+ new SparseArray<>();
+
+ private static AppWidgetHost sWidgetHost = null;
+
+ private final @Nullable RemoteViews.InteractionHandler mInteractionHandler;
+
+ private final @NonNull IntConsumer mAppWidgetRemovedCallback;
+
+ private final ArrayList<ProviderChangedListener> mProviderChangedListeners = new ArrayList<>();
+
+ @Thunk
+ QuickstepWidgetHolder(@NonNull Context context,
+ @Nullable IntConsumer appWidgetRemovedCallback,
+ @Nullable RemoteViews.InteractionHandler interactionHandler) {
+ super(context, appWidgetRemovedCallback);
+ mAppWidgetRemovedCallback = appWidgetRemovedCallback != null ? appWidgetRemovedCallback
+ : i -> {};
+ mInteractionHandler = interactionHandler;
+ sHolders.add(this);
+ }
+
+ @Override
+ @NonNull
+ protected AppWidgetHost createHost(@NonNull Context context,
+ @Nullable IntConsumer appWidgetRemovedCallback) {
+ if (sWidgetHost == null) {
+ sWidgetHost = new QuickstepAppWidgetHost(context.getApplicationContext(),
+ i -> MAIN_EXECUTOR.execute(() ->
+ sHolders.forEach(h -> h.mAppWidgetRemovedCallback.accept(i))),
+ () -> MAIN_EXECUTOR.execute(() ->
+ sHolders.forEach(h -> h.mProviderChangedListeners.forEach(
+ ProviderChangedListener::notifyWidgetProvidersChanged))),
+ UI_HELPER_EXECUTOR.getLooper());
+ if (!WidgetsModel.GO_DISABLE_WIDGETS) {
+ sWidgetHost.startListening();
+ }
+ }
+ return sWidgetHost;
+ }
+
+ /**
+ * Delete the specified app widget from the host
+ * @param appWidgetId The ID of the app widget to be deleted
+ */
+ @Override
+ public void deleteAppWidgetId(int appWidgetId) {
+ super.deleteAppWidgetId(appWidgetId);
+ sListeners.remove(appWidgetId);
+ }
+
+ /**
+ * Called when the launcher is destroyed
+ */
+ @Override
+ public void destroy() {
+ sHolders.remove(this);
+ }
+
+ /**
+ * Add a listener that is triggered when the providers of the widgets are changed
+ * @param listener The listener that notifies when the providers changed
+ */
+ @Override
+ public void addProviderChangeListener(
+ @NonNull LauncherWidgetHolder.ProviderChangedListener listener) {
+ mProviderChangedListeners.add(listener);
+ }
+
+ /**
+ * Remove the specified listener from the host
+ * @param listener The listener that is to be removed from the host
+ */
+ @Override
+ public void removeProviderChangeListener(
+ LauncherWidgetHolder.ProviderChangedListener listener) {
+ mProviderChangedListeners.remove(listener);
+ }
+
+ /**
+ * Stop the host from updating the widget views
+ */
+ @Override
+ public void stopListening() {
+ if (WidgetsModel.GO_DISABLE_WIDGETS) {
+ return;
+ }
+
+ sWidgetHost.setAppWidgetHidden();
+ setListeningFlag(false);
+ }
+
+ /**
+ * Create a view for the specified app widget
+ * @param context The activity context for which the view is created
+ * @param appWidgetId The ID of the widget
+ * @param appWidget The {@link LauncherAppWidgetProviderInfo} of the widget
+ * @return A view for the widget
+ */
+ @NonNull
+ @Override
+ public LauncherAppWidgetHostView createView(@NonNull Context context, int appWidgetId,
+ @NonNull LauncherAppWidgetProviderInfo appWidget) {
+ LauncherAppWidgetHostView widgetView = getPendingView(appWidgetId);
+ if (widgetView != null) {
+ removePendingView(appWidgetId);
+ } else {
+ widgetView = new LauncherAppWidgetHostView(context);
+ }
+ widgetView.setInteractionHandler(mInteractionHandler);
+ widgetView.setAppWidget(appWidgetId, appWidget);
+
+ QuickstepWidgetHolderListener listener = sListeners.get(appWidgetId);
+ if (listener == null) {
+ listener = new QuickstepWidgetHolderListener(this, widgetView);
+ sWidgetHost.setListener(appWidgetId, listener);
+ sListeners.put(appWidgetId, listener);
+ } else {
+ listener.resetView(this, widgetView);
+ }
+
+ return widgetView;
+ }
+
+ /**
+ * Clears all the views from the host
+ */
+ @Override
+ public void clearViews() {
+ for (int i = sListeners.size() - 1; i >= 0; i--) {
+ sListeners.valueAt(i).mView.remove(this);
+ }
+ }
+
+ private static class QuickstepWidgetHolderListener
+ implements AppWidgetHost.AppWidgetHostListener {
+ @NonNull
+ private final Map<QuickstepWidgetHolder, AppWidgetHostView> mView = new WeakHashMap<>();
+
+ @Nullable
+ private RemoteViews mRemoteViews = null;
+
+ QuickstepWidgetHolderListener(@NonNull QuickstepWidgetHolder holder,
+ @NonNull LauncherAppWidgetHostView view) {
+ mView.put(holder, view);
+ }
+
+ @UiThread
+ public void resetView(@NonNull QuickstepWidgetHolder holder,
+ @NonNull AppWidgetHostView view) {
+ mView.put(holder, view);
+ view.updateAppWidget(mRemoteViews);
+ }
+
+ @Override
+ @WorkerThread
+ public void onUpdateProviderInfo(@Nullable AppWidgetProviderInfo info) {
+ mRemoteViews = null;
+ executeOnMainExecutor(v -> v.onUpdateProviderInfo(info));
+ }
+
+ @Override
+ @WorkerThread
+ public void updateAppWidget(@Nullable RemoteViews views) {
+ mRemoteViews = views;
+ executeOnMainExecutor(v -> v.updateAppWidget(mRemoteViews));
+ }
+
+ @Override
+ @WorkerThread
+ public void onViewDataChanged(int viewId) {
+ executeOnMainExecutor(v -> v.onViewDataChanged(viewId));
+ }
+
+ private void executeOnMainExecutor(Consumer<AppWidgetHostView> consumer) {
+ MAIN_EXECUTOR.execute(() -> mView.values().forEach(consumer));
+ }
+ }
+
+ /**
+ * {@code HolderFactory} subclass that takes an interaction handler as one of the parameters
+ * when creating a new instance.
+ */
+ public static class QuickstepHolderFactory extends HolderFactory {
+
+ @SuppressWarnings("unused")
+ public QuickstepHolderFactory(Context context) { }
+
+ @Override
+ public LauncherWidgetHolder newInstance(@NonNull Context context,
+ @Nullable IntConsumer appWidgetRemovedCallback) {
+ return newInstance(context, appWidgetRemovedCallback, null);
+ }
+
+ /**
+ * @param context The context of the caller
+ * @param appWidgetRemovedCallback The callback that is called when widgets are removed
+ * @param interactionHandler The interaction handler when the widgets are clicked
+ * @return A new {@link LauncherWidgetHolder} instance
+ */
+ public LauncherWidgetHolder newInstance(@NonNull Context context,
+ @Nullable IntConsumer appWidgetRemovedCallback,
+ @Nullable RemoteViews.InteractionHandler interactionHandler) {
+
+ if (!FeatureFlags.ENABLE_WIDGET_HOST_IN_BACKGROUND.get()) {
+ return new LauncherWidgetHolder(context, appWidgetRemovedCallback) {
+ @Override
+ protected AppWidgetHost createHost(Context context,
+ @Nullable IntConsumer appWidgetRemovedCallback) {
+ AppWidgetHost host = super.createHost(context, appWidgetRemovedCallback);
+ host.setInteractionHandler(interactionHandler);
+ return host;
+ }
+ };
+ }
+ return new QuickstepWidgetHolder(context, appWidgetRemovedCallback, interactionHandler);
+ }
+ }
+}
diff --git a/res/values/config.xml b/res/values/config.xml
index 4cab2de..016420b 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -83,6 +83,7 @@
<string name="model_delegate_class" translatable="false"></string>
<string name="window_manager_proxy_class" translatable="false"></string>
<string name="secondary_display_predictions_class" translatable="false"></string>
+ <string name="widget_holder_factory_class" translatable="false"></string>
<!-- View ID to use for QSB widget -->
<item type="id" name="qsb_widget" />
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 18ed0fc..43772e4 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -1548,8 +1548,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 f4c0501..767c3d9 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -1093,7 +1093,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 a610548..4906c1d 100644
--- a/src/com/android/launcher3/dragndrop/AddItemActivity.java
+++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java
@@ -295,7 +295,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);
+ }
}
}
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java b/src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java
index 02f4ece..47bf135 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java
@@ -17,14 +17,9 @@
package com.android.launcher3.uioverrides;
import android.app.Person;
-import android.appwidget.AppWidgetHost;
import android.content.pm.ShortcutInfo;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
import com.android.launcher3.Utilities;
-import com.android.launcher3.widget.LauncherWidgetHolder;
/**
* A wrapper for the hidden API calls
@@ -36,14 +31,4 @@
public static Person[] getPersons(ShortcutInfo si) {
return Utilities.EMPTY_PERSON_ARRAY;
}
-
- /**
- * Set the interaction handler for the host
- * @param host AppWidgetHost that needs the interaction handler
- * @param handler InteractionHandler for the views in the host
- */
- public static void setHostInteractionHandler(@NonNull AppWidgetHost host,
- @Nullable LauncherWidgetHolder.LauncherWidgetInteractionHandler handler) {
- // No-op
- }
}
diff --git a/tests/src/com/android/launcher3/util/WidgetUtils.java b/tests/src/com/android/launcher3/util/WidgetUtils.java
index e514142..b0df055 100644
--- a/tests/src/com/android/launcher3/util/WidgetUtils.java
+++ b/tests/src/com/android/launcher3/util/WidgetUtils.java
@@ -70,7 +70,7 @@
pendingInfo.minSpanY = item.minSpanY;
Bundle options = pendingInfo.getDefaultSizeOptions(targetContext);
- LauncherWidgetHolder holder = new LauncherWidgetHolder(targetContext);
+ LauncherWidgetHolder holder = LauncherWidgetHolder.newInstance(targetContext);
try {
int widgetId = holder.allocateAppWidgetId();
if (!new WidgetManagerHelper(targetContext)