diff options
9 files changed, 73 insertions, 30 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/CoreStartable.java b/packages/SystemUI/src/com/android/systemui/CoreStartable.java index 39e1c4150167..55ccaa68c855 100644 --- a/packages/SystemUI/src/com/android/systemui/CoreStartable.java +++ b/packages/SystemUI/src/com/android/systemui/CoreStartable.java @@ -33,12 +33,23 @@ import java.io.PrintWriter; * abstract fun bind(impl: FoobarStartable): CoreStartable * </pre> * - * If your CoreStartable depends on different CoreStartables starting before it, use a - * {@link com.android.systemui.startable.Dependencies} annotation to list out those dependencies. + * If your CoreStartable depends on different CoreStartables starting before it, you can specify + * another map binding listing out its dependencies: + * <pre> + * @Provides + * @IntoMap + * @Dependencies // Important! com.android.systemui.startable.Dependencies. + * @ClassKey(FoobarStartable::class) + * fun providesDeps(): Set<Class<out CoreStartable>> { + * return setOf(OtherStartable::class.java) + * } + * </pre> + * * * @see SystemUIApplication#startSystemUserServicesIfNeeded() */ public interface CoreStartable extends Dumpable { + String STARTABLE_DEPENDENCIES = "startable_dependencies"; /** Main entry point for implementations. Called shortly after SysUI startup. */ void start(); diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java index ba869bd56f31..08d45fae5ddd 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java @@ -44,16 +44,15 @@ import com.android.systemui.dagger.SysUIComponent; import com.android.systemui.dump.DumpManager; import com.android.systemui.process.ProcessWrapper; import com.android.systemui.res.R; -import com.android.systemui.startable.Dependencies; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.util.NotificationChannels; import java.lang.reflect.InvocationTargetException; import java.util.ArrayDeque; -import java.util.Arrays; import java.util.Comparator; import java.util.HashSet; import java.util.Map; +import java.util.Set; import java.util.StringJoiner; import java.util.TreeMap; @@ -307,9 +306,9 @@ public class SystemUIApplication extends Application implements Map.Entry<Class<?>, Provider<CoreStartable>> entry = queue.removeFirst(); Class<?> cls = entry.getKey(); - Dependencies dep = cls.getAnnotation(Dependencies.class); - Class<?>[] deps = (dep == null ? null : dep.value()); - if (deps == null || startedStartables.containsAll(Arrays.asList(deps))) { + Set<Class<? extends CoreStartable>> deps = + mSysUIComponent.getStartableDependencies().get(cls); + if (deps == null || startedStartables.containsAll(deps)) { String clsName = cls.getName(); int i = serviceIndex; // Copied to make lambda happy. timeInitialization( @@ -331,12 +330,12 @@ public class SystemUIApplication extends Application implements while (!nextQueue.isEmpty()) { Map.Entry<Class<?>, Provider<CoreStartable>> entry = nextQueue.removeFirst(); Class<?> cls = entry.getKey(); - Dependencies dep = cls.getAnnotation(Dependencies.class); - Class<?>[] deps = (dep == null ? null : dep.value()); + Set<Class<? extends CoreStartable>> deps = + mSysUIComponent.getStartableDependencies().get(cls); StringJoiner stringJoiner = new StringJoiner(", "); - for (int i = 0; deps != null && i < deps.length; i++) { - if (!startedStartables.contains(deps[i])) { - stringJoiner.add(deps[i].getName()); + for (Class<? extends CoreStartable> c : deps) { + if (!startedStartables.contains(c)) { + stringJoiner.add(c.getName()); } } Log.e(TAG, "Failed to start " + cls.getName() diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java index e104166935c1..871ef1e9edf1 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java @@ -25,6 +25,7 @@ import com.android.systemui.dagger.qualifiers.PerUser; import com.android.systemui.dump.DumpManager; import com.android.systemui.keyguard.KeyguardSliceProvider; import com.android.systemui.people.PeopleProvider; +import com.android.systemui.startable.Dependencies; import com.android.systemui.statusbar.NotificationInsetsModule; import com.android.systemui.statusbar.QsFrameTranslateModule; import com.android.systemui.statusbar.policy.ConfigurationController; @@ -47,6 +48,7 @@ import dagger.Subcomponent; import java.util.Map; import java.util.Optional; +import java.util.Set; import javax.inject.Provider; @@ -160,6 +162,11 @@ public interface SysUIComponent { @PerUser Map<Class<?>, Provider<CoreStartable>> getPerUserStartables(); /** + * Returns {@link CoreStartable} dependencies if there are any. + */ + @Dependencies Map<Class<?>, Set<Class<? extends CoreStartable>>> getStartableDependencies(); + + /** * Member injection into the supplied argument. */ void inject(SystemUIAppComponentFactoryBase factory); diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java index 6b85d3039e15..938647996899 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java @@ -29,6 +29,7 @@ import com.android.keyguard.dagger.KeyguardBouncerComponent; import com.android.systemui.BootCompleteCache; import com.android.systemui.BootCompleteCacheImpl; import com.android.systemui.CameraProtectionModule; +import com.android.systemui.CoreStartable; import com.android.systemui.SystemUISecondaryUserService; import com.android.systemui.accessibility.AccessibilityModule; import com.android.systemui.accessibility.data.repository.AccessibilityRepositoryModule; @@ -105,6 +106,7 @@ import com.android.systemui.shade.transition.LargeScreenShadeInterpolator; import com.android.systemui.shade.transition.LargeScreenShadeInterpolatorImpl; import com.android.systemui.shared.condition.Monitor; import com.android.systemui.smartspace.dagger.SmartspaceModule; +import com.android.systemui.startable.Dependencies; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationShadeWindowController; @@ -162,11 +164,14 @@ import dagger.Module; import dagger.Provides; import dagger.multibindings.ClassKey; import dagger.multibindings.IntoMap; +import dagger.multibindings.Multibinds; import kotlinx.coroutines.CoroutineScope; import java.util.Collections; +import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.concurrent.Executor; import javax.inject.Named; @@ -270,6 +275,10 @@ import javax.inject.Named; }) public abstract class SystemUIModule { + @Multibinds + @Dependencies + abstract Map<Class<?>, Set<Class<? extends CoreStartable>>> startableDependencyMap(); + @Binds abstract BootCompleteCache bindBootCompleteCache(BootCompleteCacheImpl bootCompleteCache); diff --git a/packages/SystemUI/src/com/android/systemui/startable/Dependencies.kt b/packages/SystemUI/src/com/android/systemui/startable/Dependencies.kt index 8eed0975579d..396c5f2db605 100644 --- a/packages/SystemUI/src/com/android/systemui/startable/Dependencies.kt +++ b/packages/SystemUI/src/com/android/systemui/startable/Dependencies.kt @@ -16,7 +16,8 @@ package com.android.systemui.startable import com.android.systemui.CoreStartable -import kotlin.reflect.KClass +import java.lang.annotation.Documented +import javax.inject.Qualifier /** * Allows a [CoreStartable] to declare that it must be started after its dependencies. @@ -24,7 +25,4 @@ import kotlin.reflect.KClass * This creates a partial, topological ordering. See [com.android.systemui.SystemUIApplication] for * how this ordering is enforced at runtime. */ -@MustBeDocumented -@Target(AnnotationTarget.CLASS) -@Retention(AnnotationRetention.RUNTIME) -annotation class Dependencies(vararg val value: KClass<*> = []) +@Qualifier @Documented @Retention(AnnotationRetention.RUNTIME) annotation class Dependencies() diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java b/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java index d2fe20d9c50c..8104755b5e7b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java @@ -23,7 +23,6 @@ import android.view.View; import com.android.systemui.CoreStartable; import com.android.systemui.plugins.statusbar.StatusBarStateController; -import com.android.systemui.startable.Dependencies; import com.android.systemui.statusbar.phone.CentralSurfaces; import java.lang.annotation.Retention; @@ -31,7 +30,6 @@ import java.lang.annotation.Retention; /** * Sends updates to {@link StateListener}s about changes to the status bar state and dozing state */ -@Dependencies(CentralSurfaces.class) public interface SysuiStatusBarStateController extends StatusBarStateController, CoreStartable { // TODO: b/115739177 (remove this explicit ordering if we can) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java index 594c1913fd33..9bb860f989e1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java @@ -41,6 +41,7 @@ import com.android.systemui.shade.NotificationPanelViewController; import com.android.systemui.shade.ShadeSurface; import com.android.systemui.shade.ShadeSurfaceImpl; import com.android.systemui.shade.carrier.ShadeCarrierGroupController; +import com.android.systemui.startable.Dependencies; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.NotificationClickNotifier; import com.android.systemui.statusbar.NotificationMediaManager; @@ -52,6 +53,7 @@ import com.android.systemui.statusbar.commandline.CommandRegistry; import com.android.systemui.statusbar.notification.collection.NotifCollection; import com.android.systemui.statusbar.notification.collection.NotifPipeline; import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider; +import com.android.systemui.statusbar.phone.CentralSurfaces; import com.android.systemui.statusbar.phone.CentralSurfacesImpl; import com.android.systemui.statusbar.phone.ManagedProfileController; import com.android.systemui.statusbar.phone.ManagedProfileControllerImpl; @@ -68,6 +70,8 @@ import dagger.Provides; import dagger.multibindings.ClassKey; import dagger.multibindings.IntoMap; +import java.util.Set; + import javax.inject.Provider; /** @@ -157,6 +161,15 @@ public interface CentralSurfacesDependenciesModule { CoreStartable bindsStartStatusBarStateController(StatusBarStateControllerImpl sbsc); /** */ + @Provides + @IntoMap + @Dependencies + @ClassKey(SysuiStatusBarStateController.class) + static Set<Class<? extends CoreStartable>> providesStatusBarStateControllerDeps() { + return Set.of(CentralSurfaces.class); + } + + /** */ @Binds StatusBarIconController provideStatusBarIconController( StatusBarIconControllerImpl controllerImpl); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java index 2651d2eed404..8fb552f167bc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java @@ -37,6 +37,7 @@ import androidx.lifecycle.LifecycleOwner; import com.android.internal.annotations.VisibleForTesting; import com.android.keyguard.AuthKeyguardMessageArea; +import com.android.systemui.CoreStartable; import com.android.systemui.Dumpable; import com.android.systemui.animation.ActivityTransitionAnimator; import com.android.systemui.animation.RemoteAnimationRunnerCompat; @@ -50,7 +51,7 @@ import com.android.systemui.util.Compile; import java.io.PrintWriter; /** */ -public interface CentralSurfaces extends Dumpable, LifecycleOwner { +public interface CentralSurfaces extends Dumpable, LifecycleOwner, CoreStartable { boolean MULTIUSER_DEBUG = false; // Should match the values in PhoneWindowManager String SYSTEM_DIALOG_REASON_KEY = "reason"; @@ -182,6 +183,9 @@ public interface CentralSurfaces extends Dumpable, LifecycleOwner { return contextForUser.getPackageManager(); } + /** Default impl for CoreStartable. */ + default void start() {} + boolean updateIsKeyguard(); boolean updateIsKeyguard(boolean forceStateChange); diff --git a/packages/SystemUI/tests/src/com/android/systemui/SystemUIApplicationTest.kt b/packages/SystemUI/tests/src/com/android/systemui/SystemUIApplicationTest.kt index e157fc508f87..4f7610ab7d72 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/SystemUIApplicationTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/SystemUIApplicationTest.kt @@ -27,7 +27,6 @@ import com.android.systemui.dump.dumpManager import com.android.systemui.flags.systemPropertiesHelper import com.android.systemui.kosmos.Kosmos import com.android.systemui.process.processWrapper -import com.android.systemui.startable.Dependencies import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth.assertThat import javax.inject.Provider @@ -56,6 +55,19 @@ class SystemUIApplicationTest : SysuiTestCase() { @Mock private lateinit var bootCompleteCache: BootCompleteCacheImpl @Mock private lateinit var initController: InitController + class StartableA : TestableStartable() + class StartableB : TestableStartable() + class StartableC : TestableStartable() + class StartableD : TestableStartable() + class StartableE : TestableStartable() + + val dependencyMap: Map<Class<*>, Set<Class<out CoreStartable>>> = + mapOf( + StartableC::class.java to setOf(StartableA::class.java), + StartableD::class.java to setOf(StartableA::class.java, StartableB::class.java), + StartableE::class.java to setOf(StartableD::class.java, StartableB::class.java), + ) + private val startableA = StartableA() private val startableB = StartableB() private val startableC = StartableC() @@ -76,6 +88,7 @@ class SystemUIApplicationTest : SysuiTestCase() { whenever(sysuiComponent.provideBootCacheImpl()).thenReturn(bootCompleteCache) whenever(sysuiComponent.createDumpManager()).thenReturn(kosmos.dumpManager) whenever(sysuiComponent.initController).thenReturn(initController) + whenever(sysuiComponent.startableDependencies).thenReturn(dependencyMap) kosmos.processWrapper.systemUser = true app.setContextAvailableCallback(contextAvailableCallback) @@ -168,13 +181,4 @@ class SystemUIApplicationTest : SysuiTestCase() { startOrder++ } } - - class StartableA : TestableStartable() - class StartableB : TestableStartable() - - @Dependencies(StartableA::class) class StartableC : TestableStartable() - - @Dependencies(StartableA::class, StartableB::class) class StartableD : TestableStartable() - - @Dependencies(StartableD::class, StartableB::class) class StartableE : TestableStartable() } |