Merge changes Ie14c36f0,I73fc9334,Ic06b0e34 into main
* changes: InternetPreferenceController V2 (6/n) InternetPreferenceController V2 (5/n) InternetPreferenceController V2 (4/n)
This commit is contained in:
@@ -22,11 +22,13 @@ import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceScreen
|
||||
import com.android.settings.R
|
||||
import com.android.settings.core.BasePreferenceController
|
||||
import com.android.settingslib.Utils
|
||||
import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
|
||||
|
||||
class InternetPreferenceControllerV2(context: Context, preferenceKey: String) :
|
||||
BasePreferenceController(context, preferenceKey) {
|
||||
|
||||
private val repository = InternetPreferenceRepository(mContext)
|
||||
private var preference: Preference? = null
|
||||
|
||||
override fun getAvailabilityStatus() =
|
||||
@@ -39,9 +41,14 @@ class InternetPreferenceControllerV2(context: Context, preferenceKey: String) :
|
||||
}
|
||||
|
||||
override fun onViewCreated(viewLifecycleOwner: LifecycleOwner) {
|
||||
InternetPreferenceRepository(mContext).summaryFlow()
|
||||
.collectLatestWithLifecycle(viewLifecycleOwner) {
|
||||
preference?.summary = it
|
||||
repository.displayInfoFlow().collectLatestWithLifecycle(viewLifecycleOwner) { displayInfo ->
|
||||
preference?.apply {
|
||||
summary = displayInfo.summary
|
||||
icon =
|
||||
mContext.getDrawable(displayInfo.iconResId)?.apply {
|
||||
setTintList(Utils.getColorAttr(mContext, android.R.attr.colorControlNormal))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,9 +18,11 @@ package com.android.settings.network
|
||||
|
||||
import android.content.Context
|
||||
import android.net.NetworkCapabilities
|
||||
import android.net.wifi.WifiInfo
|
||||
import android.net.wifi.WifiManager
|
||||
import android.provider.Settings
|
||||
import android.util.Log
|
||||
import androidx.annotation.DrawableRes
|
||||
import com.android.settings.R
|
||||
import com.android.settings.network.telephony.DataSubscriptionRepository
|
||||
import com.android.settings.wifi.WifiSummaryRepository
|
||||
@@ -32,7 +34,9 @@ import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.conflate
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@@ -47,42 +51,80 @@ class InternetPreferenceRepository(
|
||||
context.settingsGlobalBooleanFlow(Settings.Global.AIRPLANE_MODE_ON),
|
||||
) {
|
||||
|
||||
fun summaryFlow(): Flow<String> =
|
||||
data class DisplayInfo(
|
||||
val summary: String,
|
||||
@DrawableRes val iconResId: Int,
|
||||
)
|
||||
|
||||
fun displayInfoFlow(): Flow<DisplayInfo> =
|
||||
connectivityRepository
|
||||
.networkCapabilitiesFlow()
|
||||
.flatMapLatest { capabilities -> capabilities.summaryFlow() }
|
||||
.onEach { Log.d(TAG, "summaryFlow: $it") }
|
||||
.flatMapLatest { capabilities -> capabilities.displayInfoFlow() }
|
||||
.onEach { Log.d(TAG, "displayInfoFlow: $it") }
|
||||
.conflate()
|
||||
.flowOn(Dispatchers.Default)
|
||||
|
||||
private fun NetworkCapabilities.summaryFlow(): Flow<String> {
|
||||
private fun NetworkCapabilities.displayInfoFlow(): Flow<DisplayInfo> {
|
||||
if (
|
||||
hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) &&
|
||||
hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
|
||||
) {
|
||||
val transportInfo = transportInfo
|
||||
if (transportInfo is WifiInfo && transportInfo.isCarrierMerged) {
|
||||
Log.i(TAG, "Detect a merged carrier Wi-Fi connected.")
|
||||
return cellularDisplayInfoFlow()
|
||||
}
|
||||
for (transportType in transportTypes) {
|
||||
when (transportType) {
|
||||
NetworkCapabilities.TRANSPORT_WIFI -> return wifiSummaryRepository.summaryFlow()
|
||||
NetworkCapabilities.TRANSPORT_CELLULAR ->
|
||||
return dataSubscriptionRepository.dataSummaryFlow()
|
||||
NetworkCapabilities.TRANSPORT_WIFI -> return wifiDisplayInfoFlow()
|
||||
NetworkCapabilities.TRANSPORT_CELLULAR -> return cellularDisplayInfoFlow()
|
||||
NetworkCapabilities.TRANSPORT_ETHERNET -> return ethernetDisplayInfoFlow()
|
||||
}
|
||||
}
|
||||
}
|
||||
return defaultSummaryFlow()
|
||||
return defaultDisplayInfoFlow()
|
||||
}
|
||||
|
||||
private fun defaultSummaryFlow(): Flow<String> =
|
||||
private fun wifiDisplayInfoFlow() =
|
||||
wifiSummaryRepository.summaryFlow().map { summary ->
|
||||
DisplayInfo(
|
||||
summary = summary,
|
||||
iconResId = R.drawable.ic_wifi_signal_4,
|
||||
)
|
||||
}
|
||||
|
||||
private fun cellularDisplayInfoFlow() =
|
||||
dataSubscriptionRepository.dataSummaryFlow().map { summary ->
|
||||
DisplayInfo(
|
||||
summary = summary,
|
||||
iconResId = R.drawable.ic_network_cell,
|
||||
)
|
||||
}
|
||||
|
||||
private fun ethernetDisplayInfoFlow() =
|
||||
flowOf(
|
||||
DisplayInfo(
|
||||
summary = context.getString(R.string.to_switch_networks_disconnect_ethernet),
|
||||
iconResId = R.drawable.ic_settings_ethernet,
|
||||
)
|
||||
)
|
||||
|
||||
private fun defaultDisplayInfoFlow(): Flow<DisplayInfo> =
|
||||
combine(
|
||||
airplaneModeOnFlow,
|
||||
wifiRepository.wifiStateFlow(),
|
||||
) { airplaneModeOn: Boolean, wifiState: Int ->
|
||||
context.getString(
|
||||
if (airplaneModeOn && wifiState != WifiManager.WIFI_STATE_ENABLED) {
|
||||
R.string.condition_airplane_title
|
||||
} else {
|
||||
R.string.networks_available
|
||||
}
|
||||
)
|
||||
if (airplaneModeOn && wifiState != WifiManager.WIFI_STATE_ENABLED) {
|
||||
DisplayInfo(
|
||||
summary = context.getString(R.string.condition_airplane_title),
|
||||
iconResId = R.drawable.ic_no_internet_unavailable,
|
||||
)
|
||||
} else {
|
||||
DisplayInfo(
|
||||
summary = context.getString(R.string.networks_available),
|
||||
iconResId = R.drawable.ic_no_internet_available,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private companion object {
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.settings.network
|
||||
|
||||
import android.content.Context
|
||||
import android.net.NetworkCapabilities
|
||||
import android.net.wifi.WifiInfo
|
||||
import android.net.wifi.WifiManager
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
@@ -32,6 +33,7 @@ import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.kotlin.any
|
||||
import org.mockito.kotlin.doReturn
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.stub
|
||||
@@ -58,7 +60,7 @@ class InternetPreferenceRepositoryTest {
|
||||
)
|
||||
|
||||
@Test
|
||||
fun summaryFlow_wifi() = runBlocking {
|
||||
fun displayInfoFlow_wifi() = runBlocking {
|
||||
val wifiNetworkCapabilities =
|
||||
NetworkCapabilities.Builder()
|
||||
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
|
||||
@@ -70,13 +72,49 @@ class InternetPreferenceRepositoryTest {
|
||||
}
|
||||
mockWifiSummaryRepository.stub { on { summaryFlow() } doReturn flowOf(SUMMARY) }
|
||||
|
||||
val summary = repository.summaryFlow().firstWithTimeoutOrNull()
|
||||
val displayInfo = repository.displayInfoFlow().firstWithTimeoutOrNull()
|
||||
|
||||
assertThat(summary).isEqualTo(SUMMARY)
|
||||
assertThat(displayInfo)
|
||||
.isEqualTo(
|
||||
InternetPreferenceRepository.DisplayInfo(
|
||||
summary = SUMMARY,
|
||||
iconResId = R.drawable.ic_wifi_signal_4,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun summaryFlow_cellular() = runBlocking {
|
||||
fun displayInfoFlow_carrierMergedWifi_asCellular() = runBlocking {
|
||||
val wifiInfo =
|
||||
mock<WifiInfo> {
|
||||
on { isCarrierMerged } doReturn true
|
||||
on { makeCopy(any()) } doReturn mock
|
||||
}
|
||||
val wifiNetworkCapabilities =
|
||||
NetworkCapabilities.Builder()
|
||||
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
|
||||
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
||||
.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
|
||||
.setTransportInfo(wifiInfo)
|
||||
.build()
|
||||
mockConnectivityRepository.stub {
|
||||
on { networkCapabilitiesFlow() } doReturn flowOf(wifiNetworkCapabilities)
|
||||
}
|
||||
mockDataSubscriptionRepository.stub { on { dataSummaryFlow() } doReturn flowOf(SUMMARY) }
|
||||
|
||||
val displayInfo = repository.displayInfoFlow().firstWithTimeoutOrNull()
|
||||
|
||||
assertThat(displayInfo)
|
||||
.isEqualTo(
|
||||
InternetPreferenceRepository.DisplayInfo(
|
||||
summary = SUMMARY,
|
||||
iconResId = R.drawable.ic_network_cell,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun displayInfoFlow_cellular() = runBlocking {
|
||||
val wifiNetworkCapabilities =
|
||||
NetworkCapabilities.Builder()
|
||||
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
|
||||
@@ -88,13 +126,42 @@ class InternetPreferenceRepositoryTest {
|
||||
}
|
||||
mockDataSubscriptionRepository.stub { on { dataSummaryFlow() } doReturn flowOf(SUMMARY) }
|
||||
|
||||
val summary = repository.summaryFlow().firstWithTimeoutOrNull()
|
||||
val displayInfo = repository.displayInfoFlow().firstWithTimeoutOrNull()
|
||||
|
||||
assertThat(summary).isEqualTo(SUMMARY)
|
||||
assertThat(displayInfo)
|
||||
.isEqualTo(
|
||||
InternetPreferenceRepository.DisplayInfo(
|
||||
summary = SUMMARY,
|
||||
iconResId = R.drawable.ic_network_cell,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun summaryFlow_airplaneModeOnAndWifiOn() = runBlocking {
|
||||
fun displayInfoFlow_ethernet() = runBlocking {
|
||||
val wifiNetworkCapabilities =
|
||||
NetworkCapabilities.Builder()
|
||||
.addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET)
|
||||
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
||||
.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
|
||||
.build()
|
||||
mockConnectivityRepository.stub {
|
||||
on { networkCapabilitiesFlow() } doReturn flowOf(wifiNetworkCapabilities)
|
||||
}
|
||||
|
||||
val displayInfo = repository.displayInfoFlow().firstWithTimeoutOrNull()
|
||||
|
||||
assertThat(displayInfo)
|
||||
.isEqualTo(
|
||||
InternetPreferenceRepository.DisplayInfo(
|
||||
summary = context.getString(R.string.to_switch_networks_disconnect_ethernet),
|
||||
iconResId = R.drawable.ic_settings_ethernet,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun displayInfoFlow_airplaneModeOnAndWifiOn() = runBlocking {
|
||||
mockConnectivityRepository.stub {
|
||||
on { networkCapabilitiesFlow() } doReturn flowOf(NetworkCapabilities())
|
||||
}
|
||||
@@ -103,13 +170,19 @@ class InternetPreferenceRepositoryTest {
|
||||
on { wifiStateFlow() } doReturn flowOf(WifiManager.WIFI_STATE_ENABLED)
|
||||
}
|
||||
|
||||
val summary = repository.summaryFlow().firstWithTimeoutOrNull()
|
||||
val displayInfo = repository.displayInfoFlow().firstWithTimeoutOrNull()
|
||||
|
||||
assertThat(summary).isEqualTo(context.getString(R.string.networks_available))
|
||||
assertThat(displayInfo)
|
||||
.isEqualTo(
|
||||
InternetPreferenceRepository.DisplayInfo(
|
||||
summary = context.getString(R.string.networks_available),
|
||||
iconResId = R.drawable.ic_no_internet_available,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun summaryFlow_airplaneModeOnAndWifiOff() = runBlocking {
|
||||
fun displayInfoFlow_airplaneModeOnAndWifiOff() = runBlocking {
|
||||
mockConnectivityRepository.stub {
|
||||
on { networkCapabilitiesFlow() } doReturn flowOf(NetworkCapabilities())
|
||||
}
|
||||
@@ -118,13 +191,19 @@ class InternetPreferenceRepositoryTest {
|
||||
on { wifiStateFlow() } doReturn flowOf(WifiManager.WIFI_STATE_DISABLED)
|
||||
}
|
||||
|
||||
val summary = repository.summaryFlow().firstWithTimeoutOrNull()
|
||||
val displayInfo = repository.displayInfoFlow().firstWithTimeoutOrNull()
|
||||
|
||||
assertThat(summary).isEqualTo(context.getString(R.string.condition_airplane_title))
|
||||
assertThat(displayInfo)
|
||||
.isEqualTo(
|
||||
InternetPreferenceRepository.DisplayInfo(
|
||||
summary = context.getString(R.string.condition_airplane_title),
|
||||
iconResId = R.drawable.ic_no_internet_unavailable,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun summaryFlow_airplaneModeOff() = runBlocking {
|
||||
fun displayInfoFlow_airplaneModeOff() = runBlocking {
|
||||
mockConnectivityRepository.stub {
|
||||
on { networkCapabilitiesFlow() } doReturn flowOf(NetworkCapabilities())
|
||||
}
|
||||
@@ -133,9 +212,15 @@ class InternetPreferenceRepositoryTest {
|
||||
on { wifiStateFlow() } doReturn flowOf(WifiManager.WIFI_STATE_DISABLED)
|
||||
}
|
||||
|
||||
val summary = repository.summaryFlow().firstWithTimeoutOrNull()
|
||||
val displayInfo = repository.displayInfoFlow().firstWithTimeoutOrNull()
|
||||
|
||||
assertThat(summary).isEqualTo(context.getString(R.string.networks_available))
|
||||
assertThat(displayInfo)
|
||||
.isEqualTo(
|
||||
InternetPreferenceRepository.DisplayInfo(
|
||||
summary = context.getString(R.string.networks_available),
|
||||
iconResId = R.drawable.ic_no_internet_available,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
|
||||
Reference in New Issue
Block a user