Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0d758dfd authored by Chaohui Wang's avatar Chaohui Wang
Browse files

InternetPreferenceController V2 (4/n)

Display different icon for different condition.

Bug: 339884322
Flag: com.android.settings.flags.internet_preference_controller_v2
Test: manual - on Internet
Test: unit test
Change-Id: Ic06b0e349a284f8b4466bd0c19f318a6a0936a6e
parent 585727a3
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -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))
                    }
            }
        }
    }
}
+42 −16
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.net.NetworkCapabilities
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
@@ -33,6 +34,7 @@ import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach

@OptIn(ExperimentalCoroutinesApi::class)
@@ -47,43 +49,67 @@ 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)
        ) {
            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()
                }
            }
        }
        return defaultDisplayInfoFlow()
    }
        return defaultSummaryFlow()

    private fun wifiDisplayInfoFlow() =
        wifiSummaryRepository.summaryFlow().map { summary ->
            DisplayInfo(
                summary = summary,
                iconResId = R.drawable.ic_wifi_signal_4,
            )
        }

    private fun defaultSummaryFlow(): Flow<String> =
    private fun cellularDisplayInfoFlow() =
        dataSubscriptionRepository.dataSummaryFlow().map { summary ->
            DisplayInfo(
                summary = summary,
                iconResId = R.drawable.ic_network_cell,
            )
        }

    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
                DisplayInfo(
                    summary = context.getString(R.string.condition_airplane_title),
                    iconResId = R.drawable.ic_no_internet_unavailable,
                )
            } else {
                    R.string.networks_available
                }
                DisplayInfo(
                    summary = context.getString(R.string.networks_available),
                    iconResId = R.drawable.ic_no_internet_available,
                )
            }
        }

    private companion object {
        private const val TAG = "InternetPreferenceRepo"
+45 −15
Original line number Diff line number Diff line
@@ -58,7 +58,7 @@ class InternetPreferenceRepositoryTest {
        )

    @Test
    fun summaryFlow_wifi() = runBlocking {
    fun displayInfoFlow_wifi() = runBlocking {
        val wifiNetworkCapabilities =
            NetworkCapabilities.Builder()
                .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
@@ -70,13 +70,19 @@ 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_cellular() = runBlocking {
        val wifiNetworkCapabilities =
            NetworkCapabilities.Builder()
                .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
@@ -88,13 +94,19 @@ 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_airplaneModeOnAndWifiOn() = runBlocking {
        mockConnectivityRepository.stub {
            on { networkCapabilitiesFlow() } doReturn flowOf(NetworkCapabilities())
        }
@@ -103,13 +115,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 +136,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 +157,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 {