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

Commit 8daf3357 authored by Chaohui Wang's avatar Chaohui Wang Committed by Android (Google) Code Review
Browse files

Merge "Catch exception in telephonyRepository.isDataEnabledFlow" into main

parents baabc091 8c507e87
Loading
Loading
Loading
Loading
+2 −4
Original line number Diff line number Diff line
@@ -26,11 +26,9 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.settings.R
import com.android.settings.core.SubSettingLauncher
import com.android.settings.datausage.lib.BillingCycleRepository
import com.android.settings.network.mobileDataEnabledFlow
import com.android.settings.spa.preference.ComposePreference
import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel
import kotlinx.coroutines.flow.map

/**
 * Preference which displays billing cycle of subscription
@@ -46,8 +44,8 @@ class BillingCyclePreference @JvmOverloads constructor(

    override fun setTemplate(template: NetworkTemplate, subId: Int) {
        setContent {
            val isModifiable by remember {
                context.mobileDataEnabledFlow(subId).map { repository.isModifiable(subId) }
            val isModifiable by remember(subId) {
                repository.isModifiableFlow(subId)
            }.collectAsStateWithLifecycle(initialValue = false)

            Preference(object : PreferenceModel {
+7 −9
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@ import com.android.settings.datausage.lib.BillingCycleRepository
import com.android.settings.datausage.lib.NetworkUsageData
import com.android.settings.network.MobileNetworkRepository
import com.android.settings.network.SubscriptionUtil
import com.android.settings.network.mobileDataEnabledFlow
import com.android.settings.network.telephony.requireSubscriptionManager
import com.android.settingslib.mobile.dataservice.SubscriptionInfoEntity
import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
import com.android.settingslib.spaprivileged.framework.common.userManager
@@ -113,8 +113,8 @@ open class DataUsageList : DashboardFragment() {
    override fun onViewCreated(v: View, savedInstanceState: Bundle?) {
        super.onViewCreated(v, savedInstanceState)

        requireContext().mobileDataEnabledFlow(subId)
            .collectLatestWithLifecycle(viewLifecycleOwner) { updatePolicy() }
        billingCycleRepository.isModifiableFlow(subId)
            .collectLatestWithLifecycle(viewLifecycleOwner, action = ::updatePolicy)

        val template = template ?: return
        viewModel.templateFlow.value = template
@@ -163,16 +163,14 @@ open class DataUsageList : DashboardFragment() {
    }

    /** Update chart sweeps and cycle list to reflect [NetworkPolicy] for current [template]. */
    private fun updatePolicy() {
        val isBillingCycleModifiable = isBillingCycleModifiable()
    private fun updatePolicy(isModifiable: Boolean) {
        val isBillingCycleModifiable = isModifiable && isActiveSubscription()
        dataUsageListHeaderController?.setConfigButtonVisible(isBillingCycleModifiable)
        chartDataUsagePreferenceController?.setBillingCycleModifiable(isBillingCycleModifiable)
    }

    private fun isBillingCycleModifiable(): Boolean =
        billingCycleRepository.isModifiable(subId) &&
            requireContext().getSystemService(SubscriptionManager::class.java)!!
                .getActiveSubscriptionInfo(subId) != null
    private fun isActiveSubscription(): Boolean =
            requireContext().requireSubscriptionManager().getActiveSubscriptionInfo(subId) != null

    /**
     * Updates the chart and detail data when initial loaded or selected cycle changed.
+11 −8
Original line number Diff line number Diff line
@@ -19,10 +19,15 @@ package com.android.settings.datausage.lib
import android.content.Context
import android.os.INetworkManagementService
import android.os.ServiceManager
import android.telephony.TelephonyManager
import android.util.Log
import androidx.annotation.OpenForTesting
import com.android.settings.network.telephony.TelephonyRepository
import com.android.settingslib.spaprivileged.framework.common.userManager
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map

@OpenForTesting
open class BillingCycleRepository @JvmOverloads constructor(
@@ -31,12 +36,14 @@ open class BillingCycleRepository @JvmOverloads constructor(
        INetworkManagementService.Stub.asInterface(
            ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE)
        ),
    private val telephonyRepository: TelephonyRepository = TelephonyRepository(context),
) {
    private val userManager = context.userManager
    private val telephonyManager = context.getSystemService(TelephonyManager::class.java)!!

    fun isModifiable(subId: Int): Boolean =
        isBandwidthControlEnabled() && userManager.isAdminUser && isDataEnabled(subId)
    fun isModifiableFlow(subId: Int): Flow<Boolean> =
        telephonyRepository.isDataEnabledFlow(subId).map { isDataEnabled ->
            isDataEnabled && isBandwidthControlEnabled() && userManager.isAdminUser
        }.conflate().flowOn(Dispatchers.Default)

    open fun isBandwidthControlEnabled(): Boolean = try {
        networkService.isBandwidthControlEnabled
@@ -45,10 +52,6 @@ open class BillingCycleRepository @JvmOverloads constructor(
        false
    }

    private fun isDataEnabled(subId: Int): Boolean =
        telephonyManager.createForSubscriptionId(subId)
            .isDataEnabledForReason(TelephonyManager.DATA_ENABLED_REASON_USER)

    companion object {
        private const val TAG = "BillingCycleRepository"
    }
+11 −6
Original line number Diff line number Diff line
@@ -29,10 +29,12 @@ import kotlinx.coroutines.channels.ProducerScope
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach

class TelephonyRepository(
    private val context: Context,
@@ -64,19 +66,21 @@ class TelephonyRepository(
        telephonyManager.setMobileDataPolicyEnabled(policy, enabled)
    }

    fun isDataEnabled(
        subId: Int,
    ): Flow<Boolean> {
    fun isDataEnabledFlow(subId: Int): Flow<Boolean> {
        if (!SubscriptionManager.isValidSubscriptionId(subId)) return flowOf(false)

        Log.d(TAG, "register mobileDataEnabledFlow: [$subId]")
        return context.mobileDataEnabledFlow(subId)
            .map {
                Log.d(TAG, "mobileDataEnabledFlow: receive mobile data [$subId] start")
                val telephonyManager = context.telephonyManager(subId)
                telephonyManager.isDataEnabledForReason(TelephonyManager.DATA_ENABLED_REASON_USER)
                    .also { Log.d(TAG, "mobileDataEnabledFlow: [$subId] isDataEnabled(): $it") }
            }
            .catch {
                Log.w(TAG, "[$subId] isDataEnabledFlow: exception", it)
                emit(false)
            }
            .onEach { Log.d(TAG, "[$subId] isDataEnabledFlow: isDataEnabled() = $it") }
            .conflate()
            .flowOn(Dispatchers.Default)
    }

    fun setMobileData(
@@ -100,6 +104,7 @@ class TelephonyRepository(
            wifiPickerTrackerHelper.setCarrierNetworkEnabled(enabled)
        }
    }

    private companion object {
        private const val TAG = "TelephonyRepository"
    }
+2 −3
Original line number Diff line number Diff line
@@ -36,11 +36,11 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleRegistry
import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import com.android.settings.R
@@ -62,7 +62,6 @@ import com.android.settingslib.spaprivileged.settingsprovider.settingsGlobalBool
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.flowOf
@@ -207,7 +206,7 @@ fun MobileDataSectionImpl(
        }.collectAsStateWithLifecycle(initialValue = null)

        val mobileDataStateChanged by remember(mobileDataSelectedId.intValue) {
            TelephonyRepository(context).isDataEnabled(mobileDataSelectedId.intValue)
            TelephonyRepository(context).isDataEnabledFlow(mobileDataSelectedId.intValue)
        }.collectAsStateWithLifecycle(initialValue = false)
        val coroutineScope = rememberCoroutineScope()

Loading