diff --git a/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java b/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java index 088277b5ca..c3508b77db 100644 --- a/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java +++ b/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java @@ -22,6 +22,7 @@ import com.android.launcher3.pm.InstallSessionHelper; import com.android.launcher3.util.DaggerSingletonTracker; import com.android.launcher3.util.ScreenOnTracker; import com.android.launcher3.util.SettingsCache; +import com.android.launcher3.widget.custom.CustomWidgetManager; import dagger.BindsInstance; @@ -38,6 +39,7 @@ public interface LauncherBaseAppComponent { InstallSessionHelper getInstallSessionHelper(); ScreenOnTracker getScreenOnTracker(); SettingsCache getSettingsCache(); + CustomWidgetManager getCustomWidgetManager(); /** Builder for LauncherBaseAppComponent. */ interface Builder { diff --git a/src/com/android/launcher3/widget/custom/CustomWidgetManager.java b/src/com/android/launcher3/widget/custom/CustomWidgetManager.java index faa5d12875..0778172127 100644 --- a/src/com/android/launcher3/widget/custom/CustomWidgetManager.java +++ b/src/com/android/launcher3/widget/custom/CustomWidgetManager.java @@ -33,7 +33,12 @@ import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import com.android.launcher3.R; -import com.android.launcher3.util.MainThreadInitializedObject; +import com.android.launcher3.dagger.ApplicationContext; +import com.android.launcher3.dagger.LauncherAppSingleton; +import com.android.launcher3.dagger.LauncherBaseAppComponent; +import com.android.launcher3.util.DaggerSingletonObject; +import com.android.launcher3.util.DaggerSingletonTracker; +import com.android.launcher3.util.ExecutorUtil; import com.android.launcher3.util.PackageUserKey; import com.android.launcher3.util.PluginManagerWrapper; import com.android.launcher3.util.SafeCloseable; @@ -50,13 +55,16 @@ import java.util.Map; import java.util.function.Consumer; import java.util.stream.Stream; +import javax.inject.Inject; + /** * CustomWidgetManager handles custom widgets implemented as a plugin. */ +@LauncherAppSingleton public class CustomWidgetManager implements PluginListener, SafeCloseable { - public static final MainThreadInitializedObject INSTANCE = - new MainThreadInitializedObject<>(CustomWidgetManager::new); + public static final DaggerSingletonObject INSTANCE = + new DaggerSingletonObject<>(LauncherBaseAppComponent::getCustomWidgetManager); private static final String TAG = "CustomWidgetManager"; private static final String PLUGIN_PKG = "android"; @@ -66,34 +74,44 @@ public class CustomWidgetManager implements PluginListener, private Consumer mWidgetRefreshCallback; private final @NonNull AppWidgetManager mAppWidgetManager; - private CustomWidgetManager(Context context) { - this(context, AppWidgetManager.getInstance(context)); + @Inject + CustomWidgetManager(@ApplicationContext Context context, DaggerSingletonTracker tracker) { + this(context, AppWidgetManager.getInstance(context), tracker); } @VisibleForTesting - CustomWidgetManager(Context context, @NonNull AppWidgetManager widgetManager) { + CustomWidgetManager(@ApplicationContext Context context, + @NonNull AppWidgetManager widgetManager, + DaggerSingletonTracker tracker) { mContext = context; mAppWidgetManager = widgetManager; mPlugins = new HashMap<>(); mCustomWidgets = new ArrayList<>(); - PluginManagerWrapper.INSTANCE.get(context) - .addPluginListener(this, CustomWidgetPlugin.class, true); - if (enableSmartspaceAsAWidget()) { - for (String s: context.getResources() - .getStringArray(R.array.custom_widget_providers)) { - try { - Class cls = Class.forName(s); - CustomWidgetPlugin plugin = (CustomWidgetPlugin) - cls.getDeclaredConstructor(Context.class).newInstance(context); - onPluginConnected(plugin, context); - } catch (ClassNotFoundException | InstantiationException | IllegalAccessException - | ClassCastException | NoSuchMethodException - | InvocationTargetException e) { - Log.e(TAG, "Exception found when trying to add custom widgets: " + e); + + ExecutorUtil.executeSyncOnMainOrFail(() -> { + PluginManagerWrapper.INSTANCE.get(context) + .addPluginListener(this, CustomWidgetPlugin.class, true); + + if (enableSmartspaceAsAWidget()) { + for (String s: context.getResources() + .getStringArray(R.array.custom_widget_providers)) { + try { + Class cls = Class.forName(s); + CustomWidgetPlugin plugin = (CustomWidgetPlugin) + cls.getDeclaredConstructor(Context.class).newInstance(context); + onPluginConnected(plugin, context); + } catch (ClassNotFoundException | InstantiationException + | IllegalAccessException + | ClassCastException | NoSuchMethodException + | InvocationTargetException e) { + Log.e(TAG, "Exception found when trying to add custom widgets: " + e); + } } } - } + + tracker.addCloseable(this); + }); } @Override diff --git a/tests/multivalentTests/src/com/android/launcher3/widget/custom/CustomWidgetManagerTest.kt b/tests/multivalentTests/src/com/android/launcher3/widget/custom/CustomWidgetManagerTest.kt index 4b5710d5ac..82f56b8c2e 100644 --- a/tests/multivalentTests/src/com/android/launcher3/widget/custom/CustomWidgetManagerTest.kt +++ b/tests/multivalentTests/src/com/android/launcher3/widget/custom/CustomWidgetManagerTest.kt @@ -23,6 +23,7 @@ import android.platform.test.flag.junit.SetFlagsRule import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation +import com.android.launcher3.util.DaggerSingletonTracker import com.android.launcher3.util.LauncherModelHelper.SandboxModelContext import com.android.launcher3.util.PluginManagerWrapper import com.android.launcher3.util.WidgetUtils @@ -57,12 +58,13 @@ class CustomWidgetManagerTest { @Mock private lateinit var pluginManager: PluginManagerWrapper @Mock private lateinit var mockAppWidgetManager: AppWidgetManager + @Mock private lateinit var tracker: DaggerSingletonTracker @Before fun setUp() { MockitoAnnotations.initMocks(this) context.putObject(PluginManagerWrapper.INSTANCE, pluginManager) - underTest = CustomWidgetManager(context, mockAppWidgetManager) + underTest = CustomWidgetManager(context, mockAppWidgetManager, tracker) } @After