Merge "Revert "Change SysemUIFactory to SystemUIInitializer.""
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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. -->
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -42,6 +42,7 @@ 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;
|
||||
@@ -64,6 +65,7 @@ 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;
|
||||
|
||||
@@ -78,8 +80,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();
|
||||
@@ -88,10 +90,6 @@ public class SystemUIApplication extends Application implements
|
||||
ProtoLog.REQUIRE_PROTOLOGTOOL = false;
|
||||
}
|
||||
|
||||
protected GlobalRootComponent getRootComponent() {
|
||||
return mInitializer.getRootComponent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
@@ -101,8 +99,10 @@ public class SystemUIApplication extends Application implements
|
||||
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 class SystemUIApplication extends Application implements
|
||||
*/
|
||||
|
||||
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 @@ 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(mSysUIComponent.getPerUserStartables());
|
||||
sortedStartables.putAll(SystemUIFactory.getInstance().getStartableComponentsPerUser());
|
||||
startServicesIfNeeded(
|
||||
sortedStartables, "StartSecondaryServices", null);
|
||||
}
|
||||
|
||||
@@ -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.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;
|
||||
@@ -29,47 +31,66 @@ 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;
|
||||
|
||||
/**
|
||||
* 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 @@ public abstract class SystemUIInitializer {
|
||||
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 @@ public abstract class SystemUIInitializer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
@@ -179,10 +214,24 @@ public abstract class SystemUIInitializer {
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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.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 @@ public interface SysUIComponent {
|
||||
/**
|
||||
* Member injection into the supplied argument.
|
||||
*/
|
||||
void inject(SystemUIAppComponentFactoryBase factory);
|
||||
void inject(SystemUIAppComponentFactory factory);
|
||||
|
||||
/**
|
||||
* Member injection into the supplied argument.
|
||||
|
||||
@@ -26,6 +26,7 @@ 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;
|
||||
@@ -197,6 +198,11 @@ 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
|
||||
|
||||
@@ -21,7 +21,7 @@ import android.os.HandlerThread;
|
||||
|
||||
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 @@ import dagger.Subcomponent;
|
||||
/**
|
||||
* 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}
|
||||
|
||||
@@ -29,8 +29,7 @@ import android.os.UserHandle;
|
||||
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 @@ import javax.inject.Inject;
|
||||
|
||||
/** 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 @@ public class PeopleProvider extends ContentProvider implements
|
||||
|
||||
@Override
|
||||
public void setContextAvailableCallback(
|
||||
ContextAvailableCallback callback) {
|
||||
SystemUIAppComponentFactory.ContextAvailableCallback callback) {
|
||||
mCallback = callback;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
@@ -26,8 +26,6 @@ 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 {
|
||||
|
||||
@@ -46,12 +44,10 @@ public class DependencyTest extends SysuiTestCase {
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,8 +34,6 @@ 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;
|
||||
@@ -56,11 +54,10 @@ public abstract class SysuiBaseFragmentTest extends BaseFragmentTest {
|
||||
}
|
||||
|
||||
@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 abstract class SysuiBaseFragmentTest extends BaseFragmentTest {
|
||||
public void SysuiTeardown() {
|
||||
InstrumentationRegistry.registerInstance(mRealInstrumentation,
|
||||
InstrumentationRegistry.getArguments());
|
||||
SystemUIFactory.cleanup();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
|
||||
@@ -76,10 +76,9 @@ public abstract class SysuiTestCase {
|
||||
|
||||
@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),
|
||||
|
||||
@@ -45,7 +45,6 @@ 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;
|
||||
@@ -101,7 +100,7 @@ public class KeyguardSliceProviderTest extends SysuiTestCase {
|
||||
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)));
|
||||
|
||||
@@ -44,7 +44,6 @@ 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;
|
||||
@@ -113,7 +112,6 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
|
||||
@Before
|
||||
public void setup() {
|
||||
injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
|
||||
mDependency.injectMockDependency(DarkIconDispatcher.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user