Eliminate reflective form factor aware initialization

This CL removes the runtime instantiation of the form-factor specific
SystemUIInitializer via reflection, which is no longer necessary since
Android TV moved to use a dedicated TvSystemUI target.

This reduces the size of the SystemUI.apk by 500 KB by enabling R8 to
discard TV-specific classes.

Test: make
Bug: 282633512
Change-Id: I30cdb0c2a26e631594bb4bd9ddcecd329de10325
This commit is contained in:
Nikolas Havrikov
2023-05-15 13:53:24 +02:00
parent 0bec56ca04
commit ee2f59665f
13 changed files with 38 additions and 142 deletions

View File

@@ -370,7 +370,7 @@
android:defaultToDeviceProtectedStorage="true"
android:directBootAware="true"
tools:replace="android:appComponentFactory"
android:appComponentFactory=".SystemUIAppComponentFactory">
android:appComponentFactory=".PhoneSystemUIAppComponentFactory">
<!-- Keep theme in sync with SystemUIApplication.onCreate().
Setting the theme on the application does not affect views inflated by services.
The application theme is set again from onCreate to take effect for those views. -->

View File

@@ -1,13 +1,7 @@
-include proguard_common.flags
-keep class com.android.systemui.statusbar.tv.TvStatusBar
-keep class com.android.systemui.SystemUIInitializerImpl {
*;
}
-keep class com.android.systemui.tv.TvSystemUIInitializer {
*;
}
-keep,allowoptimization,allowaccessmodification class com.android.systemui.dagger.DaggerReferenceGlobalRootComponent** { !synthetic *; }
-keep,allowoptimization,allowaccessmodification class com.android.systemui.tv.DaggerTvGlobalRootComponent** { !synthetic *; }
-keep,allowoptimization,allowaccessmodification class com.android.systemui.dagger.DaggerReferenceGlobalRootComponent** { !synthetic *; }

View File

@@ -20,11 +20,6 @@
<!-- These resources are around just to allow their values to be customized
for different hardware and product builds. -->
<resources>
<!-- SystemUIFactory component -->
<string name="config_systemUIFactoryComponent" translatable="false">
com.android.systemui.tv.TvSystemUIInitializer
</string>
<!-- Svelte specific logic, see RecentsConfiguration.SVELTE_* constants. -->
<integer name="recents_svelte_level">3</integer>

View File

@@ -302,9 +302,6 @@
<!-- Determines whether the shell features all run on another thread. -->
<bool name="config_enableShellMainThread">true</bool>
<!-- SystemUIFactory component -->
<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>
<dimen name="config_qsTileStrokeWidthInactive">-1dp</dimen>

View File

@@ -0,0 +1,23 @@
/*
* Copyright (C) 2023 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
class PhoneSystemUIAppComponentFactory : SystemUIAppComponentFactoryBase() {
override fun createSystemUIInitializer(context: Context) = SystemUIInitializerImpl(context)
}

View File

@@ -1,37 +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.content.Context;
/**
* Starts up SystemUI using the AOSP {@link SystemUIInitializerImpl}.
*
* 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.
*
* @deprecated Define your own SystemUIAppComponentFactoryBase implementation and use that. This
* implementation may be changed or removed in future releases.
*/
@Deprecated
public class SystemUIAppComponentFactory extends SystemUIAppComponentFactoryBase {
@Override
protected SystemUIInitializer createSystemUIInitializer(Context context) {
return SystemUIInitializerFactory.createWithContext(context);
}
}

View File

@@ -54,7 +54,7 @@ import javax.inject.Provider;
* Application class for SystemUI.
*/
public class SystemUIApplication extends Application implements
SystemUIAppComponentFactory.ContextInitializer {
SystemUIAppComponentFactoryBase.ContextInitializer {
public static final String TAG = "SystemUIService";
private static final boolean DEBUG = false;
@@ -66,7 +66,7 @@ public class SystemUIApplication extends Application implements
*/
private CoreStartable[] mServices;
private boolean mServicesStarted;
private SystemUIAppComponentFactory.ContextAvailableCallback mContextAvailableCallback;
private SystemUIAppComponentFactoryBase.ContextAvailableCallback mContextAvailableCallback;
private SysUIComponent mSysUIComponent;
private SystemUIInitializer mInitializer;
@@ -366,7 +366,7 @@ public class SystemUIApplication extends Application implements
@Override
public void setContextAvailableCallback(
SystemUIAppComponentFactory.ContextAvailableCallback callback) {
SystemUIAppComponentFactoryBase.ContextAvailableCallback callback) {
mContextAvailableCallback = callback;
}

View File

@@ -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
}
}
}
}

