diff options
5 files changed, 194 insertions, 29 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModel.kt index 120ba4eba094..b6f167704cd7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModel.kt @@ -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( diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/model/WifiIcon.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/model/WifiIcon.kt index 8156500528a7..668c5b3c4b78 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/model/WifiIcon.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/model/WifiIcon.kt @@ -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 @@ -82,22 +92,50 @@ 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], - ContentDescription.Loaded( - "$levelDesc,${context.getString(NO_INTERNET)}" - ), - ) - } + 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] + } + } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt index 27ac7b9be6e6..d099c8eb1c9d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt @@ -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, @@ -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 diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt index 8150a313abe6..6624ec2ece77 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt @@ -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 @@ -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 @@ -144,17 +144,112 @@ 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 { val latest by collectLastValue(underTest.tileModel) @@ -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 } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt index 5aacc6626eb7..a520f6c109cc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt @@ -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 @@ -117,6 +118,27 @@ class WifiViewModelTest : SysuiTestCase() { } @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 { whenever(connectivityConstants.shouldShowActivityConfig).thenReturn(false) |