summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Caitlin Shkuratov <caitlinshk@google.com> 2023-07-28 14:52:24 +0000
committer Caitlin Shkuratov <caitlinshk@google.com> 2023-08-07 15:12:56 +0000
commit1a3a5b5361635e03bca5f959eac6c7482fa6e355 (patch)
tree82f15c92af7d162401834068c63d4b64b6fb13c2
parent98eb78a66ffafbea9d70ad5986b4e7299092b1db (diff)
[Status Bar] Wifi: Add support for hotspot device types to repo.
This is needed for instant tether. The device type isn't hooked up to the UI yet because the device type icon should only be displayed in Quick Settings Internet Tile (not the status bar) and the Internet Tile isn't yet hooked in to the new pipeline. Bug: 265342892 Bug: 293585143 Test: `adb shell am broadcast -a com.android.systemui.demo -e command network -e wifi show -e hotspot {tablet/laptop/watch/etc}` -> verify demo repo has hotspot info Test: atest WifiRepositoryViaTrackerLibTest WifiNetworkModelTest Change-Id: Ia121ea81717333addd6cf498100c34d3fcae2297
-rw-r--r--packages/SystemUI/src/com/android/systemui/flags/Flags.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoModeWifiDataSource.kt17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoWifiRepository.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/model/FakeWifiEventModel.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryViaTrackerLib.kt17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/model/WifiNetworkModel.kt51
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt20
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryViaTrackerLibTest.kt168
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/shared/model/WifiNetworkModelTest.kt9
11 files changed, 287 insertions, 14 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index 99e33ea8e619..27541e809902 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -374,6 +374,9 @@ object Flags {
@JvmField val INCOMPATIBLE_CHARGING_BATTERY_ICON =
unreleasedFlag(614, "incompatible_charging_battery_icon")
+ // TODO(b/293585143): Tracking Bug
+ val INSTANT_TETHER = unreleasedFlag(615, "instant_tether")
+
// 700 - dialer/calls
// TODO(b/254512734): Tracking Bug
val ONGOING_CALL_STATUS_BAR_CHIP = releasedFlag(700, "ongoing_call_status_bar_chip")
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoModeWifiDataSource.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoModeWifiDataSource.kt
index 7d2501ca0e79..ab9b516b837f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoModeWifiDataSource.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoModeWifiDataSource.kt
@@ -24,6 +24,7 @@ import com.android.systemui.demomode.DemoMode.COMMAND_NETWORK
import com.android.systemui.demomode.DemoModeController
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.model.FakeWifiEventModel
+import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted
@@ -56,12 +57,14 @@ constructor(
val activity = getString("activity").toActivity()
val ssid = getString("ssid")
val validated = getString("fully").toBoolean()
+ val hotspotDeviceType = getString("hotspot").toHotspotDeviceType()
return FakeWifiEventModel.Wifi(
level = level,
activity = activity,
ssid = ssid,
validated = validated,
+ hotspotDeviceType,
)
}
@@ -82,6 +85,20 @@ constructor(
else -> WifiManager.TrafficStateCallback.DATA_ACTIVITY_NONE
}
+ private fun String?.toHotspotDeviceType(): WifiNetworkModel.HotspotDeviceType {
+ return when (this) {
+ null,
+ "none" -> WifiNetworkModel.HotspotDeviceType.NONE
+ "unknown" -> WifiNetworkModel.HotspotDeviceType.UNKNOWN
+ "phone" -> WifiNetworkModel.HotspotDeviceType.PHONE
+ "tablet" -> WifiNetworkModel.HotspotDeviceType.TABLET
+ "laptop" -> WifiNetworkModel.HotspotDeviceType.LAPTOP
+ "watch" -> WifiNetworkModel.HotspotDeviceType.WATCH
+ "auto" -> WifiNetworkModel.HotspotDeviceType.AUTO
+ else -> WifiNetworkModel.HotspotDeviceType.INVALID
+ }
+ }
+
companion object {
const val DEFAULT_CARRIER_MERGED_SUB_ID = 10
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoWifiRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoWifiRepository.kt
index a57be665f105..99b680056d7f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoWifiRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/DemoWifiRepository.kt
@@ -97,6 +97,7 @@ constructor(
isValidated = validated ?: true,
level = level ?: 0,
ssid = ssid ?: DEMO_NET_SSID,
+ hotspotDeviceType = hotspotDeviceType,
// These fields below aren't supported in demo mode, since they aren't needed to satisfy
// the interface.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/model/FakeWifiEventModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/model/FakeWifiEventModel.kt
index f5035cbc0215..b2e843e283f7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/model/FakeWifiEventModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/demo/model/FakeWifiEventModel.kt
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.model
import android.telephony.Annotation
+import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
/**
* Model for demo wifi commands, ported from [NetworkControllerImpl]
@@ -29,6 +30,8 @@ sealed interface FakeWifiEventModel {
@Annotation.DataActivityType val activity: Int,
val ssid: String?,
val validated: Boolean?,
+ val hotspotDeviceType: WifiNetworkModel.HotspotDeviceType =
+ WifiNetworkModel.HotspotDeviceType.NONE,
) : FakeWifiEventModel
data class CarrierMerged(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt
index 9944c00c6ee7..946c571998ac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt
@@ -261,6 +261,8 @@ constructor(
isValidated = networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED),
level = wifiManager.calculateSignalLevel(wifiInfo.rssi),
wifiInfo.ssid,
+ // This repository doesn't support any hotspot information.
+ WifiNetworkModel.HotspotDeviceType.NONE,
wifiInfo.isPasspointAp,
wifiInfo.isOsuAp,
wifiInfo.passpointProviderFriendlyName
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryViaTrackerLib.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryViaTrackerLib.kt
index 6f1ac34de9d3..43f8bc6ef3f8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryViaTrackerLib.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryViaTrackerLib.kt
@@ -23,6 +23,8 @@ import androidx.lifecycle.LifecycleRegistry
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.core.LogLevel
import com.android.systemui.log.table.TableLogBuffer
@@ -37,6 +39,8 @@ import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiReposito
import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.WifiRepositoryImpl.Companion.WIFI_NETWORK_DEFAULT
import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.WifiRepositoryImpl.Companion.WIFI_STATE_DEFAULT
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
+import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel.Inactive.toHotspotDeviceType
+import com.android.wifitrackerlib.HotspotNetworkEntry
import com.android.wifitrackerlib.MergedCarrierEntry
import com.android.wifitrackerlib.WifiEntry
import com.android.wifitrackerlib.WifiPickerTracker
@@ -61,6 +65,7 @@ import kotlinx.coroutines.flow.stateIn
class WifiRepositoryViaTrackerLib
@Inject
constructor(
+ featureFlags: FeatureFlags,
@Application private val scope: CoroutineScope,
@Main private val mainExecutor: Executor,
private val wifiPickerTrackerFactory: WifiPickerTrackerFactory,
@@ -74,6 +79,8 @@ constructor(
mainExecutor.execute { it.currentState = Lifecycle.State.CREATED }
}
+ private val isInstantTetherEnabled = featureFlags.isEnabled(Flags.INSTANT_TETHER)
+
private var wifiPickerTracker: WifiPickerTracker? = null
private val wifiPickerTrackerInfo: StateFlow<WifiPickerTrackerInfo> = run {
@@ -181,11 +188,19 @@ constructor(
numberOfLevels = wifiManager.maxSignalLevel + 1,
)
} else {
+ val hotspotDeviceType =
+ if (isInstantTetherEnabled && this is HotspotNetworkEntry) {
+ this.deviceType.toHotspotDeviceType()
+ } else {
+ WifiNetworkModel.HotspotDeviceType.NONE
+ }
+
WifiNetworkModel.Active(
networkId = NETWORK_ID,
isValidated = this.hasInternetAccess(),
level = this.level,
ssid = this.title,
+ hotspotDeviceType = hotspotDeviceType,
// With WifiTrackerLib, [WifiEntry.title] will appropriately fetch the SSID for
// typical wifi networks *and* passpoint/OSU APs. So, the AP-specific values can
// always be false/null in this repository.
@@ -259,6 +274,7 @@ constructor(
class Factory
@Inject
constructor(
+ private val featureFlags: FeatureFlags,
@Application private val scope: CoroutineScope,
@Main private val mainExecutor: Executor,
private val wifiPickerTrackerFactory: WifiPickerTrackerFactory,
@@ -267,6 +283,7 @@ constructor(
) {
fun create(wifiManager: WifiManager): WifiRepositoryViaTrackerLib {
return WifiRepositoryViaTrackerLib(
+ featureFlags,
scope,
mainExecutor,
wifiPickerTrackerFactory,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/model/WifiNetworkModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/model/WifiNetworkModel.kt
index 4b33c88cea30..c11640a31b82 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/model/WifiNetworkModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/model/WifiNetworkModel.kt
@@ -17,11 +17,13 @@
package com.android.systemui.statusbar.pipeline.wifi.shared.model
import android.net.wifi.WifiManager.UNKNOWN_SSID
+import android.net.wifi.sharedconnectivity.app.NetworkProviderInfo
import android.telephony.SubscriptionManager
import androidx.annotation.VisibleForTesting
import com.android.systemui.log.table.Diffable
import com.android.systemui.log.table.TableRowLogger
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
+import com.android.wifitrackerlib.HotspotNetworkEntry.DeviceType
/** Provides information about the current wifi network. */
sealed class WifiNetworkModel : Diffable<WifiNetworkModel> {
@@ -52,6 +54,7 @@ sealed class WifiNetworkModel : Diffable<WifiNetworkModel> {
row.logChange(COL_LEVEL, LEVEL_DEFAULT)
row.logChange(COL_NUM_LEVELS, NUM_LEVELS_DEFAULT)
row.logChange(COL_SSID, null)
+ row.logChange(COL_HOTSPOT, null)
row.logChange(COL_PASSPOINT_ACCESS_POINT, false)
row.logChange(COL_ONLINE_SIGN_UP, false)
row.logChange(COL_PASSPOINT_NAME, null)
@@ -83,6 +86,7 @@ sealed class WifiNetworkModel : Diffable<WifiNetworkModel> {
row.logChange(COL_LEVEL, LEVEL_DEFAULT)
row.logChange(COL_NUM_LEVELS, NUM_LEVELS_DEFAULT)
row.logChange(COL_SSID, null)
+ row.logChange(COL_HOTSPOT, null)
row.logChange(COL_PASSPOINT_ACCESS_POINT, false)
row.logChange(COL_ONLINE_SIGN_UP, false)
row.logChange(COL_PASSPOINT_NAME, null)
@@ -110,6 +114,7 @@ sealed class WifiNetworkModel : Diffable<WifiNetworkModel> {
row.logChange(COL_LEVEL, LEVEL_DEFAULT)
row.logChange(COL_NUM_LEVELS, NUM_LEVELS_DEFAULT)
row.logChange(COL_SSID, null)
+ row.logChange(COL_HOTSPOT, null)
row.logChange(COL_PASSPOINT_ACCESS_POINT, false)
row.logChange(COL_ONLINE_SIGN_UP, false)
row.logChange(COL_PASSPOINT_NAME, null)
@@ -184,6 +189,7 @@ sealed class WifiNetworkModel : Diffable<WifiNetworkModel> {
row.logChange(COL_LEVEL, level)
row.logChange(COL_NUM_LEVELS, numberOfLevels)
row.logChange(COL_SSID, null)
+ row.logChange(COL_HOTSPOT, null)
row.logChange(COL_PASSPOINT_ACCESS_POINT, false)
row.logChange(COL_ONLINE_SIGN_UP, false)
row.logChange(COL_PASSPOINT_NAME, null)
@@ -209,6 +215,12 @@ sealed class WifiNetworkModel : Diffable<WifiNetworkModel> {
/** See [android.net.wifi.WifiInfo.ssid]. */
val ssid: String? = null,
+ /**
+ * The type of device providing a hotspot connection, or [HotspotDeviceType.NONE] if this
+ * isn't a hotspot connection.
+ */
+ val hotspotDeviceType: HotspotDeviceType = WifiNetworkModel.HotspotDeviceType.NONE,
+
/** See [android.net.wifi.WifiInfo.isPasspointAp]. */
val isPasspointAccessPoint: Boolean = false,
@@ -247,6 +259,9 @@ sealed class WifiNetworkModel : Diffable<WifiNetworkModel> {
if (prevVal.ssid != ssid) {
row.logChange(COL_SSID, ssid)
}
+ if (prevVal.hotspotDeviceType != hotspotDeviceType) {
+ row.logChange(COL_HOTSPOT, hotspotDeviceType.name)
+ }
// TODO(b/238425913): The passpoint-related values are frequently never used, so it
// would be great to not log them when they're not used.
@@ -272,6 +287,7 @@ sealed class WifiNetworkModel : Diffable<WifiNetworkModel> {
row.logChange(COL_LEVEL, level)
row.logChange(COL_NUM_LEVELS, null)
row.logChange(COL_SSID, ssid)
+ row.logChange(COL_HOTSPOT, hotspotDeviceType.name)
row.logChange(COL_PASSPOINT_ACCESS_POINT, isPasspointAccessPoint)
row.logChange(COL_ONLINE_SIGN_UP, isOnlineSignUpForPasspointAccessPoint)
row.logChange(COL_PASSPOINT_NAME, passpointProviderFriendlyName)
@@ -305,6 +321,40 @@ sealed class WifiNetworkModel : Diffable<WifiNetworkModel> {
companion object {
@VisibleForTesting internal const val MIN_VALID_LEVEL = 0
}
+
+ /**
+ * Enum for the type of device providing the hotspot connection, or [NONE] if this connection
+ * isn't a hotspot.
+ */
+ enum class HotspotDeviceType {
+ /* This wifi connection isn't a hotspot. */
+ NONE,
+ /** The device type for this hotspot is unknown. */
+ UNKNOWN,
+ PHONE,
+ TABLET,
+ LAPTOP,
+ WATCH,
+ AUTO,
+ /** The device type sent for this hotspot is invalid to SysUI. */
+ INVALID,
+ }
+
+ /**
+ * Converts a device type from [com.android.wifitrackerlib.HotspotNetworkEntry.deviceType] to
+ * our internal representation.
+ */
+ fun @receiver:DeviceType Int.toHotspotDeviceType(): HotspotDeviceType {
+ return when (this) {
+ NetworkProviderInfo.DEVICE_TYPE_UNKNOWN -> HotspotDeviceType.UNKNOWN
+ NetworkProviderInfo.DEVICE_TYPE_PHONE -> HotspotDeviceType.PHONE
+ NetworkProviderInfo.DEVICE_TYPE_TABLET -> HotspotDeviceType.TABLET
+ NetworkProviderInfo.DEVICE_TYPE_LAPTOP -> HotspotDeviceType.LAPTOP
+ NetworkProviderInfo.DEVICE_TYPE_WATCH -> HotspotDeviceType.WATCH
+ NetworkProviderInfo.DEVICE_TYPE_AUTO -> HotspotDeviceType.AUTO
+ else -> HotspotDeviceType.INVALID
+ }
+ }
}
const val TYPE_CARRIER_MERGED = "CarrierMerged"
@@ -319,6 +369,7 @@ const val COL_VALIDATED = "isValidated"
const val COL_LEVEL = "level"
const val COL_NUM_LEVELS = "maxLevel"
const val COL_SSID = "ssid"
+const val COL_HOTSPOT = "hotspot"
const val COL_PASSPOINT_ACCESS_POINT = "isPasspointAccessPoint"
const val COL_ONLINE_SIGN_UP = "isOnlineSignUpForPasspointAccessPoint"
const val COL_PASSPOINT_NAME = "passpointProviderFriendlyName"
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java
index e7d420bcb32b..9016220b40cf 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java
@@ -419,7 +419,15 @@ public class CarrierTextManagerTest extends SysuiTestCase {
assertFalse(mWifiRepository.isWifiConnectedWithValidSsid());
mWifiRepository.setWifiNetwork(
- new WifiNetworkModel.Active(0, false, 0, "", false, false, null));
+ new WifiNetworkModel.Active(
+ /* networkId= */ 0,
+ /* isValidated= */ false,
+ /* level= */ 0,
+ /* ssid= */ "",
+ /* hotspotDeviceType= */ WifiNetworkModel.HotspotDeviceType.NONE,
+ /* isPasspointAccessPoint= */ false,
+ /* isOnlineSignUpForPasspointAccessPoint= */ false,
+ /* passpointProviderFriendlyName= */ null));
assertTrue(mWifiRepository.isWifiConnectedWithValidSsid());
mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt
index fef042be65a8..2dbeb7aa7e90 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt
@@ -489,6 +489,26 @@ class WifiRepositoryImplTest : SysuiTestCase() {
}
@Test
+ fun wifiNetwork_neverHasHotspot() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.wifiNetwork)
+
+ val wifiInfo =
+ mock<WifiInfo>().apply {
+ whenever(this.ssid).thenReturn(SSID)
+ whenever(this.isPrimary).thenReturn(true)
+ }
+ val network = mock<Network>().apply { whenever(this.getNetId()).thenReturn(NETWORK_ID) }
+
+ getNetworkCallback()
+ .onCapabilitiesChanged(network, createWifiNetworkCapabilities(wifiInfo))
+
+ assertThat(latest is WifiNetworkModel.Active).isTrue()
+ assertThat((latest as WifiNetworkModel.Active).hotspotDeviceType)
+ .isEqualTo(WifiNetworkModel.HotspotDeviceType.NONE)
+ }
+
+ @Test
fun wifiNetwork_isCarrierMerged_flowHasCarrierMerged() =
testScope.runTest {
val latest by collectLastValue(underTest.wifiNetwork)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryViaTrackerLibTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryViaTrackerLibTest.kt
index bd20e415ab37..7a78ae368fa9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryViaTrackerLibTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryViaTrackerLibTest.kt
@@ -18,10 +18,13 @@ package com.android.systemui.statusbar.pipeline.wifi.data.repository.prod
import android.net.wifi.WifiManager
import android.net.wifi.WifiManager.UNKNOWN_SSID
+import android.net.wifi.sharedconnectivity.app.NetworkProviderInfo
import android.testing.TestableLooper
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.table.TableLogBuffer
import com.android.systemui.statusbar.connectivity.WifiPickerTrackerFactory
@@ -35,6 +38,8 @@ import com.android.systemui.util.mockito.capture
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.time.FakeSystemClock
+import com.android.wifitrackerlib.HotspotNetworkEntry
+import com.android.wifitrackerlib.HotspotNetworkEntry.DeviceType
import com.android.wifitrackerlib.MergedCarrierEntry
import com.android.wifitrackerlib.WifiEntry
import com.android.wifitrackerlib.WifiPickerTracker
@@ -59,10 +64,25 @@ import org.mockito.Mockito.verify
@TestableLooper.RunWithLooper(setAsMainLooper = true)
class WifiRepositoryViaTrackerLibTest : SysuiTestCase() {
- private lateinit var underTest: WifiRepositoryViaTrackerLib
+ // Using lazy means that the class will only be constructed once it's fetched. Because the
+ // repository internally sets some values on construction, we need to set up some test
+ // parameters (like feature flags) *before* construction. Using lazy allows us to do that setup
+ // inside each test case without needing to manually recreate the repository.
+ private val underTest: WifiRepositoryViaTrackerLib by lazy {
+ WifiRepositoryViaTrackerLib(
+ featureFlags,
+ testScope.backgroundScope,
+ executor,
+ wifiPickerTrackerFactory,
+ wifiManager,
+ logger,
+ tableLogger,
+ )
+ }
private val executor = FakeExecutor(FakeSystemClock())
private val logger = LogBuffer("name", maxSize = 100, logcatEchoTracker = mock())
+ private val featureFlags = FakeFeatureFlags()
private val tableLogger = mock<TableLogBuffer>()
private val wifiManager =
mock<WifiManager>().apply { whenever(this.maxSignalLevel).thenReturn(10) }
@@ -76,9 +96,9 @@ class WifiRepositoryViaTrackerLibTest : SysuiTestCase() {
@Before
fun setUp() {
+ featureFlags.set(Flags.INSTANT_TETHER, false)
whenever(wifiPickerTrackerFactory.create(any(), capture(callbackCaptor)))
.thenReturn(wifiPickerTracker)
- underTest = createRepo()
}
@Test
@@ -273,6 +293,136 @@ class WifiRepositoryViaTrackerLibTest : SysuiTestCase() {
}
@Test
+ fun wifiNetwork_notHotspot_none() =
+ testScope.runTest {
+ featureFlags.set(Flags.INSTANT_TETHER, true)
+ val latest by collectLastValue(underTest.wifiNetwork)
+
+ val wifiEntry =
+ mock<WifiEntry>().apply { whenever(this.isPrimaryNetwork).thenReturn(true) }
+ whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
+ getCallback().onWifiEntriesChanged()
+
+ assertThat((latest as WifiNetworkModel.Active).hotspotDeviceType)
+ .isEqualTo(WifiNetworkModel.HotspotDeviceType.NONE)
+ }
+
+ @Test
+ fun wifiNetwork_hotspot_unknown() =
+ testScope.runTest {
+ featureFlags.set(Flags.INSTANT_TETHER, true)
+ val latest by collectLastValue(underTest.wifiNetwork)
+
+ val wifiEntry = createHotspotWithType(NetworkProviderInfo.DEVICE_TYPE_UNKNOWN)
+ whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
+ getCallback().onWifiEntriesChanged()
+
+ assertThat((latest as WifiNetworkModel.Active).hotspotDeviceType)
+ .isEqualTo(WifiNetworkModel.HotspotDeviceType.UNKNOWN)
+ }
+
+ @Test
+ fun wifiNetwork_hotspot_phone() =
+ testScope.runTest {
+ featureFlags.set(Flags.INSTANT_TETHER, true)
+ val latest by collectLastValue(underTest.wifiNetwork)
+
+ val wifiEntry = createHotspotWithType(NetworkProviderInfo.DEVICE_TYPE_PHONE)
+ whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
+ getCallback().onWifiEntriesChanged()
+
+ assertThat((latest as WifiNetworkModel.Active).hotspotDeviceType)
+ .isEqualTo(WifiNetworkModel.HotspotDeviceType.PHONE)
+ }
+
+ @Test
+ fun wifiNetwork_hotspot_tablet() =
+ testScope.runTest {
+ featureFlags.set(Flags.INSTANT_TETHER, true)
+ val latest by collectLastValue(underTest.wifiNetwork)
+
+ val wifiEntry = createHotspotWithType(NetworkProviderInfo.DEVICE_TYPE_TABLET)
+ whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
+ getCallback().onWifiEntriesChanged()
+
+ assertThat((latest as WifiNetworkModel.Active).hotspotDeviceType)
+ .isEqualTo(WifiNetworkModel.HotspotDeviceType.TABLET)
+ }
+
+ @Test
+ fun wifiNetwork_hotspot_laptop() =
+ testScope.runTest {
+ featureFlags.set(Flags.INSTANT_TETHER, true)
+ val latest by collectLastValue(underTest.wifiNetwork)
+
+ val wifiEntry = createHotspotWithType(NetworkProviderInfo.DEVICE_TYPE_LAPTOP)
+ whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
+ getCallback().onWifiEntriesChanged()
+
+ assertThat((latest as WifiNetworkModel.Active).hotspotDeviceType)
+ .isEqualTo(WifiNetworkModel.HotspotDeviceType.LAPTOP)
+ }
+
+ @Test
+ fun wifiNetwork_hotspot_watch() =
+ testScope.runTest {
+ featureFlags.set(Flags.INSTANT_TETHER, true)
+ val latest by collectLastValue(underTest.wifiNetwork)
+
+ val wifiEntry = createHotspotWithType(NetworkProviderInfo.DEVICE_TYPE_WATCH)
+ whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
+ getCallback().onWifiEntriesChanged()
+
+ assertThat((latest as WifiNetworkModel.Active).hotspotDeviceType)
+ .isEqualTo(WifiNetworkModel.HotspotDeviceType.WATCH)
+ }
+
+ @Test
+ fun wifiNetwork_hotspot_auto() =
+ testScope.runTest {
+ featureFlags.set(Flags.INSTANT_TETHER, true)
+ val latest by collectLastValue(underTest.wifiNetwork)
+
+ val wifiEntry = createHotspotWithType(NetworkProviderInfo.DEVICE_TYPE_AUTO)
+ whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
+ getCallback().onWifiEntriesChanged()
+
+ assertThat((latest as WifiNetworkModel.Active).hotspotDeviceType)
+ .isEqualTo(WifiNetworkModel.HotspotDeviceType.AUTO)
+ }
+
+ @Test
+ fun wifiNetwork_hotspot_invalid() =
+ testScope.runTest {
+ featureFlags.set(Flags.INSTANT_TETHER, true)
+ val latest by collectLastValue(underTest.wifiNetwork)
+
+ val wifiEntry = createHotspotWithType(1234)
+ whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
+ getCallback().onWifiEntriesChanged()
+
+ assertThat((latest as WifiNetworkModel.Active).hotspotDeviceType)
+ .isEqualTo(WifiNetworkModel.HotspotDeviceType.INVALID)
+ }
+
+ @Test
+ fun wifiNetwork_hotspot_flagOff_valueNotUsed() =
+ testScope.runTest {
+ // WHEN the flag is off
+ featureFlags.set(Flags.INSTANT_TETHER, false)
+
+ val latest by collectLastValue(underTest.wifiNetwork)
+
+ val wifiEntry = createHotspotWithType(NetworkProviderInfo.DEVICE_TYPE_WATCH)
+ whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
+ getCallback().onWifiEntriesChanged()
+
+ // THEN NONE is always used, even if the wifi entry does have a hotspot device type
+ assertThat((latest as WifiNetworkModel.Active).hotspotDeviceType)
+ .isEqualTo(WifiNetworkModel.HotspotDeviceType.NONE)
+ }
+
+ @Test
fun wifiNetwork_isCarrierMerged_flowHasCarrierMerged() =
testScope.runTest {
val latest by collectLastValue(underTest.wifiNetwork)
@@ -726,15 +876,11 @@ class WifiRepositoryViaTrackerLibTest : SysuiTestCase() {
return callbackCaptor.value!!
}
- private fun createRepo(): WifiRepositoryViaTrackerLib {
- return WifiRepositoryViaTrackerLib(
- testScope.backgroundScope,
- executor,
- wifiPickerTrackerFactory,
- wifiManager,
- logger,
- tableLogger,
- )
+ private fun createHotspotWithType(@DeviceType type: Int): HotspotNetworkEntry {
+ return mock<HotspotNetworkEntry>().apply {
+ whenever(this.isPrimaryNetwork).thenReturn(true)
+ whenever(this.deviceType).thenReturn(type)
+ }
}
private companion object {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/shared/model/WifiNetworkModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/shared/model/WifiNetworkModelTest.kt
index 4e0c309512e8..ba035bec340c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/shared/model/WifiNetworkModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/shared/model/WifiNetworkModelTest.kt
@@ -136,7 +136,8 @@ class WifiNetworkModelTest : SysuiTestCase() {
networkId = 5,
isValidated = true,
level = 3,
- ssid = "Test SSID"
+ ssid = "Test SSID",
+ hotspotDeviceType = WifiNetworkModel.HotspotDeviceType.LAPTOP,
)
activeNetwork.logDiffs(prevVal = WifiNetworkModel.Inactive, logger)
@@ -146,6 +147,7 @@ class WifiNetworkModelTest : SysuiTestCase() {
assertThat(logger.changes).contains(Pair(COL_VALIDATED, "true"))
assertThat(logger.changes).contains(Pair(COL_LEVEL, "3"))
assertThat(logger.changes).contains(Pair(COL_SSID, "Test SSID"))
+ assertThat(logger.changes).contains(Pair(COL_HOTSPOT, "LAPTOP"))
}
@Test
fun logDiffs_activeToInactive_resetsAllActiveFields() {
@@ -165,6 +167,7 @@ class WifiNetworkModelTest : SysuiTestCase() {
assertThat(logger.changes).contains(Pair(COL_VALIDATED, "false"))
assertThat(logger.changes).contains(Pair(COL_LEVEL, LEVEL_DEFAULT.toString()))
assertThat(logger.changes).contains(Pair(COL_SSID, "null"))
+ assertThat(logger.changes).contains(Pair(COL_HOTSPOT, "null"))
}
@Test
@@ -175,7 +178,8 @@ class WifiNetworkModelTest : SysuiTestCase() {
networkId = 5,
isValidated = true,
level = 3,
- ssid = "Test SSID"
+ ssid = "Test SSID",
+ hotspotDeviceType = WifiNetworkModel.HotspotDeviceType.AUTO,
)
val prevVal =
WifiNetworkModel.CarrierMerged(
@@ -191,6 +195,7 @@ class WifiNetworkModelTest : SysuiTestCase() {
assertThat(logger.changes).contains(Pair(COL_VALIDATED, "true"))
assertThat(logger.changes).contains(Pair(COL_LEVEL, "3"))
assertThat(logger.changes).contains(Pair(COL_SSID, "Test SSID"))
+ assertThat(logger.changes).contains(Pair(COL_HOTSPOT, "AUTO"))
}
@Test
fun logDiffs_activeToCarrierMerged_logsAllFields() {