View File

@@ -16,12 +16,11 @@
package com.android.systemui.dagger;
import android.content.Context;
import android.os.HandlerThread;
import androidx.annotation.Nullable;
import com.android.systemui.SystemUIInitializerFactory;
import com.android.systemui.SystemUIInitializer;
import com.android.systemui.tv.TvWMComponent;
import com.android.wm.shell.back.BackAnimation;
import com.android.wm.shell.bubbles.Bubbles;
@@ -49,7 +48,7 @@ import java.util.Optional;
/**
* 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 SystemUIInitializer#init(boolean)}), and references the specific dependencies
* provided by its particular device/form-factor SystemUI implementation.
*
* ie. {@link WMComponent} includes {@link WMShellModule}

View File

@@ -49,7 +49,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.R;
import com.android.systemui.SystemUIAppComponentFactory;
import com.android.systemui.SystemUIAppComponentFactoryBase;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.NotificationMediaManager;
@@ -72,13 +72,13 @@ import javax.inject.Inject;
/**
* Simple Slice provider that shows the current date.
*
* Injection is handled by {@link SystemUIAppComponentFactory} +
* Injection is handled by {@link SystemUIAppComponentFactoryBase} +
* {@link com.android.systemui.dagger.GlobalRootComponent#inject(KeyguardSliceProvider)}.
*/
public class KeyguardSliceProvider extends SliceProvider implements
NextAlarmController.NextAlarmChangeCallback, ZenModeController.Callback,
NotificationMediaManager.MediaListener, StatusBarStateController.StateListener,
SystemUIAppComponentFactory.ContextInitializer {
SystemUIAppComponentFactoryBase.ContextInitializer {
private static final String TAG = "KgdSliceProvider";
@@ -148,7 +148,7 @@ public class KeyguardSliceProvider extends SliceProvider implements
protected boolean mDozing;
private int mStatusBarState;
private boolean mMediaIsVisible;
private SystemUIAppComponentFactory.ContextAvailableCallback mContextAvailableCallback;
private SystemUIAppComponentFactoryBase.ContextAvailableCallback mContextAvailableCallback;
@Inject
WakeLockLogger mWakeLockLogger;
@@ -533,7 +533,7 @@ public class KeyguardSliceProvider extends SliceProvider implements
@Override
public void setContextAvailableCallback(
SystemUIAppComponentFactory.ContextAvailableCallback callback) {
SystemUIAppComponentFactoryBase.ContextAvailableCallback callback) {
mContextAvailableCallback = callback;
}
}

View File

@@ -48,8 +48,7 @@ public class DependencyTest extends SysuiTestCase {
@Test
public void testInitDependency() throws ExecutionException, InterruptedException {
Dependency.clearDependencies();
SystemUIInitializer initializer =
SystemUIInitializerFactory.createFromConfigNoAssert(mContext);
SystemUIInitializer initializer = new SystemUIInitializerImpl(mContext);
initializer.init(true);
Dependency dependency = initializer.getSysUIComponent().createDependency();
dependency.start();

View File

@@ -57,8 +57,7 @@ public abstract class SysuiBaseFragmentTest extends BaseFragmentTest {
@Before
public void sysuiSetup() throws ExecutionException, InterruptedException {
SystemUIInitializer initializer =
SystemUIInitializerFactory.createFromConfigNoAssert(mContext);
SystemUIInitializer initializer = new SystemUIInitializerImpl(mContext);
initializer.init(true);
mDependency = new TestableDependency(initializer.getSysUIComponent().createDependency());
Dependency.setInstance(mDependency);

View File

@@ -90,8 +90,7 @@ public abstract class SysuiTestCase {
if (isRobolectricTest()) {
mContext = mContext.createDefaultDisplayContext();
}
SystemUIInitializer initializer =
SystemUIInitializerFactory.createFromConfigNoAssert(mContext);
SystemUIInitializer initializer = new SystemUIInitializerImpl(mContext);
initializer.init(true);
mDependency = new TestableDependency(initializer.getSysUIComponent().createDependency());
Dependency.setInstance(mDependency);