Loading packages/SystemUI/src/com/android/systemui/statusbar/pipeline/battery/data/repository/BatteryRepository.kt +100 −7 Original line number Diff line number Diff line Loading @@ -21,7 +21,10 @@ import android.provider.Settings import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.log.table.logDiffsForTable import com.android.systemui.shared.settings.data.repository.SystemSettingsRepository import com.android.systemui.statusbar.pipeline.dagger.BatteryTableLog import com.android.systemui.statusbar.policy.BatteryController import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow import javax.inject.Inject Loading @@ -34,6 +37,7 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map Loading Loading @@ -90,6 +94,7 @@ constructor( @Background bgDispatcher: CoroutineDispatcher, private val controller: BatteryController, settingsRepository: SystemSettingsRepository, @BatteryTableLog tableLog: TableLogBuffer, ) : BatteryRepository { private val batteryState: StateFlow<BatteryCallbackState> = conflatedCallbackFlow<(BatteryCallbackState) -> BatteryCallbackState> { Loading Loading @@ -141,17 +146,79 @@ constructor( .flowOn(bgDispatcher) .stateIn(scope, SharingStarted.Lazily, BatteryCallbackState()) override val isPluggedIn = batteryState.map { it.isPluggedIn } override val isPluggedIn = batteryState .map { it.isPluggedIn } .distinctUntilChanged() .logDiffsForTable( tableLogBuffer = tableLog, columnName = COL_PLUGGED_IN, initialValue = batteryState.value.isPluggedIn, ) .stateIn(scope, SharingStarted.WhileSubscribed(), batteryState.value.isPluggedIn) override val isPowerSaveEnabled = batteryState.map { it.isPowerSaveEnabled } override val isPowerSaveEnabled = batteryState .map { it.isPowerSaveEnabled } .distinctUntilChanged() .logDiffsForTable( tableLogBuffer = tableLog, columnName = COL_POWER_SAVE, initialValue = batteryState.value.isPowerSaveEnabled, ) .stateIn(scope, SharingStarted.WhileSubscribed(), batteryState.value.isPowerSaveEnabled) override val isBatteryDefenderEnabled = batteryState.map { it.isBatteryDefenderEnabled } override val isBatteryDefenderEnabled = batteryState .map { it.isBatteryDefenderEnabled } .distinctUntilChanged() .logDiffsForTable( tableLogBuffer = tableLog, columnName = COL_DEFEND, initialValue = batteryState.value.isBatteryDefenderEnabled, ) .stateIn( scope, SharingStarted.WhileSubscribed(), batteryState.value.isBatteryDefenderEnabled, ) override val isIncompatibleCharging = batteryState.map { it.isIncompatibleCharging } override val isIncompatibleCharging = batteryState .map { it.isIncompatibleCharging } .distinctUntilChanged() .logDiffsForTable( tableLogBuffer = tableLog, columnName = COL_INCOMPATIBLE_CHARGING, initialValue = batteryState.value.isIncompatibleCharging, ) .stateIn( scope, SharingStarted.WhileSubscribed(), batteryState.value.isIncompatibleCharging, ) override val level = batteryState.map { it.level } override val level = batteryState .map { it.level } .distinctUntilChanged() .logDiffsForTable( tableLogBuffer = tableLog, columnName = COL_LEVEL, initialValue = batteryState.value.level, ) .stateIn(scope, SharingStarted.WhileSubscribed(), batteryState.value.level) override val isStateUnknown = batteryState.map { it.isStateUnknown } override val isStateUnknown = batteryState .map { it.isStateUnknown } .distinctUntilChanged() .logDiffsForTable( tableLogBuffer = tableLog, columnName = COL_UNKNOWN, initialValue = batteryState.value.isStateUnknown, ) .stateIn(scope, SharingStarted.WhileSubscribed(), batteryState.value.isStateUnknown) override val isShowBatteryPercentSettingEnabled = run { val default = Loading @@ -161,6 +228,12 @@ constructor( settingsRepository .boolSetting(name = Settings.System.SHOW_BATTERY_PERCENT, defaultValue = default) .flowOn(bgDispatcher) .distinctUntilChanged() .logDiffsForTable( tableLogBuffer = tableLog, columnName = COL_SHOW_PERCENT_SETTING, initialValue = default, ) .stateIn(scope, SharingStarted.Lazily, default) } Loading @@ -173,7 +246,16 @@ constructor( } } override val batteryTimeRemainingEstimate: Flow<String?> = estimate.flowOn(bgDispatcher) override val batteryTimeRemainingEstimate: Flow<String?> = estimate .flowOn(bgDispatcher) .distinctUntilChanged() .logDiffsForTable( tableLogBuffer = tableLog, columnName = COL_TIME_REMAINING_EST, initialValue = null, ) .stateIn(scope, SharingStarted.WhileSubscribed(), null) private suspend fun fetchEstimate() = suspendCancellableCoroutine { continuation -> val callback = Loading @@ -181,6 +263,17 @@ constructor( controller.getEstimatedTimeRemainingString(callback) } companion object { private const val COL_PLUGGED_IN = "pluggedIn" private const val COL_POWER_SAVE = "powerSave" private const val COL_DEFEND = "defend" private const val COL_INCOMPATIBLE_CHARGING = "incompatibleCharging" private const val COL_LEVEL = "level" private const val COL_UNKNOWN = "unknown" private const val COL_SHOW_PERCENT_SETTING = "showPercentSetting" private const val COL_TIME_REMAINING_EST = "timeRemainingEstimate" } } /** Data object to track the current battery callback state */ Loading packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/BatteryTableLog.kt 0 → 100644 +24 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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.statusbar.pipeline.dagger import javax.inject.Qualifier @Qualifier @MustBeDocumented @kotlin.annotation.Retention(AnnotationRetention.RUNTIME) annotation class BatteryTableLog packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt +7 −0 Original line number Diff line number Diff line Loading @@ -320,6 +320,13 @@ abstract class StatusBarPipelineModule { return factory.create("StackedMobileIconTableLog", 100) } @Provides @SysUISingleton @BatteryTableLog fun provideBatteryTableLog(factory: TableLogBufferFactory): TableLogBuffer { return factory.create("BatteryTableLog", 100) } const val FIRST_MOBILE_SUB_SHOWING_NETWORK_TYPE_ICON = "FirstMobileSubShowingNetworkTypeIcon" } Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/battery/data/repository/BatteryRepositoryTest.kt +2 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import com.android.systemui.kosmos.collectLastValue import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope import com.android.systemui.log.table.logcatTableLogBuffer import com.android.systemui.shared.settings.data.repository.fakeSystemSettingsRepository import com.android.systemui.shared.settings.data.repository.systemSettingsRepository import com.android.systemui.statusbar.policy.batteryController Loading @@ -53,6 +54,7 @@ class BatteryRepositoryTest : SysuiTestCase() { testDispatcher, batteryController, systemSettingsRepository, logcatTableLogBuffer(this, "BatteryTableLog"), ) } Loading packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/battery/data/repository/BatteryRepositoryKosmos.kt +2 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.content.testableContext import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope import com.android.systemui.log.table.logcatTableLogBuffer import com.android.systemui.shared.settings.data.repository.systemSettingsRepository import com.android.systemui.statusbar.policy.batteryController Loading @@ -32,5 +33,6 @@ val Kosmos.batteryRepository by testDispatcher, batteryController, systemSettingsRepository, logcatTableLogBuffer(this, "BatteryTableLog"), ) } Loading
packages/SystemUI/src/com/android/systemui/statusbar/pipeline/battery/data/repository/BatteryRepository.kt +100 −7 Original line number Diff line number Diff line Loading @@ -21,7 +21,10 @@ import android.provider.Settings import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.log.table.logDiffsForTable import com.android.systemui.shared.settings.data.repository.SystemSettingsRepository import com.android.systemui.statusbar.pipeline.dagger.BatteryTableLog import com.android.systemui.statusbar.policy.BatteryController import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow import javax.inject.Inject Loading @@ -34,6 +37,7 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map Loading Loading @@ -90,6 +94,7 @@ constructor( @Background bgDispatcher: CoroutineDispatcher, private val controller: BatteryController, settingsRepository: SystemSettingsRepository, @BatteryTableLog tableLog: TableLogBuffer, ) : BatteryRepository { private val batteryState: StateFlow<BatteryCallbackState> = conflatedCallbackFlow<(BatteryCallbackState) -> BatteryCallbackState> { Loading Loading @@ -141,17 +146,79 @@ constructor( .flowOn(bgDispatcher) .stateIn(scope, SharingStarted.Lazily, BatteryCallbackState()) override val isPluggedIn = batteryState.map { it.isPluggedIn } override val isPluggedIn = batteryState .map { it.isPluggedIn } .distinctUntilChanged() .logDiffsForTable( tableLogBuffer = tableLog, columnName = COL_PLUGGED_IN, initialValue = batteryState.value.isPluggedIn, ) .stateIn(scope, SharingStarted.WhileSubscribed(), batteryState.value.isPluggedIn) override val isPowerSaveEnabled = batteryState.map { it.isPowerSaveEnabled } override val isPowerSaveEnabled = batteryState .map { it.isPowerSaveEnabled } .distinctUntilChanged() .logDiffsForTable( tableLogBuffer = tableLog, columnName = COL_POWER_SAVE, initialValue = batteryState.value.isPowerSaveEnabled, ) .stateIn(scope, SharingStarted.WhileSubscribed(), batteryState.value.isPowerSaveEnabled) override val isBatteryDefenderEnabled = batteryState.map { it.isBatteryDefenderEnabled } override val isBatteryDefenderEnabled = batteryState .map { it.isBatteryDefenderEnabled } .distinctUntilChanged() .logDiffsForTable( tableLogBuffer = tableLog, columnName = COL_DEFEND, initialValue = batteryState.value.isBatteryDefenderEnabled, ) .stateIn( scope, SharingStarted.WhileSubscribed(), batteryState.value.isBatteryDefenderEnabled, ) override val isIncompatibleCharging = batteryState.map { it.isIncompatibleCharging } override val isIncompatibleCharging = batteryState .map { it.isIncompatibleCharging } .distinctUntilChanged() .logDiffsForTable( tableLogBuffer = tableLog, columnName = COL_INCOMPATIBLE_CHARGING, initialValue = batteryState.value.isIncompatibleCharging, ) .stateIn( scope, SharingStarted.WhileSubscribed(), batteryState.value.isIncompatibleCharging, ) override val level = batteryState.map { it.level } override val level = batteryState .map { it.level } .distinctUntilChanged() .logDiffsForTable( tableLogBuffer = tableLog, columnName = COL_LEVEL, initialValue = batteryState.value.level, ) .stateIn(scope, SharingStarted.WhileSubscribed(), batteryState.value.level) override val isStateUnknown = batteryState.map { it.isStateUnknown } override val isStateUnknown = batteryState .map { it.isStateUnknown } .distinctUntilChanged() .logDiffsForTable( tableLogBuffer = tableLog, columnName = COL_UNKNOWN, initialValue = batteryState.value.isStateUnknown, ) .stateIn(scope, SharingStarted.WhileSubscribed(), batteryState.value.isStateUnknown) override val isShowBatteryPercentSettingEnabled = run { val default = Loading @@ -161,6 +228,12 @@ constructor( settingsRepository .boolSetting(name = Settings.System.SHOW_BATTERY_PERCENT, defaultValue = default) .flowOn(bgDispatcher) .distinctUntilChanged() .logDiffsForTable( tableLogBuffer = tableLog, columnName = COL_SHOW_PERCENT_SETTING, initialValue = default, ) .stateIn(scope, SharingStarted.Lazily, default) } Loading @@ -173,7 +246,16 @@ constructor( } } override val batteryTimeRemainingEstimate: Flow<String?> = estimate.flowOn(bgDispatcher) override val batteryTimeRemainingEstimate: Flow<String?> = estimate .flowOn(bgDispatcher) .distinctUntilChanged() .logDiffsForTable( tableLogBuffer = tableLog, columnName = COL_TIME_REMAINING_EST, initialValue = null, ) .stateIn(scope, SharingStarted.WhileSubscribed(), null) private suspend fun fetchEstimate() = suspendCancellableCoroutine { continuation -> val callback = Loading @@ -181,6 +263,17 @@ constructor( controller.getEstimatedTimeRemainingString(callback) } companion object { private const val COL_PLUGGED_IN = "pluggedIn" private const val COL_POWER_SAVE = "powerSave" private const val COL_DEFEND = "defend" private const val COL_INCOMPATIBLE_CHARGING = "incompatibleCharging" private const val COL_LEVEL = "level" private const val COL_UNKNOWN = "unknown" private const val COL_SHOW_PERCENT_SETTING = "showPercentSetting" private const val COL_TIME_REMAINING_EST = "timeRemainingEstimate" } } /** Data object to track the current battery callback state */ Loading
packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/BatteryTableLog.kt 0 → 100644 +24 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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.statusbar.pipeline.dagger import javax.inject.Qualifier @Qualifier @MustBeDocumented @kotlin.annotation.Retention(AnnotationRetention.RUNTIME) annotation class BatteryTableLog
packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt +7 −0 Original line number Diff line number Diff line Loading @@ -320,6 +320,13 @@ abstract class StatusBarPipelineModule { return factory.create("StackedMobileIconTableLog", 100) } @Provides @SysUISingleton @BatteryTableLog fun provideBatteryTableLog(factory: TableLogBufferFactory): TableLogBuffer { return factory.create("BatteryTableLog", 100) } const val FIRST_MOBILE_SUB_SHOWING_NETWORK_TYPE_ICON = "FirstMobileSubShowingNetworkTypeIcon" } Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/battery/data/repository/BatteryRepositoryTest.kt +2 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import com.android.systemui.kosmos.collectLastValue import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope import com.android.systemui.log.table.logcatTableLogBuffer import com.android.systemui.shared.settings.data.repository.fakeSystemSettingsRepository import com.android.systemui.shared.settings.data.repository.systemSettingsRepository import com.android.systemui.statusbar.policy.batteryController Loading @@ -53,6 +54,7 @@ class BatteryRepositoryTest : SysuiTestCase() { testDispatcher, batteryController, systemSettingsRepository, logcatTableLogBuffer(this, "BatteryTableLog"), ) } Loading
packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/battery/data/repository/BatteryRepositoryKosmos.kt +2 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.content.testableContext import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope import com.android.systemui.log.table.logcatTableLogBuffer import com.android.systemui.shared.settings.data.repository.systemSettingsRepository import com.android.systemui.statusbar.policy.batteryController Loading @@ -32,5 +33,6 @@ val Kosmos.batteryRepository by testDispatcher, batteryController, systemSettingsRepository, logcatTableLogBuffer(this, "BatteryTableLog"), ) }