Merge "Revert^2 "Change SysemUIFactory to SystemUIInitializer."" into tm-qpr-dev

This commit is contained in:
Dave Mankoff
2022-07-15 16:44:04 +00:00
committed by Android (Google) Code Review
19 changed files with 378 additions and 270 deletions

View File

@@ -5,9 +5,9 @@
-keep class com.android.systemui.statusbar.car.CarStatusBar
-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.SystemUIFactory
-keep class com.android.systemui.tv.TvSystemUIFactory
-keep class ** extends com.android.systemui.SystemUIInitializer {
*;
}
-keep class * extends com.android.systemui.CoreStartable
-keep class * implements com.android.systemui.CoreStartable$Injector

View File

@@ -22,7 +22,7 @@
<resources>
<!-- SystemUIFactory component -->
<string name="config_systemUIFactoryComponent" translatable="false">
com.android.systemui.tv.TvSystemUIFactory
com.android.systemui.tv.TvSystemUIInitializer
</string>
<!-- Svelte specific logic, see RecentsConfiguration.SVELTE_* constants. -->

View File

@@ -286,7 +286,7 @@
<bool name="config_enableFullscreenUserSwitcher">false</bool>
<!-- SystemUIFactory component -->
<string name="config_systemUIFactoryComponent" translatable="false">com.android.systemui.SystemUIFactory</string>
<string name="config_systemUIFactoryComponent" translatable="false">com.android.systemui.SystemUIInitializerImpl</string>
<!-- QS tile shape store width. negative implies fill configuration instead of stroke-->
<dimen name="config_qsTileStrokeWidthActive">-1dp</dimen>

View File

@@ -16,160 +16,22 @@
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;
/**
* Implementation of AppComponentFactory that injects into constructors.
* Starts up SystemUI using the AOSP {@link SystemUIInitializerImpl}.
*
* This class sets up dependency injection when creating our application.
* 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.
*
* Services support dependency injection into their constructors.
*
* ContentProviders support injection into member variables - _not_ constructors.
* @deprecated Define your own SystemUIAppComponentFactoryBase implementation and use that. This
* implementation may be changed or removed in future releases.
*/
public class SystemUIAppComponentFactory extends AppComponentFactory {
private static final String TAG = "AppComponentFactory";
@Inject
public ContextComponentHelper mComponentHelper;
public SystemUIAppComponentFactory() {
super();
}
@NonNull
@Deprecated
public class SystemUIAppComponentFactory extends SystemUIAppComponentFactoryBase {
@Override
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);
protected SystemUIInitializer createSystemUIInitializer(Context context) {
return SystemUIInitializerFactory.createWithContext(context);
}
}

View File

