Loading packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModel.kt +1 −1 Original line number Diff line number Diff line Loading @@ -65,7 +65,7 @@ constructor( // [DefaultConnectionModel] private val wifiIconFlow: Flow<InternetTileModel> = wifiInteractor.wifiNetwork.flatMapLatest { val wifiIcon = WifiIcon.fromModel(it, context) val wifiIcon = WifiIcon.fromModel(it, context, showHotspotInfo = true) if (it is WifiNetworkModel.Active && wifiIcon is WifiIcon.Visible) { flowOf( InternetTileModel.Active( Loading packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/model/WifiIcon.kt +54 −16 Original line number Diff line number Diff line Loading @@ -65,8 +65,18 @@ sealed interface WifiIcon : Diffable<WifiIcon> { @VisibleForTesting internal val NO_INTERNET = R.string.data_connection_no_internet /** Mapping from a [WifiNetworkModel] to the appropriate [WifiIcon] */ fun fromModel(model: WifiNetworkModel, context: Context): WifiIcon = /** * Mapping from a [WifiNetworkModel] to the appropriate [WifiIcon]. * * @param showHotspotInfo true if the wifi icon should represent the hotspot device (if it * exists) and false if the wifi icon should only ever show the wifi level and *not* the * hotspot device. */ fun fromModel( model: WifiNetworkModel, context: Context, showHotspotInfo: Boolean, ): WifiIcon = when (model) { is WifiNetworkModel.Unavailable -> Hidden is WifiNetworkModel.Invalid -> Hidden Loading @@ -82,21 +92,49 @@ sealed interface WifiIcon : Diffable<WifiIcon> { ) is WifiNetworkModel.Active -> { val levelDesc = context.getString(WIFI_CONNECTION_STRENGTH[model.level]) when { model.isValidated -> Visible( WifiIcons.WIFI_FULL_ICONS[model.level], ContentDescription.Loaded(levelDesc), ) else -> Visible( WifiIcons.WIFI_NO_INTERNET_ICONS[model.level], val contentDescription = ContentDescription.Loaded( if (model.isValidated) { (levelDesc) } else { "$levelDesc,${context.getString(NO_INTERNET)}" ), } ) Visible(model.toIcon(showHotspotInfo), contentDescription) } } @DrawableRes private fun WifiNetworkModel.Active.toIcon(showHotspotInfo: Boolean): Int { return if (!showHotspotInfo) { this.toBasicIcon() } else { when (this.hotspotDeviceType) { WifiNetworkModel.HotspotDeviceType.NONE -> this.toBasicIcon() WifiNetworkModel.HotspotDeviceType.TABLET -> com.android.settingslib.R.drawable.ic_hotspot_tablet WifiNetworkModel.HotspotDeviceType.LAPTOP -> com.android.settingslib.R.drawable.ic_hotspot_laptop WifiNetworkModel.HotspotDeviceType.WATCH -> com.android.settingslib.R.drawable.ic_hotspot_watch WifiNetworkModel.HotspotDeviceType.AUTO -> com.android.settingslib.R.drawable.ic_hotspot_auto // Use phone as the default drawable WifiNetworkModel.HotspotDeviceType.PHONE, WifiNetworkModel.HotspotDeviceType.UNKNOWN, WifiNetworkModel.HotspotDeviceType.INVALID -> com.android.settingslib.R.drawable.ic_hotspot_phone } } } @DrawableRes private fun WifiNetworkModel.Active.toBasicIcon(): Int { return if (this.isValidated) { WifiIcons.WIFI_FULL_ICONS[this.level] } else { WifiIcons.WIFI_NO_INTERNET_ICONS[this.level] } } } } Loading packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt +2 −6 Original line number Diff line number Diff line Loading @@ -66,11 +66,6 @@ constructor( @Application private val scope: CoroutineScope, wifiConstants: WifiConstants, ) : WifiViewModelCommon { /** Returns the icon to use based on the given network. */ private fun WifiNetworkModel.icon(): WifiIcon { return WifiIcon.fromModel(this, context) } override val wifiIcon: StateFlow<WifiIcon> = combine( interactor.isEnabled, Loading @@ -82,7 +77,8 @@ constructor( return@combine WifiIcon.Hidden } val icon = wifiNetwork.icon() // Don't show any hotspot info in the status bar. val icon = WifiIcon.fromModel(wifiNetwork, context, showHotspotInfo = false) return@combine when { isDefault -> icon Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt +115 −6 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import com.android.systemui.common.shared.model.Text import com.android.systemui.coroutines.collectLastValue import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.qs.tileimpl.QSTileImpl.ResourceIcon import com.android.systemui.statusbar.connectivity.WifiIcons import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository import com.android.systemui.statusbar.pipeline.ethernet.domain.EthernetInteractor import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState Loading @@ -41,7 +42,6 @@ import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepo import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractorImpl import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiScanEntry import com.android.systemui.statusbar.pipeline.wifi.ui.model.WifiIcon import com.android.systemui.util.CarrierConfigTracker import com.android.systemui.util.mockito.mock import com.google.common.truth.Truth.assertThat Loading Loading @@ -144,16 +144,111 @@ class InternetTileViewModelTest : SysuiTestCase() { wifiRepository.setIsWifiDefault(true) wifiRepository.setWifiNetwork(networkModel) // Type is [Visible] since that is the only model that stores a resId val expectedIcon: WifiIcon.Visible = WifiIcon.fromModel(networkModel, context) as WifiIcon.Visible assertThat(latest?.secondaryTitle).isEqualTo("test ssid") assertThat(latest?.secondaryLabel).isNull() assertThat(latest?.icon).isEqualTo(ResourceIcon.get(expectedIcon.icon.res)) assertThat(latest?.icon) .isEqualTo(ResourceIcon.get(WifiIcons.WIFI_NO_INTERNET_ICONS[4])) assertThat(latest?.iconId).isNull() } @Test fun wifiDefaultAndActive_hotspotNone() = testScope.runTest { val latest by collectLastValue(underTest.tileModel) val networkModel = WifiNetworkModel.Active( networkId = 1, level = 4, ssid = "test ssid", hotspotDeviceType = WifiNetworkModel.HotspotDeviceType.NONE, ) connectivityRepository.setWifiConnected() wifiRepository.setIsWifiDefault(true) wifiRepository.setWifiNetwork(networkModel) assertThat(latest?.icon) .isEqualTo(ResourceIcon.get(WifiIcons.WIFI_NO_INTERNET_ICONS[4])) } @Test fun wifiDefaultAndActive_hotspotTablet() = testScope.runTest { val latest by collectLastValue(underTest.tileModel) setWifiNetworkWithHotspot(WifiNetworkModel.HotspotDeviceType.TABLET) assertThat(latest?.icon) .isEqualTo(ResourceIcon.get(com.android.settingslib.R.drawable.ic_hotspot_tablet)) } @Test fun wifiDefaultAndActive_hotspotLaptop() = testScope.runTest { val latest by collectLastValue(underTest.tileModel) setWifiNetworkWithHotspot(WifiNetworkModel.HotspotDeviceType.LAPTOP) assertThat(latest?.icon) .isEqualTo(ResourceIcon.get(com.android.settingslib.R.drawable.ic_hotspot_laptop)) } @Test fun wifiDefaultAndActive_hotspotWatch() = testScope.runTest { val latest by collectLastValue(underTest.tileModel) setWifiNetworkWithHotspot(WifiNetworkModel.HotspotDeviceType.WATCH) assertThat(latest?.icon) .isEqualTo(ResourceIcon.get(com.android.settingslib.R.drawable.ic_hotspot_watch)) } @Test fun wifiDefaultAndActive_hotspotAuto() = testScope.runTest { val latest by collectLastValue(underTest.tileModel) setWifiNetworkWithHotspot(WifiNetworkModel.HotspotDeviceType.AUTO) assertThat(latest?.icon) .isEqualTo(ResourceIcon.get(com.android.settingslib.R.drawable.ic_hotspot_auto)) } @Test fun wifiDefaultAndActive_hotspotPhone() = testScope.runTest { val latest by collectLastValue(underTest.tileModel) setWifiNetworkWithHotspot(WifiNetworkModel.HotspotDeviceType.PHONE) assertThat(latest?.icon) .isEqualTo(ResourceIcon.get(com.android.settingslib.R.drawable.ic_hotspot_phone)) } @Test fun wifiDefaultAndActive_hotspotUnknown() = testScope.runTest { val latest by collectLastValue(underTest.tileModel) setWifiNetworkWithHotspot(WifiNetworkModel.HotspotDeviceType.UNKNOWN) assertThat(latest?.icon) .isEqualTo(ResourceIcon.get(com.android.settingslib.R.drawable.ic_hotspot_phone)) } @Test fun wifiDefaultAndActive_hotspotInvalid() = testScope.runTest { val latest by collectLastValue(underTest.tileModel) setWifiNetworkWithHotspot(WifiNetworkModel.HotspotDeviceType.INVALID) assertThat(latest?.icon) .isEqualTo(ResourceIcon.get(com.android.settingslib.R.drawable.ic_hotspot_phone)) } @Test fun wifiDefaultAndNotActive_noNetworksAvailable() = testScope.runTest { Loading Loading @@ -237,6 +332,20 @@ class InternetTileViewModelTest : SysuiTestCase() { assertThat(latest?.icon).isNull() } private fun setWifiNetworkWithHotspot(hotspot: WifiNetworkModel.HotspotDeviceType) { val networkModel = WifiNetworkModel.Active( networkId = 1, level = 4, ssid = "test ssid", hotspotDeviceType = hotspot, ) connectivityRepository.setWifiConnected() wifiRepository.setIsWifiDefault(true) wifiRepository.setWifiNetwork(networkModel) } companion object { const val SUB_1_ID = 1 } Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt +22 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.statusbar.connectivity.WifiIcons import com.android.systemui.statusbar.phone.StatusBarLocation import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor Loading Loading @@ -116,6 +117,27 @@ class WifiViewModelTest : SysuiTestCase() { assertThat(latestKeyguard).isEqualTo(latestQs) } @Test fun wifiIcon_validHotspot_hotspotIconNotShown() = testScope.runTest { val latest by collectLastValue(underTest.wifiIcon) // Even WHEN the network has a valid hotspot type wifiRepository.setWifiNetwork( WifiNetworkModel.Active( NETWORK_ID, isValidated = true, level = 1, hotspotDeviceType = WifiNetworkModel.HotspotDeviceType.LAPTOP, ) ) // THEN the hotspot icon is not used for the status bar icon, and the typical wifi icon // is used instead assertThat(latest).isInstanceOf(WifiIcon.Visible::class.java) assertThat((latest as WifiIcon.Visible).res).isEqualTo(WifiIcons.WIFI_FULL_ICONS[1]) } @Test fun activity_showActivityConfigFalse_outputsFalse() = testScope.runTest { Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModel.kt +1 −1 Original line number Diff line number Diff line Loading @@ -65,7 +65,7 @@ constructor( // [DefaultConnectionModel] private val wifiIconFlow: Flow<InternetTileModel> = wifiInteractor.wifiNetwork.flatMapLatest { val wifiIcon = WifiIcon.fromModel(it, context) val wifiIcon = WifiIcon.fromModel(it, context, showHotspotInfo = true) if (it is WifiNetworkModel.Active && wifiIcon is WifiIcon.Visible) { flowOf( InternetTileModel.Active( Loading
packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/model/WifiIcon.kt +54 −16 Original line number Diff line number Diff line Loading @@ -65,8 +65,18 @@ sealed interface WifiIcon : Diffable<WifiIcon> { @VisibleForTesting internal val NO_INTERNET = R.string.data_connection_no_internet /** Mapping from a [WifiNetworkModel] to the appropriate [WifiIcon] */ fun fromModel(model: WifiNetworkModel, context: Context): WifiIcon = /** * Mapping from a [WifiNetworkModel] to the appropriate [WifiIcon]. * * @param showHotspotInfo true if the wifi icon should represent the hotspot device (if it * exists) and false if the wifi icon should only ever show the wifi level and *not* the * hotspot device. */ fun fromModel( model: WifiNetworkModel, context: Context, showHotspotInfo: Boolean, ): WifiIcon = when (model) { is WifiNetworkModel.Unavailable -> Hidden is WifiNetworkModel.Invalid -> Hidden Loading @@ -82,21 +92,49 @@ sealed interface WifiIcon : Diffable<WifiIcon> { ) is WifiNetworkModel.Active -> { val levelDesc = context.getString(WIFI_CONNECTION_STRENGTH[model.level]) when { model.isValidated -> Visible( WifiIcons.WIFI_FULL_ICONS[model.level], ContentDescription.Loaded(levelDesc), ) else -> Visible( WifiIcons.WIFI_NO_INTERNET_ICONS[model.level], val contentDescription = ContentDescription.Loaded( if (model.isValidated) { (levelDesc) } else { "$levelDesc,${context.getString(NO_INTERNET)}" ), } ) Visible(model.toIcon(showHotspotInfo), contentDescription) } } @DrawableRes private fun WifiNetworkModel.Active.toIcon(showHotspotInfo: Boolean): Int { return if (!showHotspotInfo) { this.toBasicIcon() } else { when (this.hotspotDeviceType) { WifiNetworkModel.HotspotDeviceType.NONE -> this.toBasicIcon() WifiNetworkModel.HotspotDeviceType.TABLET -> com.android.settingslib.R.drawable.ic_hotspot_tablet WifiNetworkModel.HotspotDeviceType.LAPTOP -> com.android.settingslib.R.drawable.ic_hotspot_laptop WifiNetworkModel.HotspotDeviceType.WATCH -> com.android.settingslib.R.drawable.ic_hotspot_watch WifiNetworkModel.HotspotDeviceType.AUTO -> com.android.settingslib.R.drawable.ic_hotspot_auto // Use phone as the default drawable WifiNetworkModel.HotspotDeviceType.PHONE, WifiNetworkModel.HotspotDeviceType.UNKNOWN, WifiNetworkModel.HotspotDeviceType.INVALID -> com.android.settingslib.R.drawable.ic_hotspot_phone } } } @DrawableRes private fun WifiNetworkModel.Active.toBasicIcon(): Int { return if (this.isValidated) { WifiIcons.WIFI_FULL_ICONS[this.level] } else { WifiIcons.WIFI_NO_INTERNET_ICONS[this.level] } } } } Loading
packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt +2 −6 Original line number Diff line number Diff line Loading @@ -66,11 +66,6 @@ constructor( @Application private val scope: CoroutineScope, wifiConstants: WifiConstants, ) : WifiViewModelCommon { /** Returns the icon to use based on the given network. */ private fun WifiNetworkModel.icon(): WifiIcon { return WifiIcon.fromModel(this, context) } override val wifiIcon: StateFlow<WifiIcon> = combine( interactor.isEnabled, Loading @@ -82,7 +77,8 @@ constructor( return@combine WifiIcon.Hidden } val icon = wifiNetwork.icon() // Don't show any hotspot info in the status bar. val icon = WifiIcon.fromModel(wifiNetwork, context, showHotspotInfo = false) return@combine when { isDefault -> icon Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt +115 −6 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import com.android.systemui.common.shared.model.Text import com.android.systemui.coroutines.collectLastValue import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.qs.tileimpl.QSTileImpl.ResourceIcon import com.android.systemui.statusbar.connectivity.WifiIcons import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository import com.android.systemui.statusbar.pipeline.ethernet.domain.EthernetInteractor import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState Loading @@ -41,7 +42,6 @@ import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepo import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractorImpl import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiScanEntry import com.android.systemui.statusbar.pipeline.wifi.ui.model.WifiIcon import com.android.systemui.util.CarrierConfigTracker import com.android.systemui.util.mockito.mock import com.google.common.truth.Truth.assertThat Loading Loading @@ -144,16 +144,111 @@ class InternetTileViewModelTest : SysuiTestCase() { wifiRepository.setIsWifiDefault(true) wifiRepository.setWifiNetwork(networkModel) // Type is [Visible] since that is the only model that stores a resId val expectedIcon: WifiIcon.Visible = WifiIcon.fromModel(networkModel, context) as WifiIcon.Visible assertThat(latest?.secondaryTitle).isEqualTo("test ssid") assertThat(latest?.secondaryLabel).isNull() assertThat(latest?.icon).isEqualTo(ResourceIcon.get(expectedIcon.icon.res)) assertThat(latest?.icon) .isEqualTo(ResourceIcon.get(WifiIcons.WIFI_NO_INTERNET_ICONS[4])) assertThat(latest?.iconId).isNull() } @Test fun wifiDefaultAndActive_hotspotNone() = testScope.runTest { val latest by collectLastValue(underTest.tileModel) val networkModel = WifiNetworkModel.Active( networkId = 1, level = 4, ssid = "test ssid", hotspotDeviceType = WifiNetworkModel.HotspotDeviceType.NONE, ) connectivityRepository.setWifiConnected() wifiRepository.setIsWifiDefault(true) wifiRepository.setWifiNetwork(networkModel) assertThat(latest?.icon) .isEqualTo(ResourceIcon.get(WifiIcons.WIFI_NO_INTERNET_ICONS[4])) } @Test fun wifiDefaultAndActive_hotspotTablet() = testScope.runTest { val latest by collectLastValue(underTest.tileModel) setWifiNetworkWithHotspot(WifiNetworkModel.HotspotDeviceType.TABLET) assertThat(latest?.icon) .isEqualTo(ResourceIcon.get(com.android.settingslib.R.drawable.ic_hotspot_tablet)) } @Test fun wifiDefaultAndActive_hotspotLaptop() = testScope.runTest { val latest by collectLastValue(underTest.tileModel) setWifiNetworkWithHotspot(WifiNetworkModel.HotspotDeviceType.LAPTOP) assertThat(latest?.icon) .isEqualTo(ResourceIcon.get(com.android.settingslib.R.drawable.ic_hotspot_laptop)) } @Test fun wifiDefaultAndActive_hotspotWatch() = testScope.runTest { val latest by collectLastValue(underTest.tileModel) setWifiNetworkWithHotspot(WifiNetworkModel.HotspotDeviceType.WATCH) assertThat(latest?.icon) .isEqualTo(ResourceIcon.get(com.android.settingslib.R.drawable.ic_hotspot_watch)) } @Test fun wifiDefaultAndActive_hotspotAuto() = testScope.runTest { val latest by collectLastValue(underTest.tileModel) setWifiNetworkWithHotspot(WifiNetworkModel.HotspotDeviceType.AUTO) assertThat(latest?.icon) .isEqualTo(ResourceIcon.get(com.android.settingslib.R.drawable.ic_hotspot_auto)) } @Test fun wifiDefaultAndActive_hotspotPhone() = testScope.runTest { val latest by collectLastValue(underTest.tileModel) setWifiNetworkWithHotspot(WifiNetworkModel.HotspotDeviceType.PHONE) assertThat(latest?.icon) .isEqualTo(ResourceIcon.get(com.android.settingslib.R.drawable.ic_hotspot_phone)) } @Test fun wifiDefaultAndActive_hotspotUnknown() = testScope.runTest { val latest by collectLastValue(underTest.tileModel) setWifiNetworkWithHotspot(WifiNetworkModel.HotspotDeviceType.UNKNOWN) assertThat(latest?.icon) .isEqualTo(ResourceIcon.get(com.android.settingslib.R.drawable.ic_hotspot_phone)) } @Test fun wifiDefaultAndActive_hotspotInvalid() = testScope.runTest { val latest by collectLastValue(underTest.tileModel) setWifiNetworkWithHotspot(WifiNetworkModel.HotspotDeviceType.INVALID) assertThat(latest?.icon) .isEqualTo(ResourceIcon.get(com.android.settingslib.R.drawable.ic_hotspot_phone)) } @Test fun wifiDefaultAndNotActive_noNetworksAvailable() = testScope.runTest { Loading Loading @@ -237,6 +332,20 @@ class InternetTileViewModelTest : SysuiTestCase() { assertThat(latest?.icon).isNull() } private fun setWifiNetworkWithHotspot(hotspot: WifiNetworkModel.HotspotDeviceType) { val networkModel = WifiNetworkModel.Active( networkId = 1, level = 4, ssid = "test ssid", hotspotDeviceType = hotspot, ) connectivityRepository.setWifiConnected() wifiRepository.setIsWifiDefault(true) wifiRepository.setWifiNetwork(networkModel) } companion object { const val SUB_1_ID = 1 } Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt +22 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import com.android.systemui.RoboPilotTest import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.statusbar.connectivity.WifiIcons import com.android.systemui.statusbar.phone.StatusBarLocation import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor Loading Loading @@ -116,6 +117,27 @@ class WifiViewModelTest : SysuiTestCase() { assertThat(latestKeyguard).isEqualTo(latestQs) } @Test fun wifiIcon_validHotspot_hotspotIconNotShown() = testScope.runTest { val latest by collectLastValue(underTest.wifiIcon) // Even WHEN the network has a valid hotspot type wifiRepository.setWifiNetwork( WifiNetworkModel.Active( NETWORK_ID, isValidated = true, level = 1, hotspotDeviceType = WifiNetworkModel.HotspotDeviceType.LAPTOP, ) ) // THEN the hotspot icon is not used for the status bar icon, and the typical wifi icon // is used instead assertThat(latest).isInstanceOf(WifiIcon.Visible::class.java) assertThat((latest as WifiIcon.Visible).res).isEqualTo(WifiIcons.WIFI_FULL_ICONS[1]) } @Test fun activity_showActivityConfigFalse_outputsFalse() = testScope.runTest { Loading