Loading packages/SystemUI/src/com/android/systemui/common/ui/ConfigurationState.kt +65 −12 Original line number Diff line number Diff line Loading @@ -23,31 +23,72 @@ import androidx.annotation.ColorInt import androidx.annotation.DimenRes import androidx.annotation.LayoutRes import com.android.settingslib.Utils import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.onDensityOrFontScaleChanged import com.android.systemui.statusbar.policy.onThemeChanged import com.android.systemui.util.kotlin.emitOnStart import javax.inject.Inject import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.merge interface ConfigurationState { /** * Returns a [Flow] that emits a dimension pixel size that is kept in sync with the device * configuration. * * @see android.content.res.Resources.getDimensionPixelSize */ fun getDimensionPixelSize(@DimenRes id: Int): Flow<Int> /** * Returns a [Flow] that emits a dimension pixel size that is kept in sync with the device * configuration. * * @see android.content.res.Resources.getDimensionPixelSize */ fun getDimensionPixelOffset(@DimenRes id: Int): Flow<Int> /** * Returns a [Flow] that emits a color that is kept in sync with the device theme. * * @see Utils.getColorAttrDefaultColor */ fun getColorAttr(@AttrRes id: Int, @ColorInt defaultValue: Int): Flow<Int> /** * Returns a [Flow] that emits a [View] that is re-inflated as necessary to remain in sync with * the device configuration. * * @see LayoutInflater.inflate */ @Suppress("UNCHECKED_CAST") fun <T : View> inflateLayout( @LayoutRes id: Int, root: ViewGroup?, attachToRoot: Boolean, ): Flow<T> } /** Configuration-aware-state-tracking utilities. */ class ConfigurationState @Inject class ConfigurationStateImpl @AssistedInject constructor( private val configurationController: ConfigurationController, @Application private val context: Context, private val layoutInflater: LayoutInflater, ) { @Assisted private val configurationController: ConfigurationController, @Assisted private val context: Context, ) : ConfigurationState { private val layoutInflater = LayoutInflater.from(context) /** * Returns a [Flow] that emits a dimension pixel size that is kept in sync with the device * configuration. * * @see android.content.res.Resources.getDimensionPixelSize */ fun getDimensionPixelSize(@DimenRes id: Int): Flow<Int> { override fun getDimensionPixelSize(@DimenRes id: Int): Flow<Int> { return configurationController.onDensityOrFontScaleChanged.emitOnStart().map { context.resources.getDimensionPixelSize(id) } Loading @@ -59,7 +100,7 @@ constructor( * * @see android.content.res.Resources.getDimensionPixelSize */ fun getDimensionPixelOffset(@DimenRes id: Int): Flow<Int> { override fun getDimensionPixelOffset(@DimenRes id: Int): Flow<Int> { return configurationController.onDensityOrFontScaleChanged.emitOnStart().map { context.resources.getDimensionPixelOffset(id) } Loading @@ -70,7 +111,7 @@ constructor( * * @see Utils.getColorAttrDefaultColor */ fun getColorAttr(@AttrRes id: Int, @ColorInt defaultValue: Int): Flow<Int> { override fun getColorAttr(@AttrRes id: Int, @ColorInt defaultValue: Int): Flow<Int> { return configurationController.onThemeChanged.emitOnStart().map { Utils.getColorAttrDefaultColor(context, id, defaultValue) } Loading @@ -83,7 +124,7 @@ constructor( * @see LayoutInflater.inflate */ @Suppress("UNCHECKED_CAST") fun <T : View> inflateLayout( override fun <T : View> inflateLayout( @LayoutRes id: Int, root: ViewGroup?, attachToRoot: Boolean, Loading @@ -97,4 +138,16 @@ constructor( .emitOnStart() .map { layoutInflater.inflate(id, root, attachToRoot) as T } } @AssistedFactory interface Factory { /** * Creates a configurationState for a given context. The [configurationController] is * supposed to give config events specific for that context. */ fun create( context: Context, configurationController: ConfigurationController ): ConfigurationStateImpl } } packages/SystemUI/src/com/android/systemui/common/ui/ConfigurationStateModule.kt 0 → 100644 +61 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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.common.ui import android.content.Context import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.statusbar.policy.ConfigurationController import dagger.Binds import dagger.Module import dagger.Provides import javax.inject.Qualifier /** * Annotates elements that provide information from the global configuration. * * The global configuration is the one associted with the main display. Secondary displays will * apply override to the global configuration. Elements annotated with this shouldn't be used for * secondary displays. */ @Qualifier @Retention(AnnotationRetention.RUNTIME) annotation class GlobalConfig @Module interface ConfigurationStateModule { /** * Deprecated: [ConfigurationState] should be injected only with the correct annotation. For * now, without annotation the global config associated state is provided. */ @Binds fun provideGlobalConfigurationState( @GlobalConfig configurationState: ConfigurationState ): ConfigurationState companion object { @SysUISingleton @Provides @GlobalConfig fun provideGlobalConfigurationState( configStateFactory: ConfigurationStateImpl.Factory, configurationController: ConfigurationController, @Application context: Context, ): ConfigurationState { return configStateFactory.create(context, configurationController) } } } packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java +2 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import com.android.systemui.CoreStartable; import com.android.systemui.Dependency; import com.android.systemui.InitController; import com.android.systemui.SystemUIAppComponentFactoryBase; import com.android.systemui.common.ui.GlobalConfig; import com.android.systemui.dagger.qualifiers.PerUser; import com.android.systemui.dump.DumpManager; import com.android.systemui.keyguard.KeyguardSliceProvider; Loading Loading @@ -127,6 +128,7 @@ public interface SysUIComponent { * Creates a ContextComponentHelper. */ @SysUISingleton @GlobalConfig ConfigurationController getConfigurationController(); /** Loading packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java +2 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ import com.android.systemui.brightness.dagger.ScreenBrightnessModule; import com.android.systemui.classifier.FalsingModule; import com.android.systemui.clipboardoverlay.dagger.ClipboardOverlayModule; import com.android.systemui.common.data.CommonDataLayerModule; import com.android.systemui.common.ui.ConfigurationStateModule; import com.android.systemui.common.usagestats.data.CommonUsageStatsDataLayerModule; import com.android.systemui.communal.dagger.CommunalModule; import com.android.systemui.complication.dagger.ComplicationComponent; Loading Loading @@ -207,6 +208,7 @@ import javax.inject.Named; ClockRegistryModule.class, CommunalModule.class, CommonDataLayerModule.class, ConfigurationStateModule.class, CommonUsageStatsDataLayerModule.class, ConfigurationControllerModule.class, ConnectivityModule.class, Loading packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt +4 −2 Original line number Diff line number Diff line Loading @@ -122,8 +122,10 @@ interface MediaProjectionAppSelectorModule { @Provides @MediaProjectionAppSelector @MediaProjectionAppSelectorScope fun bindConfigurationController(context: Context): ConfigurationController = ConfigurationControllerImpl(context) fun bindConfigurationController( context: Context, configurationControlleFactory: ConfigurationControllerImpl.Factory ): ConfigurationController = configurationControlleFactory.create(context) @Provides fun bindIconFactory(context: Context): IconFactory = IconFactory.obtain(context) Loading Loading
packages/SystemUI/src/com/android/systemui/common/ui/ConfigurationState.kt +65 −12 Original line number Diff line number Diff line Loading @@ -23,31 +23,72 @@ import androidx.annotation.ColorInt import androidx.annotation.DimenRes import androidx.annotation.LayoutRes import com.android.settingslib.Utils import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.onDensityOrFontScaleChanged import com.android.systemui.statusbar.policy.onThemeChanged import com.android.systemui.util.kotlin.emitOnStart import javax.inject.Inject import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.merge interface ConfigurationState { /** * Returns a [Flow] that emits a dimension pixel size that is kept in sync with the device * configuration. * * @see android.content.res.Resources.getDimensionPixelSize */ fun getDimensionPixelSize(@DimenRes id: Int): Flow<Int> /** * Returns a [Flow] that emits a dimension pixel size that is kept in sync with the device * configuration. * * @see android.content.res.Resources.getDimensionPixelSize */ fun getDimensionPixelOffset(@DimenRes id: Int): Flow<Int> /** * Returns a [Flow] that emits a color that is kept in sync with the device theme. * * @see Utils.getColorAttrDefaultColor */ fun getColorAttr(@AttrRes id: Int, @ColorInt defaultValue: Int): Flow<Int> /** * Returns a [Flow] that emits a [View] that is re-inflated as necessary to remain in sync with * the device configuration. * * @see LayoutInflater.inflate */ @Suppress("UNCHECKED_CAST") fun <T : View> inflateLayout( @LayoutRes id: Int, root: ViewGroup?, attachToRoot: Boolean, ): Flow<T> } /** Configuration-aware-state-tracking utilities. */ class ConfigurationState @Inject class ConfigurationStateImpl @AssistedInject constructor( private val configurationController: ConfigurationController, @Application private val context: Context, private val layoutInflater: LayoutInflater, ) { @Assisted private val configurationController: ConfigurationController, @Assisted private val context: Context, ) : ConfigurationState { private val layoutInflater = LayoutInflater.from(context) /** * Returns a [Flow] that emits a dimension pixel size that is kept in sync with the device * configuration. * * @see android.content.res.Resources.getDimensionPixelSize */ fun getDimensionPixelSize(@DimenRes id: Int): Flow<Int> { override fun getDimensionPixelSize(@DimenRes id: Int): Flow<Int> { return configurationController.onDensityOrFontScaleChanged.emitOnStart().map { context.resources.getDimensionPixelSize(id) } Loading @@ -59,7 +100,7 @@ constructor( * * @see android.content.res.Resources.getDimensionPixelSize */ fun getDimensionPixelOffset(@DimenRes id: Int): Flow<Int> { override fun getDimensionPixelOffset(@DimenRes id: Int): Flow<Int> { return configurationController.onDensityOrFontScaleChanged.emitOnStart().map { context.resources.getDimensionPixelOffset(id) } Loading @@ -70,7 +111,7 @@ constructor( * * @see Utils.getColorAttrDefaultColor */ fun getColorAttr(@AttrRes id: Int, @ColorInt defaultValue: Int): Flow<Int> { override fun getColorAttr(@AttrRes id: Int, @ColorInt defaultValue: Int): Flow<Int> { return configurationController.onThemeChanged.emitOnStart().map { Utils.getColorAttrDefaultColor(context, id, defaultValue) } Loading @@ -83,7 +124,7 @@ constructor( * @see LayoutInflater.inflate */ @Suppress("UNCHECKED_CAST") fun <T : View> inflateLayout( override fun <T : View> inflateLayout( @LayoutRes id: Int, root: ViewGroup?, attachToRoot: Boolean, Loading @@ -97,4 +138,16 @@ constructor( .emitOnStart() .map { layoutInflater.inflate(id, root, attachToRoot) as T } } @AssistedFactory interface Factory { /** * Creates a configurationState for a given context. The [configurationController] is * supposed to give config events specific for that context. */ fun create( context: Context, configurationController: ConfigurationController ): ConfigurationStateImpl } }
packages/SystemUI/src/com/android/systemui/common/ui/ConfigurationStateModule.kt 0 → 100644 +61 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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.common.ui import android.content.Context import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.statusbar.policy.ConfigurationController import dagger.Binds import dagger.Module import dagger.Provides import javax.inject.Qualifier /** * Annotates elements that provide information from the global configuration. * * The global configuration is the one associted with the main display. Secondary displays will * apply override to the global configuration. Elements annotated with this shouldn't be used for * secondary displays. */ @Qualifier @Retention(AnnotationRetention.RUNTIME) annotation class GlobalConfig @Module interface ConfigurationStateModule { /** * Deprecated: [ConfigurationState] should be injected only with the correct annotation. For * now, without annotation the global config associated state is provided. */ @Binds fun provideGlobalConfigurationState( @GlobalConfig configurationState: ConfigurationState ): ConfigurationState companion object { @SysUISingleton @Provides @GlobalConfig fun provideGlobalConfigurationState( configStateFactory: ConfigurationStateImpl.Factory, configurationController: ConfigurationController, @Application context: Context, ): ConfigurationState { return configStateFactory.create(context, configurationController) } } }
packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java +2 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import com.android.systemui.CoreStartable; import com.android.systemui.Dependency; import com.android.systemui.InitController; import com.android.systemui.SystemUIAppComponentFactoryBase; import com.android.systemui.common.ui.GlobalConfig; import com.android.systemui.dagger.qualifiers.PerUser; import com.android.systemui.dump.DumpManager; import com.android.systemui.keyguard.KeyguardSliceProvider; Loading Loading @@ -127,6 +128,7 @@ public interface SysUIComponent { * Creates a ContextComponentHelper. */ @SysUISingleton @GlobalConfig ConfigurationController getConfigurationController(); /** Loading
packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java +2 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ import com.android.systemui.brightness.dagger.ScreenBrightnessModule; import com.android.systemui.classifier.FalsingModule; import com.android.systemui.clipboardoverlay.dagger.ClipboardOverlayModule; import com.android.systemui.common.data.CommonDataLayerModule; import com.android.systemui.common.ui.ConfigurationStateModule; import com.android.systemui.common.usagestats.data.CommonUsageStatsDataLayerModule; import com.android.systemui.communal.dagger.CommunalModule; import com.android.systemui.complication.dagger.ComplicationComponent; Loading Loading @@ -207,6 +208,7 @@ import javax.inject.Named; ClockRegistryModule.class, CommunalModule.class, CommonDataLayerModule.class, ConfigurationStateModule.class, CommonUsageStatsDataLayerModule.class, ConfigurationControllerModule.class, ConnectivityModule.class, Loading
packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt +4 −2 Original line number Diff line number Diff line Loading @@ -122,8 +122,10 @@ interface MediaProjectionAppSelectorModule { @Provides @MediaProjectionAppSelector @MediaProjectionAppSelectorScope fun bindConfigurationController(context: Context): ConfigurationController = ConfigurationControllerImpl(context) fun bindConfigurationController( context: Context, configurationControlleFactory: ConfigurationControllerImpl.Factory ): ConfigurationController = configurationControlleFactory.create(context) @Provides fun bindIconFactory(context: Context): IconFactory = IconFactory.obtain(context) Loading