Merge "[sat] Table log buffers" into main
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/DeviceBasedSatelliteTableLog.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/DeviceBasedSatelliteTableLog.kt
new file mode 100644
index 0000000..a40d510
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/DeviceBasedSatelliteTableLog.kt
@@ -0,0 +1,24 @@
+/*
+ * 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.statusbar.pipeline.dagger
+
+import javax.inject.Qualifier
+
+@Qualifier
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
+annotation class DeviceBasedSatelliteTableLog
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
index a81bfa4..4850049 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
@@ -239,6 +239,13 @@
return factory.create("VerboseDeviceBasedSatelliteInputLog", 200)
}
+ @Provides
+ @SysUISingleton
+ @DeviceBasedSatelliteTableLog
+ fun provideDeviceBasedSatelliteTableLog(factory: TableLogBufferFactory): TableLogBuffer {
+ return factory.create("DeviceBasedSatelliteTableLog", 200)
+ }
+
const val FIRST_MOBILE_SUB_SHOWING_NETWORK_TYPE_ICON =
"FirstMobileSubShowingNetworkTypeIcon"
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt
index cc4d568..26553e6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractor.kt
@@ -385,7 +385,15 @@
.stateIn(scope, SharingStarted.WhileSubscribed(), false)
override val isDeviceInEmergencyCallsOnlyMode: Flow<Boolean> =
- mobileConnectionsRepo.deviceServiceState.map { it?.isEmergencyOnly ?: false }
+ mobileConnectionsRepo.deviceServiceState
+ .map { it?.isEmergencyOnly ?: false }
+ .distinctUntilChanged()
+ .logDiffsForTable(
+ tableLogger,
+ columnPrefix = LOGGING_PREFIX,
+ columnName = "deviceEmergencyOnly",
+ initialValue = false,
+ )
/** Vends out new [MobileIconInteractor] for a particular subId */
override fun getMobileConnectionInteractorForSubId(subId: Int): MobileIconInteractor =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractor.kt
index 03f88c7..f1a444f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractor.kt
@@ -21,7 +21,10 @@
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.core.LogLevel
+import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.log.table.logDiffsForTable
import com.android.systemui.statusbar.pipeline.dagger.DeviceBasedSatelliteInputLog
+import com.android.systemui.statusbar.pipeline.dagger.DeviceBasedSatelliteTableLog
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor
import com.android.systemui.statusbar.pipeline.satellite.data.DeviceBasedSatelliteRepository
import com.android.systemui.statusbar.pipeline.satellite.shared.model.SatelliteConnectionState
@@ -33,6 +36,7 @@
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
@@ -47,6 +51,7 @@
wifiInteractor: WifiInteractor,
@Application scope: CoroutineScope,
@DeviceBasedSatelliteInputLog private val logBuffer: LogBuffer,
+ @DeviceBasedSatelliteTableLog private val tableLog: TableLogBuffer,
) {
/** Must be observed by any UI showing Satellite iconography */
val isSatelliteAllowed =
@@ -55,6 +60,13 @@
} else {
flowOf(false)
}
+ .distinctUntilChanged()
+ .logDiffsForTable(
+ tableLog,
+ columnPrefix = "",
+ columnName = COL_ALLOWED,
+ initialValue = false,
+ )
.stateIn(scope, SharingStarted.WhileSubscribed(), false)
/** See [SatelliteConnectionState] for relevant states */
@@ -65,6 +77,12 @@
flowOf(SatelliteConnectionState.Off)
}
+ .distinctUntilChanged()
+ .logDiffsForTable(
+ tableLog,
+ columnPrefix = "",
+ initialValue = SatelliteConnectionState.Off,
+ )
.stateIn(scope, SharingStarted.WhileSubscribed(), SatelliteConnectionState.Off)
/** 0-4 description of the connection strength */
@@ -74,6 +92,13 @@
} else {
flowOf(0)
}
+ .distinctUntilChanged()
+ .logDiffsForTable(
+ tableLog,
+ columnPrefix = "",
+ columnName = COL_LEVEL,
+ initialValue = 0,
+ )
.stateIn(scope, SharingStarted.WhileSubscribed(), 0)
val isSatelliteProvisioned = repo.isSatelliteProvisioned
@@ -82,19 +107,27 @@
wifiInteractor.wifiNetwork.map { it is WifiNetworkModel.Active }
private val allConnectionsOos =
- iconsInteractor.icons.aggregateOver(
- selector = { intr ->
- combine(intr.isInService, intr.isEmergencyOnly, intr.isNonTerrestrial) {
- isInService,
- isEmergencyOnly,
- isNtn ->
- !isInService && !isEmergencyOnly && !isNtn
- }
- },
- defaultValue = true, // no connections == everything is OOS
- ) { isOosAndNotEmergencyAndNotSatellite ->
- isOosAndNotEmergencyAndNotSatellite.all { it }
- }
+ iconsInteractor.icons
+ .aggregateOver(
+ selector = { intr ->
+ combine(intr.isInService, intr.isEmergencyOnly, intr.isNonTerrestrial) {
+ isInService,
+ isEmergencyOnly,
+ isNtn ->
+ !isInService && !isEmergencyOnly && !isNtn
+ }
+ },
+ defaultValue = true, // no connections == everything is OOS
+ ) { isOosAndNotEmergencyAndNotSatellite ->
+ isOosAndNotEmergencyAndNotSatellite.all { it }
+ }
+ .distinctUntilChanged()
+ .logDiffsForTable(
+ tableLog,
+ columnPrefix = "",
+ columnName = COL_ALL_OOS,
+ initialValue = true,
+ )
/** When all connections are considered OOS, satellite connectivity is potentially valid */
val areAllConnectionsOutOfService =
@@ -122,10 +155,24 @@
} else {
flowOf(false)
}
+ .distinctUntilChanged()
+ .logDiffsForTable(
+ tableLog,
+ columnPrefix = "",
+ columnName = COL_FULL_OOS,
+ initialValue = true,
+ )
.stateIn(scope, SharingStarted.WhileSubscribed(), true)
companion object {
const val TAG = "DeviceBasedSatelliteInteractor"
+
+ const val COL_LEVEL = "level"
+ const val COL_ALL_OOS = "allConnsOOS"
+ const val COL_ALLOWED = "allowed"
+ // Going to try to optimize for not using too much width on the table here. This information
+ // can be ascertained by checking for the device emergency only in the mobile logs as well
+ const val COL_FULL_OOS = "allOosAndNoEmer"
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/shared/model/SatelliteConnectionState.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/shared/model/SatelliteConnectionState.kt
index bfe2941..905ed730 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/shared/model/SatelliteConnectionState.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/shared/model/SatelliteConnectionState.kt
@@ -26,8 +26,10 @@
import android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_OFF
import android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE
import android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_UNKNOWN
+import com.android.systemui.log.table.Diffable
+import com.android.systemui.log.table.TableRowLogger
-enum class SatelliteConnectionState {
+enum class SatelliteConnectionState : Diffable<SatelliteConnectionState> {
// State is unknown or undefined
Unknown,
// Radio is off
@@ -37,7 +39,15 @@
// Radio is connected, aka satellite is available for use
Connected;
+ override fun logDiffs(prevVal: SatelliteConnectionState, row: TableRowLogger) {
+ if (prevVal != this) {
+ row.logChange(COL_CONNECTION_STATE, name)
+ }
+ }
+
companion object {
+ const val COL_CONNECTION_STATE = "connState"
+
// TODO(b/316635648): validate these states. We don't need the level of granularity that
// SatelliteManager gives us.
fun fromModemState(@SatelliteManager.SatelliteModemState modemState: Int) =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModel.kt
index 48278d4..199b5b67 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModel.kt
@@ -22,9 +22,12 @@
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.core.LogLevel
+import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.log.table.logDiffsForTable
import com.android.systemui.res.R
import com.android.systemui.statusbar.pipeline.airplane.data.repository.AirplaneModeRepository
import com.android.systemui.statusbar.pipeline.dagger.DeviceBasedSatelliteInputLog
+import com.android.systemui.statusbar.pipeline.dagger.DeviceBasedSatelliteTableLog
import com.android.systemui.statusbar.pipeline.satellite.domain.interactor.DeviceBasedSatelliteInteractor
import com.android.systemui.statusbar.pipeline.satellite.shared.model.SatelliteConnectionState
import com.android.systemui.statusbar.pipeline.satellite.ui.model.SatelliteIconModel
@@ -71,22 +74,34 @@
@Application scope: CoroutineScope,
airplaneModeRepository: AirplaneModeRepository,
@DeviceBasedSatelliteInputLog logBuffer: LogBuffer,
+ @DeviceBasedSatelliteTableLog tableLog: TableLogBuffer,
) : DeviceBasedSatelliteViewModel {
private val shouldShowIcon: Flow<Boolean> =
- interactor.areAllConnectionsOutOfService.flatMapLatest { allOos ->
- if (!allOos) {
- flowOf(false)
- } else {
- combine(
- interactor.isSatelliteAllowed,
- interactor.isSatelliteProvisioned,
- interactor.isWifiActive,
- airplaneModeRepository.isAirplaneMode
- ) { isSatelliteAllowed, isSatelliteProvisioned, isWifiActive, isAirplaneMode ->
- isSatelliteAllowed && isSatelliteProvisioned && !isWifiActive && !isAirplaneMode
+ interactor.areAllConnectionsOutOfService
+ .flatMapLatest { allOos ->
+ if (!allOos) {
+ flowOf(false)
+ } else {
+ combine(
+ interactor.isSatelliteAllowed,
+ interactor.isSatelliteProvisioned,
+ interactor.isWifiActive,
+ airplaneModeRepository.isAirplaneMode
+ ) { isSatelliteAllowed, isSatelliteProvisioned, isWifiActive, isAirplaneMode ->
+ isSatelliteAllowed &&
+ isSatelliteProvisioned &&
+ !isWifiActive &&
+ !isAirplaneMode
+ }
}
}
- }
+ .distinctUntilChanged()
+ .logDiffsForTable(
+ tableLog,
+ columnPrefix = "vm",
+ columnName = COL_VISIBLE_CONDITION,
+ initialValue = false,
+ )
// This adds a 10 seconds delay before showing the icon
private val shouldActuallyShowIcon: StateFlow<Boolean> =
@@ -106,6 +121,13 @@
flowOf(false)
}
}
+ .distinctUntilChanged()
+ .logDiffsForTable(
+ tableLog,
+ columnPrefix = "vm",
+ columnName = COL_VISIBLE,
+ initialValue = false,
+ )
.stateIn(scope, SharingStarted.WhileSubscribed(), false)
override val icon: StateFlow<Icon?> =
@@ -163,5 +185,8 @@
companion object {
private const val TAG = "DeviceBasedSatelliteViewModel"
private val DELAY_DURATION = 10.seconds
+
+ const val COL_VISIBLE_CONDITION = "visCondition"
+ const val COL_VISIBLE = "visible"
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt
index cd0390e..dbb77d5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt
@@ -70,6 +70,7 @@
wifiInteractor,
testScope.backgroundScope,
FakeLogBuffer.Factory.create(),
+ mock(),
)
}
@@ -113,6 +114,7 @@
wifiInteractor,
testScope.backgroundScope,
FakeLogBuffer.Factory.create(),
+ mock(),
)
val latest by collectLastValue(underTest.isSatelliteAllowed)
@@ -161,6 +163,7 @@
wifiInteractor,
testScope.backgroundScope,
FakeLogBuffer.Factory.create(),
+ mock(),
)
val latest by collectLastValue(underTest.connectionState)
@@ -217,6 +220,7 @@
wifiInteractor,
testScope.backgroundScope,
FakeLogBuffer.Factory.create(),
+ mock(),
)
val latest by collectLastValue(underTest.signalStrength)
@@ -535,6 +539,7 @@
wifiInteractor,
testScope.backgroundScope,
FakeLogBuffer.Factory.create(),
+ mock(),
)
val latest by collectLastValue(underTest.areAllConnectionsOutOfService)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt
index 64b07fc..c3cc33f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt
@@ -33,7 +33,6 @@
import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository
import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractorImpl
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
-import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
import kotlin.time.Duration.Companion.seconds
@@ -44,6 +43,7 @@
import org.junit.Before
import org.junit.runner.RunWith
import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.mock
@SmallTest
@RunWith(AndroidJUnit4::class)
@@ -73,6 +73,7 @@
wifiInteractor,
testScope.backgroundScope,
FakeLogBuffer.Factory.create(),
+ mock(),
)
underTest =
@@ -82,6 +83,7 @@
testScope.backgroundScope,
airplaneModeRepository,
FakeLogBuffer.Factory.create(),
+ mock(),
)
}