[SB][Wifi] Display hotspot device type in QS tile.
Bug: 265342892
Test: `adb shell am broadcast -a com.android.systemui.demo -e command
network -e wifi show -e hotspot {tablet/laptop/watch/etc}` -> verify QS
tile displays an icon matching the hotspot device type. Verify status
bar does *not* display the hotspot device type.
Test: atest InternetTileViewModelTest WifiViewModelTest
Change-Id: I6abdd2c29a62bd67890704c02eb4107fc12817af
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 120ba4e..b6f1677 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 @@
// [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 8156500..668c5b3 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 @@
@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 @@
)
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 27ac7b9..d099c8e 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 @@
@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 @@
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 8150a31..6624ec2 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.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.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 @@
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 @@
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 5aacc66..a520f6c 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.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 @@
}
@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)