Revert "Change SysemUIFactory to SystemUIInitializer."
Revert submission 18917521-b235624311-app-component
Reason for revert: Broken test b/238359875 and b/238372209
Reverted Changes:
I7029fb296:Change SysemUIFactory to SystemUIInitializer.
I082787983:Conform to new SystemUIInitializer pattern.
I923e5bbbc:Conform to new SystemUIInitializer pattern.
I7af1a39b2:Conform to new SystemUIInitializer pattern.
Iba9a5ba24:Conform to new SystemUIInitializer pattern.
I4fe83e292:Conform to new SystemUIInitializer pattern.
I7f54204ae:Conform to new SystemUIInitializer pattern.
I6246c6eb4:Conform to new SystemUIInitializer pattern.
Bug: 238359875
Bug: 238372209
Change-Id: I833ec524c4f6072d64eba55e22f0b37341d38f4f
diff --git a/packages/SystemUI/proguard.flags b/packages/SystemUI/proguard.flags
index ed01494..6ffd661 100644
--- a/packages/SystemUI/proguard.flags
+++ b/packages/SystemUI/proguard.flags
@@ -9,8 +9,8 @@
-keep class com.android.systemui.statusbar.phone.CentralSurfaces
-keep class com.android.systemui.statusbar.tv.TvStatusBar
-keep class com.android.systemui.car.CarSystemUIFactory
--keep class com.android.systemui.SystemUIInitializer
--keep class com.android.systemui.tv.TvSystemUIInitializer
+-keep class com.android.systemui.SystemUIFactory
+-keep class com.android.systemui.tv.TvSystemUIFactory
-keep class * extends com.android.systemui.CoreStartable
-keep class * implements com.android.systemui.CoreStartable$Injector
diff --git a/packages/SystemUI/res/values-television/config.xml b/packages/SystemUI/res/values-television/config.xml
index 375bd39..94f6c39 100644
--- a/packages/SystemUI/res/values-television/config.xml
+++ b/packages/SystemUI/res/values-television/config.xml
@@ -22,7 +22,7 @@
<resources>
<!-- SystemUIFactory component -->
<string name="config_systemUIFactoryComponent" translatable="false">
- com.android.systemui.tv.TvSystemUIInitializer
+ com.android.systemui.tv.TvSystemUIFactory
</string>
<!-- Svelte specific logic, see RecentsConfiguration.SVELTE_* constants. -->
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 82a3b58..771973c 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -286,7 +286,7 @@
<bool name="config_enableFullscreenUserSwitcher">false</bool>
<!-- SystemUIFactory component -->
- <string name="config_systemUIFactoryComponent" translatable="false">com.android.systemui.SystemUIInitializerImpl</string>
+ <string name="config_systemUIFactoryComponent" translatable="false">com.android.systemui.SystemUIFactory</string>
<!-- QS tile shape store width. negative implies fill configuration instead of stroke-->
<dimen name="config_qsTileStrokeWidthActive">-1dp</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java
index 527ce12..714d267bb 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactory.java
@@ -16,22 +16,160 @@
package com.android.systemui;
+import android.app.Activity;
+import android.app.Application;
+import android.app.Service;
+import android.content.BroadcastReceiver;
+import android.content.ContentProvider;
import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.core.app.AppComponentFactory;
+
+import com.android.systemui.dagger.ContextComponentHelper;
+import com.android.systemui.dagger.SysUIComponent;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import javax.inject.Inject;
/**
- * Starts up SystemUI using the AOSP {@link SystemUIInitializerImpl}.
+ * Implementation of AppComponentFactory that injects into constructors.
*
- * This initializer relies on reflection to start everything up and should be considered deprecated.
- * Instead, create your own {@link SystemUIAppComponentFactoryBase}, specify it in your
- * AndroidManifest.xml and construct your own {@link SystemUIInitializer} directly.
+ * This class sets up dependency injection when creating our application.
*
- * @deprecated Define your own SystemUIAppComponentFactoryBase implementation and use that. This
- * implementation may be changed or removed in future releases.
+ * Services support dependency injection into their constructors.
+ *
+ * ContentProviders support injection into member variables - _not_ constructors.
*/
-@Deprecated
-public class SystemUIAppComponentFactory extends SystemUIAppComponentFactoryBase {
+public class SystemUIAppComponentFactory extends AppComponentFactory {
+
+ private static final String TAG = "AppComponentFactory";
+ @Inject
+ public ContextComponentHelper mComponentHelper;
+
+ public SystemUIAppComponentFactory() {
+ super();
+ }
+
+ @NonNull
@Override
- protected SystemUIInitializer createSystemUIInitializer(Context context) {
- return SystemUIInitializerFactory.createWithContext(context);
+ public Application instantiateApplicationCompat(
+ @NonNull ClassLoader cl, @NonNull String className)
+ throws InstantiationException, IllegalAccessException, ClassNotFoundException {
+ Application app = super.instantiateApplicationCompat(cl, className);
+ if (app instanceof ContextInitializer) {
+ ((ContextInitializer) app).setContextAvailableCallback(
+ context -> {
+ SystemUIFactory.createFromConfig(context);
+ SystemUIFactory.getInstance().getSysUIComponent().inject(
+ SystemUIAppComponentFactory.this);
+ }
+ );
+ }
+
+ return app;
+ }
+
+ @NonNull
+ @Override
+ public ContentProvider instantiateProviderCompat(
+ @NonNull ClassLoader cl, @NonNull String className)
+ throws InstantiationException, IllegalAccessException, ClassNotFoundException {
+
+ ContentProvider contentProvider = super.instantiateProviderCompat(cl, className);
+ if (contentProvider instanceof ContextInitializer) {
+ ((ContextInitializer) contentProvider).setContextAvailableCallback(
+ context -> {
+ SystemUIFactory.createFromConfig(context);
+ SysUIComponent rootComponent =
+ SystemUIFactory.getInstance().getSysUIComponent();
+ try {
+ Method injectMethod = rootComponent.getClass()
+ .getMethod("inject", contentProvider.getClass());
+ injectMethod.invoke(rootComponent, contentProvider);
+ } catch (NoSuchMethodException
+ | IllegalAccessException
+ | InvocationTargetException e) {
+ Log.w(TAG, "No injector for class: " + contentProvider.getClass(), e);
+ }
+ }
+ );
+ }
+
+ return contentProvider;
+ }
+
+ @NonNull
+ @Override
+ public Activity instantiateActivityCompat(@NonNull ClassLoader cl, @NonNull String className,
+ @Nullable Intent intent)
+ throws InstantiationException, IllegalAccessException, ClassNotFoundException {
+ if (mComponentHelper == null) {
+ // This shouldn't happen, but is seen on occasion.
+ // Bug filed against framework to take a look: http://b/141008541
+ SystemUIFactory.getInstance().getSysUIComponent().inject(
+ SystemUIAppComponentFactory.this);
+ }
+ Activity activity = mComponentHelper.resolveActivity(className);
+ if (activity != null) {
+ return activity;
+ }
+ return super.instantiateActivityCompat(cl, className, intent);
+ }
+
+ @NonNull
+ @Override
+ public Service instantiateServiceCompat(
+ @NonNull ClassLoader cl, @NonNull String className, Intent intent)
+ throws InstantiationException, IllegalAccessException, ClassNotFoundException {
+ if (mComponentHelper == null) {
+ // This shouldn't happen, but does when a device is freshly formatted.
+ // Bug filed against framework to take a look: http://b/141008541
+ SystemUIFactory.getInstance().getSysUIComponent().inject(
+ SystemUIAppComponentFactory.this);
+ }
+ Service service = mComponentHelper.resolveService(className);
+ if (service != null) {
+ return service;
+ }
+ return super.instantiateServiceCompat(cl, className, intent);
+ }
+
+ @NonNull
+ @Override
+ public BroadcastReceiver instantiateReceiverCompat(@NonNull ClassLoader cl,
+ @NonNull String className, @Nullable Intent intent)
+ throws InstantiationException, IllegalAccessException, ClassNotFoundException {
+ if (mComponentHelper == null) {
+ // This shouldn't happen, but does when a device is freshly formatted.
+ // Bug filed against framework to take a look: http://b/141008541
+ SystemUIFactory.getInstance().getSysUIComponent().inject(
+ SystemUIAppComponentFactory.this);
+ }
+ BroadcastReceiver receiver = mComponentHelper.resolveBroadcastReceiver(className);
+ if (receiver != null) {
+ return receiver;
+ }
+
+ return super.instantiateReceiverCompat(cl, className, intent);
+ }
+
+ /**
+ * A callback that receives a Context when one is ready.
+ */
+ public interface ContextAvailableCallback {
+ void onContextAvailable(Context context);
+ }
+
+ /**
+ * Implemented in classes that get started by the system before a context is available.
+ */
+ public interface ContextInitializer {
+ void setContextAvailableCallback(ContextAvailableCallback callback);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactoryBase.kt b/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactoryBase.kt
deleted file mode 100644
index 12108b0..0000000
--- a/packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactoryBase.kt
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (C) 2019 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.systemui
-
-import android.app.Activity
-import android.app.Application
-import android.app.Service
-import android.content.BroadcastReceiver
-import android.content.ContentProvider
-import android.content.Context
-import android.content.Intent
-import android.util.Log
-import androidx.core.app.AppComponentFactory
-import com.android.systemui.dagger.ContextComponentHelper
-import java.lang.reflect.InvocationTargetException
-import java.util.concurrent.ExecutionException
-import javax.inject.Inject
-
-/**
- * Implementation of AppComponentFactory that injects into constructors.
- *
- * This class sets up dependency injection when creating our application.
- *
- * Activities, Services, and BroadcastReceivers support dependency injection into
- * their constructors.
- *
- * ContentProviders support injection into member variables - _not_ constructors.
- */
-abstract class SystemUIAppComponentFactoryBase : AppComponentFactory() {
- companion object {
- private const val TAG = "AppComponentFactory"
- // Must be static due to http://b/141008541.
- var systemUIInitializer: SystemUIInitializer? = null
- }
-
- @set:Inject
- lateinit var componentHelper: ContextComponentHelper
-
- /**
- * Returns a new [SystemUIInitializer].
- *
- * The returned implementation should be specific to your build.
- */
- protected abstract fun createSystemUIInitializer(context: Context): SystemUIInitializer
-
- private fun createSystemUIInitializerInternal(context: Context): SystemUIInitializer {
- return systemUIInitializer ?: run {
- val initializer = createSystemUIInitializer(context.applicationContext)
- try {
- initializer.init(false)
- } catch (exception: ExecutionException) {
- throw RuntimeException("Failed to initialize SysUI", exception)
- } catch (exception: InterruptedException) {
- throw RuntimeException("Failed to initialize SysUI", exception)
- }
- initializer.sysUIComponent.inject(
- this@SystemUIAppComponentFactoryBase
- )
-
- systemUIInitializer = initializer
- return initializer
- }
- }
-
- override fun instantiateApplicationCompat(cl: ClassLoader, className: String): Application {
- val app = super.instantiateApplicationCompat(cl, className)
- if (app !is ContextInitializer) {
- throw RuntimeException("App must implement ContextInitializer")
- } else {
- app.setContextAvailableCallback { context ->
- createSystemUIInitializerInternal(context)
- }
- }
-
- return app
- }
-
- override fun instantiateProviderCompat(cl: ClassLoader, className: String): ContentProvider {
- val contentProvider = super.instantiateProviderCompat(cl, className)
- if (contentProvider is ContextInitializer) {
- contentProvider.setContextAvailableCallback { context ->
- val initializer = createSystemUIInitializerInternal(context)
- val rootComponent = initializer.sysUIComponent
- try {
- val injectMethod = rootComponent.javaClass
- .getMethod("inject", contentProvider.javaClass)
- injectMethod.invoke(rootComponent, contentProvider)
- } catch (e: NoSuchMethodException) {
- Log.w(TAG, "No injector for class: " + contentProvider.javaClass, e)
- } catch (e: IllegalAccessException) {
- Log.w(TAG, "No injector for class: " + contentProvider.javaClass, e)
- } catch (e: InvocationTargetException) {
- Log.w(TAG, "No injector for class: " + contentProvider.javaClass, e)
- }
- initializer
- }
- }
- return contentProvider
- }
-
- override fun instantiateActivityCompat(
- cl: ClassLoader,
- className: String,
- intent: Intent?
- ): Activity {
- if (!this::componentHelper.isInitialized) {
- // This shouldn't happen, but is seen on occasion.
- // Bug filed against framework to take a look: http://b/141008541
- systemUIInitializer?.sysUIComponent?.inject(this@SystemUIAppComponentFactoryBase)
- }
- return componentHelper.resolveActivity(className)
- ?: super.instantiateActivityCompat(cl, className, intent)
- }
-
- override fun instantiateServiceCompat(
- cl: ClassLoader,
- className: String,
- intent: Intent?
- ): Service {
- if (!this::componentHelper.isInitialized) {
- // This shouldn't happen, but does when a device is freshly formatted.
- // Bug filed against framework to take a look: http://b/141008541
- systemUIInitializer?.sysUIComponent?.inject(this@SystemUIAppComponentFactoryBase)
- }
- return componentHelper.resolveService(className)
- ?: super.instantiateServiceCompat(cl, className, intent)
- }
-
- override fun instantiateReceiverCompat(
- cl: ClassLoader,
- className: String,
- intent: Intent?
- ): BroadcastReceiver {
- if (!this::componentHelper.isInitialized) {
- // This shouldn't happen, but does when a device is freshly formatted.
- // Bug filed against framework to take a look: http://b/141008541
- systemUIInitializer?.sysUIComponent?.inject(this@SystemUIAppComponentFactoryBase)
- }
- return componentHelper.resolveBroadcastReceiver(className)
- ?: super.instantiateReceiverCompat(cl, className, intent)
- }
-
- /**
- * An Interface for classes that can be notified when an Application Context becomes available.
- *
- * An instance of this will be passed to implementers of [ContextInitializer].
- */
- fun interface ContextAvailableCallback {
- /** Notifies when the Application Context is available. */
- fun onContextAvailable(context: Context): SystemUIInitializer
- }
-
- /**
- * Interface for classes that can be constructed by the system before a context is available.
- *
- * This is intended for [Application] and [ContentProvider] implementations that
- * either may not have a Context until some point after construction or are themselves
- * a [Context].
- *
- * Implementers will be passed a [ContextAvailableCallback] that they should call as soon
- * as an Application Context is ready.
- */
- interface ContextInitializer {
- /**
- * Called to supply the [ContextAvailableCallback] that should be called when an
- * Application [Context] is available.
- */
- fun setContextAvailableCallback(callback: ContextAvailableCallback)
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index 9138b23..6d3fd50 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -42,6 +42,7 @@
import android.view.ThreadedRenderer;
import com.android.internal.protolog.common.ProtoLog;
+import com.android.systemui.dagger.ContextComponentHelper;
import com.android.systemui.dagger.GlobalRootComponent;
import com.android.systemui.dagger.SysUIComponent;
import com.android.systemui.dump.DumpManager;
@@ -64,6 +65,7 @@
public static final String TAG = "SystemUIService";
private static final boolean DEBUG = false;
+ private ContextComponentHelper mComponentHelper;
private BootCompleteCacheImpl mBootCompleteCache;
private DumpManager mDumpManager;
@@ -78,8 +80,8 @@
private CoreStartable[] mServices;
private boolean mServicesStarted;
private SystemUIAppComponentFactory.ContextAvailableCallback mContextAvailableCallback;
+ private GlobalRootComponent mRootComponent;
private SysUIComponent mSysUIComponent;
- private SystemUIInitializer mInitializer;
public SystemUIApplication() {
super();
@@ -88,10 +90,6 @@
ProtoLog.REQUIRE_PROTOLOGTOOL = false;
}
- protected GlobalRootComponent getRootComponent() {
- return mInitializer.getRootComponent();
- }
-
@Override
public void onCreate() {
super.onCreate();
@@ -101,8 +99,10 @@
TimingsTraceLog log = new TimingsTraceLog("SystemUIBootTiming",
Trace.TRACE_TAG_APP);
log.traceBegin("DependencyInjection");
- mInitializer = mContextAvailableCallback.onContextAvailable(this);
- mSysUIComponent = mInitializer.getSysUIComponent();
+ mContextAvailableCallback.onContextAvailable(this);
+ mRootComponent = SystemUIFactory.getInstance().getRootComponent();
+ mSysUIComponent = SystemUIFactory.getInstance().getSysUIComponent();
+ mComponentHelper = mSysUIComponent.getContextComponentHelper();
mBootCompleteCache = mSysUIComponent.provideBootCacheImpl();
log.traceEnd();
@@ -189,14 +189,15 @@
*/
public void startServicesIfNeeded() {
- final String vendorComponent = mInitializer.getVendorComponent(getResources());
+ final String vendorComponent = SystemUIFactory.getInstance()
+ .getVendorComponent(getResources());
// Sort the startables so that we get a deterministic ordering.
// TODO: make #start idempotent and require users of CoreStartable to call it.
Map<Class<?>, Provider<CoreStartable>> sortedStartables = new TreeMap<>(
Comparator.comparing(Class::getName));
- sortedStartables.putAll(mSysUIComponent.getStartables());
- sortedStartables.putAll(mSysUIComponent.getPerUserStartables());
+ sortedStartables.putAll(SystemUIFactory.getInstance().getStartableComponents());
+ sortedStartables.putAll(SystemUIFactory.getInstance().getStartableComponentsPerUser());
startServicesIfNeeded(
sortedStartables, "StartServices", vendorComponent);
}
@@ -211,7 +212,7 @@
// Sort the startables so that we get a deterministic ordering.
Map<Class<?>, Provider<CoreStartable>> sortedStartables = new TreeMap<>(
Comparator.comparing(Class::getName));
- sortedStartables.putAll(mSysUIComponent.getPerUserStartables());
+ sortedStartables.putAll(SystemUIFactory.getInstance().getStartableComponentsPerUser());
startServicesIfNeeded(
sortedStartables, "StartSecondaryServices", null);
}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
similarity index 76%
rename from packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java
rename to packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index 5100c09..ca94b8c 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIInitializer.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2016 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.
@@ -11,7 +11,7 @@
* 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.
+ * limitations under the License
*/
package com.android.systemui;
@@ -22,6 +22,8 @@
import android.os.HandlerThread;
import android.util.Log;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.dagger.DaggerGlobalRootComponent;
import com.android.systemui.dagger.GlobalRootComponent;
import com.android.systemui.dagger.SysUIComponent;
import com.android.systemui.dagger.WMComponent;
@@ -29,47 +31,66 @@
import com.android.wm.shell.dagger.WMShellConcurrencyModule;
import com.android.wm.shell.transition.ShellTransitions;
+import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
+import javax.inject.Provider;
+
/**
- * Initializer that stands up SystemUI.
- *
- * Implementations should override {@link #getGlobalRootComponentBuilder()} to fill in their own
- * Dagger root component.
+ * Class factory to provide customizable SystemUI components.
*/
-public abstract class SystemUIInitializer {
+public class SystemUIFactory {
private static final String TAG = "SystemUIFactory";
- private final Context mContext;
-
+ static SystemUIFactory mFactory;
private GlobalRootComponent mRootComponent;
private WMComponent mWMComponent;
private SysUIComponent mSysUIComponent;
private InitializationChecker mInitializationChecker;
- public SystemUIInitializer(Context context) {
- mContext = context;
+ public static <T extends SystemUIFactory> T getInstance() {
+ return (T) mFactory;
}
- protected abstract GlobalRootComponent.Builder getGlobalRootComponentBuilder();
-
- /**
- * Prepares the SysUIComponent builder before it is built.
- * @param sysUIBuilder the builder provided by the root component's getSysUIComponent() method
- * @param wm the built WMComponent from the root component's getWMComponent() method
- */
- protected SysUIComponent.Builder prepareSysUIComponentBuilder(
- SysUIComponent.Builder sysUIBuilder, WMComponent wm) {
- return sysUIBuilder;
+ public static void createFromConfig(Context context) {
+ createFromConfig(context, false);
}
- /**
- * Starts the initialization process. This stands up the Dagger graph.
- */
- public void init(boolean fromTest) throws ExecutionException, InterruptedException {
+ @VisibleForTesting
+ public static void createFromConfig(Context context, boolean fromTest) {
+ if (mFactory != null) {
+ return;
+ }
+
+ final String clsName = context.getString(R.string.config_systemUIFactoryComponent);
+ if (clsName == null || clsName.length() == 0) {
+ throw new RuntimeException("No SystemUIFactory component configured");
+ }
+
+ try {
+ Class<?> cls = null;
+ cls = context.getClassLoader().loadClass(clsName);
+ mFactory = (SystemUIFactory) cls.newInstance();
+ mFactory.init(context, fromTest);
+ } catch (Throwable t) {
+ Log.w(TAG, "Error creating SystemUIFactory component: " + clsName, t);
+ throw new RuntimeException(t);
+ }
+ }
+
+ @VisibleForTesting
+ static void cleanup() {
+ mFactory = null;
+ }
+
+ public SystemUIFactory() {}
+
+ @VisibleForTesting
+ public void init(Context context, boolean fromTest)
+ throws ExecutionException, InterruptedException {
mRootComponent = getGlobalRootComponentBuilder()
- .context(mContext)
+ .context(context)
.instrumentationTest(fromTest)
.build();
@@ -77,7 +98,7 @@
boolean initializeComponents = mInitializationChecker.initializeComponents();
// Stand up WMComponent
- setupWmComponent(mContext);
+ setupWmComponent(context);
if (initializeComponents) {
// Only initialize when not starting from tests since this currently initializes some
// components that shouldn't be run in the test environment
@@ -167,6 +188,20 @@
}
}
+ /**
+ * Prepares the SysUIComponent builder before it is built.
+ * @param sysUIBuilder the builder provided by the root component's getSysUIComponent() method
+ * @param wm the built WMComponent from the root component's getWMComponent() method
+ */
+ protected SysUIComponent.Builder prepareSysUIComponentBuilder(
+ SysUIComponent.Builder sysUIBuilder, WMComponent wm) {
+ return sysUIBuilder;
+ }
+
+ protected GlobalRootComponent.Builder getGlobalRootComponentBuilder() {
+ return DaggerGlobalRootComponent.builder();
+ }
+
public GlobalRootComponent getRootComponent() {
return mRootComponent;
}
@@ -180,9 +215,23 @@
}
/**
+ * Returns the list of {@link CoreStartable} components that should be started at startup.
+ */
+ public Map<Class<?>, Provider<CoreStartable>> getStartableComponents() {
+ return mSysUIComponent.getStartables();
+ }
+
+ /**
* Returns the list of additional system UI components that should be started.
*/
public String getVendorComponent(Resources resources) {
return resources.getString(R.string.config_systemUIVendorServiceComponent);
}
+
+ /**
+ * Returns the list of {@link CoreStartable} components that should be started per user.
+ */
+ public Map<Class<?>, Provider<CoreStartable>> getStartableComponentsPerUser() {
+ return mSysUIComponent.getPerUserStartables();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIInitializerFactory.kt b/packages/SystemUI/src/com/android/systemui/SystemUIInitializerFactory.kt
deleted file mode 100644
index b9454e8..0000000
--- a/packages/SystemUI/src/com/android/systemui/SystemUIInitializerFactory.kt
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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.systemui
-
-import android.annotation.SuppressLint
-import android.content.Context
-import android.util.Log
-import com.android.internal.annotations.VisibleForTesting
-import com.android.systemui.util.Assert
-
-/**
- * Factory to reflectively lookup a [SystemUIInitializer] to start SystemUI with.
- */
-@Deprecated("Provide your own {@link SystemUIAppComponentFactoryBase} that doesn't need this.")
-object SystemUIInitializerFactory {
- private const val TAG = "SysUIInitializerFactory"
- @SuppressLint("StaticFieldLeak")
- private var initializer: SystemUIInitializer? = null
-
- /**
- * Instantiate a [SystemUIInitializer] reflectively.
- */
- @JvmStatic
- fun createWithContext(context: Context): SystemUIInitializer {
- return createFromConfig(context)
- }
-
- /**
- * Instantiate a [SystemUIInitializer] reflectively.
- */
- @JvmStatic
- private fun createFromConfig(context: Context): SystemUIInitializer {
- Assert.isMainThread()
-
- return createFromConfigNoAssert(context)
- }
-
- @JvmStatic
- @VisibleForTesting
- fun createFromConfigNoAssert(context: Context): SystemUIInitializer {
-
- return initializer ?: run {
- val className = context.getString(R.string.config_systemUIFactoryComponent)
- if (className.isEmpty()) {
- throw RuntimeException("No SystemUIFactory component configured")
- }
- try {
- val cls = context.classLoader.loadClass(className)
- val constructor = cls.getConstructor(Context::class.java)
- (constructor.newInstance(context) as SystemUIInitializer).apply {
- initializer = this
- }
- } catch (t: Throwable) {
- Log.w(TAG, "Error creating SystemUIInitializer component: $className", t)
- throw t
- }
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIInitializerImpl.kt b/packages/SystemUI/src/com/android/systemui/SystemUIInitializerImpl.kt
deleted file mode 100644
index 8920c92..0000000
--- a/packages/SystemUI/src/com/android/systemui/SystemUIInitializerImpl.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.systemui
-
-import android.content.Context
-import com.android.systemui.dagger.DaggerGlobalRootComponent
-import com.android.systemui.dagger.GlobalRootComponent
-
-/**
- * {@link SystemUIInitializer} that stands up AOSP SystemUI.
- */
-class SystemUIInitializerImpl(context: Context) : SystemUIInitializer(context) {
- override fun getGlobalRootComponentBuilder(): GlobalRootComponent.Builder {
- return DaggerGlobalRootComponent.builder()
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
index 550af7c..3a1b129 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
@@ -21,7 +21,7 @@
import com.android.systemui.CoreStartable;
import com.android.systemui.Dependency;
import com.android.systemui.InitController;
-import com.android.systemui.SystemUIAppComponentFactoryBase;
+import com.android.systemui.SystemUIAppComponentFactory;
import com.android.systemui.dagger.qualifiers.PerUser;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.KeyguardSliceProvider;
@@ -241,7 +241,7 @@
/**
* Member injection into the supplied argument.
*/
- void inject(SystemUIAppComponentFactoryBase factory);
+ void inject(SystemUIAppComponentFactory factory);
/**
* Member injection into the supplied argument.
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index 8cc952d..137e288 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -26,6 +26,7 @@
import com.android.keyguard.dagger.KeyguardBouncerComponent;
import com.android.systemui.BootCompleteCache;
import com.android.systemui.BootCompleteCacheImpl;
+import com.android.systemui.SystemUIFactory;
import com.android.systemui.appops.dagger.AppOpsModule;
import com.android.systemui.assist.AssistModule;
import com.android.systemui.biometrics.AlternateUdfpsTouchProvider;
@@ -197,6 +198,11 @@
@Binds
abstract SystemClock bindSystemClock(SystemClockImpl systemClock);
+ @Provides
+ static SystemUIFactory getSystemUIFactory() {
+ return SystemUIFactory.getInstance();
+ }
+
// TODO: This should provided by the WM component
/** Provides Optional of BubbleManager */
@SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java
index f2f1798..1570a7e 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/WMComponent.java
@@ -21,7 +21,7 @@
import androidx.annotation.Nullable;
-import com.android.systemui.SystemUIInitializerFactory;
+import com.android.systemui.SystemUIFactory;
import com.android.systemui.tv.TvWMComponent;
import com.android.wm.shell.ShellCommandHandler;
import com.android.wm.shell.ShellInit;
@@ -52,7 +52,7 @@
/**
* Dagger Subcomponent for WindowManager. This class explicitly describes the interfaces exported
* from the WM component into the SysUI component (in
- * {@link SystemUIInitializerFactory#init(Context, boolean)}), and references the specific dependencies
+ * {@link SystemUIFactory#init(Context, boolean)}), and references the specific dependencies
* provided by its particular device/form-factor SystemUI implementation.
*
* ie. {@link WMComponent} includes {@link WMShellModule}
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleProvider.java b/packages/SystemUI/src/com/android/systemui/people/PeopleProvider.java
index 0ba077e..b55d86e 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleProvider.java
@@ -29,8 +29,7 @@
import android.util.Log;
import android.widget.RemoteViews;
-import com.android.systemui.SystemUIAppComponentFactoryBase.ContextAvailableCallback;
-import com.android.systemui.SystemUIAppComponentFactoryBase.ContextInitializer;
+import com.android.systemui.SystemUIAppComponentFactory;
import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
import com.android.systemui.shared.system.PeopleProviderUtils;
@@ -38,11 +37,11 @@
/** API that returns a People Tile preview. */
public class PeopleProvider extends ContentProvider implements
- ContextInitializer {
+ SystemUIAppComponentFactory.ContextInitializer {
private static final String TAG = "PeopleProvider";
private static final boolean DEBUG = PeopleSpaceUtils.DEBUG;
private static final String EMPTY_STRING = "";
- private ContextAvailableCallback mCallback;
+ private SystemUIAppComponentFactory.ContextAvailableCallback mCallback;
@Inject
PeopleSpaceWidgetManager mPeopleSpaceWidgetManager;
@@ -145,7 +144,7 @@
@Override
public void setContextAvailableCallback(
- ContextAvailableCallback callback) {
+ SystemUIAppComponentFactory.ContextAvailableCallback callback) {
mCallback = callback;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIInitializer.java b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIFactory.java
similarity index 73%
rename from packages/SystemUI/src/com/android/systemui/tv/TvSystemUIInitializer.java
rename to packages/SystemUI/src/com/android/systemui/tv/TvSystemUIFactory.java
index fabbb2c..0b5594b 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIInitializer.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIFactory.java
@@ -16,20 +16,14 @@
package com.android.systemui.tv;
-import android.content.Context;
-
-import com.android.systemui.SystemUIInitializer;
+import com.android.systemui.SystemUIFactory;
import com.android.systemui.dagger.GlobalRootComponent;
/**
- * TV variant {@link SystemUIInitializer}, that substitutes default {@link GlobalRootComponent} for
+ * TV variant {@link SystemUIFactory}, that substitutes default {@link GlobalRootComponent} for
* {@link TvGlobalRootComponent}
*/
-public class TvSystemUIInitializer extends SystemUIInitializer {
- public TvSystemUIInitializer(Context context) {
- super(context);
- }
-
+public class TvSystemUIFactory extends SystemUIFactory {
@Override
protected GlobalRootComponent.Builder getGlobalRootComponentBuilder() {
return DaggerTvGlobalRootComponent.builder();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java b/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java
index a0fdc8f..5d8e435 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java
@@ -26,8 +26,6 @@
import org.junit.Assert;
import org.junit.Test;
-import java.util.concurrent.ExecutionException;
-
@SmallTest
public class DependencyTest extends SysuiTestCase {
@@ -46,12 +44,10 @@
}
@Test
- public void testInitDependency() throws ExecutionException, InterruptedException {
+ public void testInitDependency() {
Dependency.clearDependencies();
- SystemUIInitializer initializer =
- SystemUIInitializerFactory.createFromConfigNoAssert(mContext);
- initializer.init(true);
- Dependency dependency = initializer.getSysUIComponent().createDependency();
+ Dependency dependency =
+ SystemUIFactory.getInstance().getSysUIComponent().createDependency();
dependency.start();
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java
index 9179efc..8c20b24 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java
@@ -34,8 +34,6 @@
import org.junit.Rule;
import org.mockito.Mockito;
-import java.util.concurrent.ExecutionException;
-
public abstract class SysuiBaseFragmentTest extends BaseFragmentTest {
public static final Class<?>[] ALL_SUPPORTED_CLASSES = LeakCheckedTest.ALL_SUPPORTED_CLASSES;
@@ -56,11 +54,10 @@
}
@Before
- public void sysuiSetup() throws ExecutionException, InterruptedException {
- SystemUIInitializer initializer =
- SystemUIInitializerFactory.createFromConfigNoAssert(mContext);
- initializer.init(true);
- mDependency = new TestableDependency(initializer.getSysUIComponent().createDependency());
+ public void SysuiSetup() {
+ SystemUIFactory.createFromConfig(mContext, true);
+ mDependency = new TestableDependency(
+ SystemUIFactory.getInstance().getSysUIComponent().createDependency());
Dependency.setInstance(mDependency);
// TODO: Figure out another way to give reference to a SysuiTestableContext.
@@ -80,6 +77,7 @@
public void SysuiTeardown() {
InstrumentationRegistry.registerInstance(mRealInstrumentation,
InstrumentationRegistry.getArguments());
+ SystemUIFactory.cleanup();
}
@AfterClass
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
index c52ea60f..8c79277 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
@@ -76,10 +76,9 @@
@Before
public void SysuiSetup() throws Exception {
- SystemUIInitializer initializer =
- SystemUIInitializerFactory.createFromConfigNoAssert(mContext);
- initializer.init(true);
- mDependency = new TestableDependency(initializer.getSysUIComponent().createDependency());
+ SystemUIFactory.createFromConfig(mContext, true);
+ mDependency = new TestableDependency(
+ SystemUIFactory.getInstance().getSysUIComponent().createDependency());
Dependency.setInstance(mDependency);
mFakeBroadcastDispatcher = new FakeBroadcastDispatcher(mContext, mock(Looper.class),
mock(Executor.class), mock(DumpManager.class),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
index 23516c9..51c2580 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
@@ -45,7 +45,6 @@
import androidx.test.filters.SmallTest;
import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.systemui.SystemUIInitializerImpl;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationMediaManager;
@@ -101,7 +100,7 @@
MockitoAnnotations.initMocks(this);
mIsZenMode = false;
mProvider = new TestableKeyguardSliceProvider();
- mProvider.setContextAvailableCallback(context -> new SystemUIInitializerImpl(mContext));
+ mProvider.setContextAvailableCallback(context -> { });
mProvider.attachInfo(getContext(), null);
reset(mContentResolver);
SliceProvider.setSpecs(new HashSet<>(Arrays.asList(SliceSpecs.LIST)));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
index 6f9e60f..3d03c47 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
@@ -44,7 +44,6 @@
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.log.LogBuffer;
import com.android.systemui.log.LogcatEchoTracker;
-import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.DisableFlagsLogger;
@@ -113,7 +112,6 @@
@Before
public void setup() {
injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
- mDependency.injectMockDependency(DarkIconDispatcher.class);
}
@Test