@@ -0,0 +1,183 @@
/*
* 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)
}
}

View File

@@ -42,7 +42,6 @@ import android.view.SurfaceControl;
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;
@@ -65,7 +64,6 @@ public class SystemUIApplication extends Application implements
public static final String TAG = "SystemUIService";
private static final boolean DEBUG = false;
private ContextComponentHelper mComponentHelper;
private BootCompleteCacheImpl mBootCompleteCache;
private DumpManager mDumpManager;
@@ -80,8 +78,8 @@ public class SystemUIApplication extends Application implements
private CoreStartable[] mServices;
private boolean mServicesStarted;
private SystemUIAppComponentFactory.ContextAvailableCallback mContextAvailableCallback;
private GlobalRootComponent mRootComponent;
private SysUIComponent mSysUIComponent;
private SystemUIInitializer mInitializer;
public SystemUIApplication() {
super();
@@ -90,6 +88,10 @@ public class SystemUIApplication extends Application implements
ProtoLog.REQUIRE_PROTOLOGTOOL = false;
}
protected GlobalRootComponent getRootComponent() {
return mInitializer.getRootComponent();
}
@Override
public void onCreate() {
super.onCreate();
@@ -99,10 +101,8 @@ public class SystemUIApplication extends Application implements
TimingsTraceLog log = new TimingsTraceLog("SystemUIBootTiming",
Trace.TRACE_TAG_APP);
log.traceBegin("DependencyInjection");
mContextAvailableCallback.onContextAvailable(this);
mRootComponent = SystemUIFactory.getInstance().getRootComponent();
mSysUIComponent = SystemUIFactory.getInstance().getSysUIComponent();
mComponentHelper = mSysUIComponent.getContextComponentHelper();
mInitializer = mContextAvailableCallback.onContextAvailable(this);
mSysUIComponent = mInitializer.getSysUIComponent();
mBootCompleteCache = mSysUIComponent.provideBootCacheImpl();
log.traceEnd();
@@ -189,15 +189,14 @@ public class SystemUIApplication extends Application implements
*/
public void startServicesIfNeeded() {
final String vendorComponent = SystemUIFactory.getInstance()
.getVendorComponent(getResources());
final String vendorComponent = mInitializer.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(SystemUIFactory.getInstance().getStartableComponents());
sortedStartables.putAll(SystemUIFactory.getInstance().getStartableComponentsPerUser());
sortedStartables.putAll(mSysUIComponent.getStartables());
sortedStartables.putAll(mSysUIComponent.getPerUserStartables());
startServicesIfNeeded(
sortedStartables, "StartServices", vendorComponent);
}
@@ -212,7 +211,7 @@ public class SystemUIApplication extends Application implements
// Sort the startables so that we get a deterministic ordering.
Map<Class<?>, Provider<CoreStartable>> sortedStartables = new TreeMap<>(
Comparator.comparing(Class::getName));
sortedStartables.putAll(SystemUIFactory.getInstance().getStartableComponentsPerUser());
sortedStartables.putAll(mSysUIComponent.getPerUserStartables());
startServicesIfNeeded(
sortedStartables, "StartSecondaryServices", null);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2016 The Android Open Source Project
* 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.
@@ -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,8 +22,6 @@ import android.os.Handler;
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;
@@ -31,66 +29,47 @@ import com.android.systemui.util.InitializationChecker;
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;
/**
* Class factory to provide customizable SystemUI components.
* Initializer that stands up SystemUI.
*
* Implementations should override {@link #getGlobalRootComponentBuilder()} to fill in their own
* Dagger root component.
*/
public class SystemUIFactory {
public abstract class SystemUIInitializer {
private static final String TAG = "SystemUIFactory";
static SystemUIFactory mFactory;
private final Context mContext;
private GlobalRootComponent mRootComponent;
private WMComponent mWMComponent;
private SysUIComponent mSysUIComponent;
private InitializationChecker mInitializationChecker;
public static <T extends SystemUIFactory> T getInstance() {
return (T) mFactory;
public SystemUIInitializer(Context context) {
mContext = context;
}
public static void createFromConfig(Context context) {
createFromConfig(context, false);
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;
}
@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 {
/**
* Starts the initialization process. This stands up the Dagger graph.
*/
public void init(boolean fromTest) throws ExecutionException, InterruptedException {
mRootComponent = getGlobalRootComponentBuilder()
.context(context)
.context(mContext)
.instrumentationTest(fromTest)
.build();
@@ -98,7 +77,7 @@ public class SystemUIFactory {
boolean initializeComponents = mInitializationChecker.initializeComponents();
// Stand up WMComponent
setupWmComponent(context);
setupWmComponent(mContext);
if (initializeComponents) {
// Only initialize when not starting from tests since this currently initializes some
// components that shouldn't be run in the test environment
@@ -188,20 +167,6 @@ public class SystemUIFactory {
}
}
/**
* 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;
}
@@ -214,24 +179,10 @@ public class SystemUIFactory {
return mSysUIComponent;
}
/**
* 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();
}
}

View File

@@ -0,0 +1,72 @@
/*
* 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
}
}
}
}

View File

@@ -0,0 +1,30 @@
/*
* 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()
}
}

View File

@@ -21,7 +21,7 @@ import com.android.systemui.BootCompleteCacheImpl;
import com.android.systemui.CoreStartable;
import com.android.systemui.Dependency;
import com.android.systemui.InitController;
import com.android.systemui.SystemUIAppComponentFactory;
import com.android.systemui.SystemUIAppComponentFactoryBase;
import com.android.systemui.dagger.qualifiers.PerUser;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.KeyguardSliceProvider;
@@ -241,7 +241,7 @@ public interface SysUIComponent {
/**
* Member injection into the supplied argument.
*/
void inject(SystemUIAppComponentFactory factory);
void inject(SystemUIAppComponentFactoryBase factory);
/**
* Member injection into the supplied argument.

View File

@@ -26,7 +26,6 @@ import com.android.keyguard.clock.ClockModule;
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;
@@ -200,11 +199,6 @@ public abstract class SystemUIModule {
@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

View File

@@ -21,7 +21,7 @@ import android.os.HandlerThread;
import androidx.annotation.Nullable;
import com.android.systemui.SystemUIFactory;
import com.android.systemui.SystemUIInitializerFactory;
import com.android.systemui.tv.TvWMComponent;
import com.android.wm.shell.ShellCommandHandler;
import com.android.wm.shell.ShellInit;
@@ -52,7 +52,7 @@ import dagger.Subcomponent;
/**
* Dagger Subcomponent for WindowManager. This class explicitly describes the interfaces exported
* from the WM component into the SysUI component (in
* {@link SystemUIFactory#init(Context, boolean)}), and references the specific dependencies
* {@link SystemUIInitializerFactory#init(Context, boolean)}), and references the specific dependencies
* provided by its particular device/form-factor SystemUI implementation.
*
* ie. {@link WMComponent} includes {@link WMShellModule}

View File

@@ -29,7 +29,8 @@ import android.os.UserHandle;
import android.util.Log;
import android.widget.RemoteViews;
import com.android.systemui.SystemUIAppComponentFactory;
import com.android.systemui.SystemUIAppComponentFactoryBase.ContextAvailableCallback;
import com.android.systemui.SystemUIAppComponentFactoryBase.ContextInitializer;
import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
import com.android.systemui.shared.system.PeopleProviderUtils;
@@ -37,11 +38,11 @@ import javax.inject.Inject;
/** API that returns a People Tile preview. */
public class PeopleProvider extends ContentProvider implements
SystemUIAppComponentFactory.ContextInitializer {
ContextInitializer {
private static final String TAG = "PeopleProvider";
private static final boolean DEBUG = PeopleSpaceUtils.DEBUG;
private static final String EMPTY_STRING = "";
private SystemUIAppComponentFactory.ContextAvailableCallback mCallback;
private ContextAvailableCallback mCallback;
@Inject
PeopleSpaceWidgetManager mPeopleSpaceWidgetManager;
@@ -144,7 +145,7 @@ public class PeopleProvider extends ContentProvider implements
@Override
public void setContextAvailableCallback(
SystemUIAppComponentFactory.ContextAvailableCallback callback) {
ContextAvailableCallback callback) {
mCallback = callback;
}
}

View File

@@ -16,14 +16,20 @@
package com.android.systemui.tv;
import com.android.systemui.SystemUIFactory;
import android.content.Context;
import com.android.systemui.SystemUIInitializer;
import com.android.systemui.dagger.GlobalRootComponent;
/**
* TV variant {@link SystemUIFactory}, that substitutes default {@link GlobalRootComponent} for
* TV variant {@link SystemUIInitializer}, that substitutes default {@link GlobalRootComponent} for
* {@link TvGlobalRootComponent}
*/
public class TvSystemUIFactory extends SystemUIFactory {
public class TvSystemUIInitializer extends SystemUIInitializer {
public TvSystemUIInitializer(Context context) {
super(context);
}
@Override
protected GlobalRootComponent.Builder getGlobalRootComponentBuilder() {
return DaggerTvGlobalRootComponent.builder();

View File

@@ -26,6 +26,8 @@ import com.android.systemui.statusbar.policy.FlashlightController;
import org.junit.Assert;
import org.junit.Test;
import java.util.concurrent.ExecutionException;
@SmallTest
public class DependencyTest extends SysuiTestCase {
@@ -44,10 +46,12 @@ public class DependencyTest extends SysuiTestCase {
}
@Test
public void testInitDependency() {
public void testInitDependency() throws ExecutionException, InterruptedException {
Dependency.clearDependencies();
Dependency dependency =
SystemUIFactory.getInstance().getSysUIComponent().createDependency();
SystemUIInitializer initializer =
SystemUIInitializerFactory.createFromConfigNoAssert(mContext);
initializer.init(true);
Dependency dependency = initializer.getSysUIComponent().createDependency();
dependency.start();
}
}

View File

@@ -34,6 +34,8 @@ import org.junit.Before;
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;
@@ -54,10 +56,11 @@ public abstract class SysuiBaseFragmentTest extends BaseFragmentTest {
}
@Before
public void SysuiSetup() {
SystemUIFactory.createFromConfig(mContext, true);
mDependency = new TestableDependency(
SystemUIFactory.getInstance().getSysUIComponent().createDependency());
public void sysuiSetup() throws ExecutionException, InterruptedException {
SystemUIInitializer initializer =
SystemUIInitializerFactory.createFromConfigNoAssert(mContext);
initializer.init(true);
mDependency = new TestableDependency(initializer.getSysUIComponent().createDependency());
Dependency.setInstance(mDependency);
// TODO: Figure out another way to give reference to a SysuiTestableContext.
@@ -77,7 +80,6 @@ public abstract class SysuiBaseFragmentTest extends BaseFragmentTest {
public void SysuiTeardown() {
InstrumentationRegistry.registerInstance(mRealInstrumentation,
InstrumentationRegistry.getArguments());
SystemUIFactory.cleanup();
}
@AfterClass

View File

@@ -76,9 +76,10 @@ public abstract class SysuiTestCase {
@Before
public void SysuiSetup() throws Exception {
SystemUIFactory.createFromConfig(mContext, true);
mDependency = new TestableDependency(
SystemUIFactory.getInstance().getSysUIComponent().createDependency());
SystemUIInitializer initializer =
SystemUIInitializerFactory.createFromConfigNoAssert(mContext);
initializer.init(true);
mDependency = new TestableDependency(initializer.getSysUIComponent().createDependency());
Dependency.setInstance(mDependency);
mFakeBroadcastDispatcher = new FakeBroadcastDispatcher(mContext, mock(Looper.class),
mock(Executor.class), mock(DumpManager.class),

View File

@@ -45,6 +45,7 @@ import androidx.slice.core.SliceQuery;
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;
@@ -100,7 +101,7 @@ public class KeyguardSliceProviderTest extends SysuiTestCase {
MockitoAnnotations.initMocks(this);
mIsZenMode = false;
mProvider = new TestableKeyguardSliceProvider();
mProvider.setContextAvailableCallback(context -> { });
mProvider.setContextAvailableCallback(context -> new SystemUIInitializerImpl(mContext));
mProvider.attachInfo(getContext(), null);
reset(mContentResolver);
SliceProvider.setSpecs(new HashSet<>(Arrays.asList(SliceSpecs.LIST)));

View File

@@ -44,6 +44,7 @@ import com.android.systemui.SysuiBaseFragmentTest;
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;
@@ -114,6 +115,7 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
@Before
public void setup() {
injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
mDependency.injectMockDependency(DarkIconDispatcher.class);
}
@Test