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

Commit ec59cd0c authored by Chaohui Wang's avatar Chaohui Wang
Browse files

Move mobile data logic into MobileDataRepository

Bug: 347224962
Flag: EXEMPT refactor
Test: manual on Mobile Settings
Test: unit
Change-Id: I2b54f9e6c4addafd31d7d96f2a44870cd54fe185
parent 2345b63c
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -21,7 +21,7 @@ import android.os.INetworkManagementService
import android.os.ServiceManager
import android.util.Log
import androidx.annotation.OpenForTesting
import com.android.settings.network.telephony.TelephonyRepository
import com.android.settings.network.telephony.MobileDataRepository
import com.android.settingslib.spaprivileged.framework.common.userManager
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
@@ -36,13 +36,13 @@ open class BillingCycleRepository @JvmOverloads constructor(
        INetworkManagementService.Stub.asInterface(
            ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE)
        ),
    private val telephonyRepository: TelephonyRepository = TelephonyRepository(context),
    private val mobileDataRepository: MobileDataRepository = MobileDataRepository(context),
) {
    private val userManager = context.userManager

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

    open fun isBandwidthControlEnabled(): Boolean = try {
+0 −43
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.settings.network

import android.content.Context
import android.provider.Settings
import android.telephony.SubscriptionManager
import com.android.settingslib.spaprivileged.settingsprovider.settingsGlobalChangeFlow
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.merge

/**
 * Flow for mobile data enabled changed event.
 *
 * Note: This flow can only notify enabled status changes, cannot provide the latest status.
 */
fun Context.mobileDataEnabledFlow(subId: Int, sendInitialValue: Boolean = true): Flow<Unit> {
    val flow = settingsGlobalChangeFlow(Settings.Global.MOBILE_DATA, sendInitialValue)
    return when (subId) {
        SubscriptionManager.INVALID_SUBSCRIPTION_ID -> flow
        else -> {
            val subIdFlow = settingsGlobalChangeFlow(
                name = Settings.Global.MOBILE_DATA + subId,
                sendInitialValue = false,
            )
            merge(flow, subIdFlow)
        }
    }
}
+2 −3
Original line number Diff line number Diff line
@@ -27,9 +27,8 @@ import android.telephony.UiccCardInfo
import android.telephony.UiccSlotInfo
import android.util.Log
import com.android.settings.network.SimOnboardingActivity.Companion.CallbackType
import com.android.settings.network.telephony.TelephonyRepository
import com.android.settings.network.telephony.MobileDataRepository
import com.android.settings.sim.SimActivationNotifier
import com.android.settings.spa.network.setAutomaticData
import com.android.settings.spa.network.setDefaultData
import com.android.settings.spa.network.setDefaultSms
import com.android.settings.spa.network.setDefaultVoice
@@ -366,7 +365,7 @@ class SimOnboardingService {
                    wifiPickerTrackerHelper,
                    targetPrimarySimMobileData
                )
                TelephonyRepository(context).setAutomaticData(
                MobileDataRepository(context).setAutoDataSwitch(
                    targetNonDds,
                    targetPrimarySimAutoDataSwitch.value
                )
+1 −2
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@ import android.telephony.TelephonyManager
import android.telephony.data.ApnSetting
import androidx.lifecycle.LifecycleOwner
import androidx.preference.PreferenceScreen
import com.android.settings.network.mobileDataEnabledFlow
import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
import kotlinx.coroutines.flow.combine

@@ -71,7 +70,7 @@ class MmsMessagePreferenceController @JvmOverloads constructor(

    override fun onViewCreated(viewLifecycleOwner: LifecycleOwner) {
        combine(
            mContext.mobileDataEnabledFlow(mSubId),
            MobileDataRepository(mContext).mobileDataEnabledChangedFlow(mSubId),
            mContext.subscriptionsChangedFlow(), // Capture isMobileDataPolicyEnabled() changes
        ) { _, _ -> }.collectLatestWithLifecycle(viewLifecycleOwner) {
            preferenceScreen?.let { super.displayPreference(it) }
+124 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.settings.network.telephony

import android.content.Context
import android.provider.Settings
import android.telephony.SubscriptionManager
import android.telephony.TelephonyManager
import android.telephony.TelephonyManager.MobileDataPolicy
import android.util.Log
import com.android.settings.wifi.WifiPickerTrackerHelper
import com.android.settingslib.spaprivileged.settingsprovider.settingsGlobalChangeFlow
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onEach

class MobileDataRepository(
    private val context: Context,
    private val subscriptionsChangedFlow: Flow<Unit> = context.subscriptionsChangedFlow(),
) {
    fun isMobileDataPolicyEnabledFlow(subId: Int, @MobileDataPolicy policy: Int): Flow<Boolean> {
        if (!SubscriptionManager.isValidSubscriptionId(subId)) return flowOf(false)
        val telephonyManager = context.telephonyManager(subId)
        return subscriptionsChangedFlow
            .map { telephonyManager.isMobileDataPolicyEnabled(policy) }
            .distinctUntilChanged()
            .conflate()
            .onEach { Log.d(TAG, "[$subId] isMobileDataPolicyEnabled($policy): $it") }
            .flowOn(Dispatchers.Default)
    }

    fun setMobileDataPolicyEnabled(subId: Int, @MobileDataPolicy policy: Int, enabled: Boolean) {
        if (!SubscriptionManager.isValidSubscriptionId(subId)) return
        Log.d(TAG, "[$subId] setMobileDataPolicyEnabled($policy): $enabled")
        context.telephonyManager(subId).setMobileDataPolicyEnabled(policy, enabled)
    }

    fun setAutoDataSwitch(subId: Int, newEnabled: Boolean) {
        setMobileDataPolicyEnabled(
            subId = subId,
            policy = TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH,
            enabled = newEnabled,
        )
    }

    /**
     * Flow for mobile data enabled changed event.
     *
     * Note: This flow can only notify enabled status changes, cannot provide the latest status.
     */
    fun mobileDataEnabledChangedFlow(subId: Int, sendInitialValue: Boolean = true): Flow<Unit> =
        mobileSettingsGlobalChangedFlow(Settings.Global.MOBILE_DATA, subId, sendInitialValue)

    private fun mobileSettingsGlobalChangedFlow(
        name: String,
        subId: Int,
        sendInitialValue: Boolean = true,
    ): Flow<Unit> {
        val flow = context.settingsGlobalChangeFlow(name, sendInitialValue)
        if (!SubscriptionManager.isValidSubscriptionId(subId)) return flow
        val subIdFlow =
            context.settingsGlobalChangeFlow(name = name + subId, sendInitialValue = false)
        return merge(flow, subIdFlow)
    }

    fun isMobileDataEnabledFlow(subId: Int): Flow<Boolean> {
        if (!SubscriptionManager.isValidSubscriptionId(subId)) return flowOf(false)
        val telephonyManager = context.telephonyManager(subId)
        return mobileDataEnabledChangedFlow(subId)
            .map {
                telephonyManager.isDataEnabledForReason(TelephonyManager.DATA_ENABLED_REASON_USER)
            }
            .catch { e ->
                Log.w(TAG, "[$subId] isMobileDataEnabledFlow: exception", e)
                emit(false)
            }
            .distinctUntilChanged()
            .conflate()
            .onEach { Log.d(TAG, "[$subId] isMobileDataEnabledFlow: $it") }
            .flowOn(Dispatchers.Default)
    }

    fun setMobileDataEnabled(
        subId: Int,
        enabled: Boolean,
        wifiPickerTrackerHelper: WifiPickerTrackerHelper? = null,
    ) {
        if (!SubscriptionManager.isValidSubscriptionId(subId)) return

        Log.d(TAG, "setMobileDataEnabled: $enabled")
        MobileNetworkUtils.setMobileDataEnabled(
            context, subId, enabled, /* disableOtherSubscriptions= */ true)

        if (wifiPickerTrackerHelper != null &&
            !wifiPickerTrackerHelper.isCarrierNetworkProvisionEnabled(subId)) {
            wifiPickerTrackerHelper.setCarrierNetworkEnabled(enabled)
        }
    }

    private companion object {
        private const val TAG = "MobileDataRepository"
    }
}
Loading