Loading src/com/android/settings/network/telephony/NetworkSelectRepository.kt +37 −2 Original line number Diff line number Diff line Loading @@ -18,8 +18,10 @@ package com.android.settings.network.telephony import android.content.Context import android.telephony.AccessNetworkConstants import android.telephony.CarrierConfigManager import android.telephony.NetworkRegistrationInfo import android.telephony.TelephonyManager import android.telephony.satellite.SatelliteManager import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.lifecycleScope Loading @@ -28,9 +30,11 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext class NetworkSelectRepository(context: Context, subId: Int) { class NetworkSelectRepository(context: Context, private val subId: Int) { private val telephonyManager = context.getSystemService(TelephonyManager::class.java)!!.createForSubscriptionId(subId) private val satelliteManager = context.getSystemService(SatelliteManager::class.java) private val carrierConfigManager = context.getSystemService(CarrierConfigManager::class.java) data class NetworkRegistrationAndForbiddenInfo( val networkList: List<NetworkRegistrationInfo>, Loading @@ -55,10 +59,21 @@ class NetworkSelectRepository(context: Context, subId: Int) { if (telephonyManager.dataState != TelephonyManager.DATA_CONNECTED) return null // Try to get the network registration states val serviceState = telephonyManager.serviceState ?: return null val networkList = serviceState.getNetworkRegistrationInfoListForTransportType( var networkList = serviceState.getNetworkRegistrationInfoListForTransportType( AccessNetworkConstants.TRANSPORT_TYPE_WWAN ) if (networkList.isEmpty()) return null val satellitePlmn = getSatellitePlmns() // If connected network is Satellite, filter out if (satellitePlmn.isNotEmpty()) { val filteredNetworkList = networkList.filter { val cellIdentity = it.cellIdentity val plmn = cellIdentity?.plmn plmn != null && !satellitePlmn.contains(plmn) } networkList = filteredNetworkList } // Due to the aggregation of cell between carriers, it's possible to get CellIdentity // containing forbidden PLMN. // Getting current network from ServiceState is no longer a good idea. Loading @@ -72,4 +87,24 @@ class NetworkSelectRepository(context: Context, subId: Int) { private fun getForbiddenPlmns(): List<String> { return telephonyManager.forbiddenPlmns?.toList() ?: emptyList() } /** * Update satellite PLMNs from the satellite framework. */ private fun getSatellitePlmns(): List<String> { val config = carrierConfigManager.getConfigForSubId( subId, CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL ) val shouldFilter = config.getBoolean( CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL, true) return if (shouldFilter) { satelliteManager.getSatellitePlmnsForCarrier(subId) } else { emptyList(); } } } tests/spa_unit/src/com/android/settings/network/telephony/NetworkSelectRepositoryTest.kt +88 −4 Original line number Diff line number Diff line Loading @@ -17,20 +17,21 @@ package com.android.settings.network.telephony import android.content.Context import android.telephony.AccessNetworkConstants import android.telephony.NetworkRegistrationInfo import android.telephony.ServiceState import android.telephony.TelephonyManager import android.os.PersistableBundle import android.telephony.* import android.telephony.satellite.SatelliteManager import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.settings.network.telephony.scan.NetworkScanRepositoryTest import com.google.common.truth.Truth.assertThat import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.anyInt import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock import org.mockito.kotlin.spy import org.mockito.kotlin.stub import org.mockito.kotlin.whenever @RunWith(AndroidJUnit4::class) class NetworkSelectRepositoryTest { Loading @@ -49,8 +50,16 @@ class NetworkSelectRepositoryTest { on { serviceState } doReturn mockServiceState } private val mockSatelliteManager = mock<SatelliteManager> { on { getSatellitePlmnsForCarrier(anyInt()) } doReturn SatellitePlmns } private var mockCarrierConfigManager = mock<CarrierConfigManager>() private val context: Context = spy(ApplicationProvider.getApplicationContext()) { on { getSystemService(TelephonyManager::class.java) } doReturn mockTelephonyManager on { getSystemService(SatelliteManager::class.java) } doReturn mockSatelliteManager on { getSystemService(CarrierConfigManager::class.java) } doReturn mockCarrierConfigManager } private val repository = NetworkSelectRepository(context, SUB_ID) Loading Loading @@ -105,6 +114,14 @@ class NetworkSelectRepositoryTest { on { forbiddenPlmns } doReturn arrayOf(FORBIDDEN_PLMN) } val config = PersistableBundle() config.putBoolean( CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL, false) whenever(mockCarrierConfigManager.getConfigForSubId( SUB_ID, CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL)) .thenReturn(config) val info = repository.getNetworkRegistrationInfo() assertThat(info).isEqualTo( Loading @@ -115,9 +132,76 @@ class NetworkSelectRepositoryTest { ) } @Test fun getNetworkRegistrationInfo_filterSatellitePlmn() { val info1 = createTestNetworkRegistrationInfo("310", "260") val info2 = createTestNetworkRegistrationInfo("310", "261") val satelliteInfo = createTestNetworkRegistrationInfo(satelliteMcc, satelliteMnc) val registrationInfos = listOf(info1, info2, satelliteInfo) val filteredRegistrationInfos = listOf(info1, info2) mockServiceState.stub { on { getNetworkRegistrationInfoListForTransportType( AccessNetworkConstants.TRANSPORT_TYPE_WWAN ) } doReturn registrationInfos } mockTelephonyManager.stub { on { forbiddenPlmns } doReturn arrayOf(FORBIDDEN_PLMN) } // disable satellite plmn filter var config = PersistableBundle() config.putBoolean( CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL, false) whenever(mockCarrierConfigManager.getConfigForSubId( SUB_ID, CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL)) .thenReturn(config) var infoList = repository.getNetworkRegistrationInfo() assertThat(infoList).isEqualTo( NetworkSelectRepository.NetworkRegistrationAndForbiddenInfo( networkList = registrationInfos, forbiddenPlmns = listOf(FORBIDDEN_PLMN), ) ) // enable satellite plmn filter config = PersistableBundle() config.putBoolean( CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL, true) whenever(mockCarrierConfigManager.getConfigForSubId( SUB_ID, CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL)) .thenReturn(config) infoList = repository.getNetworkRegistrationInfo() assertThat(infoList).isEqualTo( NetworkSelectRepository.NetworkRegistrationAndForbiddenInfo( networkList = filteredRegistrationInfos, forbiddenPlmns = listOf(FORBIDDEN_PLMN), ) ) } private companion object { const val SUB_ID = 1 val NetworkRegistrationInfos = listOf(NetworkRegistrationInfo.Builder().build()) const val FORBIDDEN_PLMN = "Forbidden PLMN" const val satelliteMcc = "310" const val satelliteMnc = "810" val SatellitePlmns = listOf(satelliteMcc + satelliteMnc) fun createTestNetworkRegistrationInfo(mcc: String, mnc: String): NetworkRegistrationInfo { val cellInfo = CellIdentityLte(0, 0, 0, 0, IntArray(2) { 0 }, 0, mcc, mnc, "", "", emptyList(), null) return NetworkRegistrationInfo.Builder().setCellIdentity(cellInfo).build() } } } Loading
src/com/android/settings/network/telephony/NetworkSelectRepository.kt +37 −2 Original line number Diff line number Diff line Loading @@ -18,8 +18,10 @@ package com.android.settings.network.telephony import android.content.Context import android.telephony.AccessNetworkConstants import android.telephony.CarrierConfigManager import android.telephony.NetworkRegistrationInfo import android.telephony.TelephonyManager import android.telephony.satellite.SatelliteManager import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.lifecycleScope Loading @@ -28,9 +30,11 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext class NetworkSelectRepository(context: Context, subId: Int) { class NetworkSelectRepository(context: Context, private val subId: Int) { private val telephonyManager = context.getSystemService(TelephonyManager::class.java)!!.createForSubscriptionId(subId) private val satelliteManager = context.getSystemService(SatelliteManager::class.java) private val carrierConfigManager = context.getSystemService(CarrierConfigManager::class.java) data class NetworkRegistrationAndForbiddenInfo( val networkList: List<NetworkRegistrationInfo>, Loading @@ -55,10 +59,21 @@ class NetworkSelectRepository(context: Context, subId: Int) { if (telephonyManager.dataState != TelephonyManager.DATA_CONNECTED) return null // Try to get the network registration states val serviceState = telephonyManager.serviceState ?: return null val networkList = serviceState.getNetworkRegistrationInfoListForTransportType( var networkList = serviceState.getNetworkRegistrationInfoListForTransportType( AccessNetworkConstants.TRANSPORT_TYPE_WWAN ) if (networkList.isEmpty()) return null val satellitePlmn = getSatellitePlmns() // If connected network is Satellite, filter out if (satellitePlmn.isNotEmpty()) { val filteredNetworkList = networkList.filter { val cellIdentity = it.cellIdentity val plmn = cellIdentity?.plmn plmn != null && !satellitePlmn.contains(plmn) } networkList = filteredNetworkList } // Due to the aggregation of cell between carriers, it's possible to get CellIdentity // containing forbidden PLMN. // Getting current network from ServiceState is no longer a good idea. Loading @@ -72,4 +87,24 @@ class NetworkSelectRepository(context: Context, subId: Int) { private fun getForbiddenPlmns(): List<String> { return telephonyManager.forbiddenPlmns?.toList() ?: emptyList() } /** * Update satellite PLMNs from the satellite framework. */ private fun getSatellitePlmns(): List<String> { val config = carrierConfigManager.getConfigForSubId( subId, CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL ) val shouldFilter = config.getBoolean( CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL, true) return if (shouldFilter) { satelliteManager.getSatellitePlmnsForCarrier(subId) } else { emptyList(); } } }
tests/spa_unit/src/com/android/settings/network/telephony/NetworkSelectRepositoryTest.kt +88 −4 Original line number Diff line number Diff line Loading @@ -17,20 +17,21 @@ package com.android.settings.network.telephony import android.content.Context import android.telephony.AccessNetworkConstants import android.telephony.NetworkRegistrationInfo import android.telephony.ServiceState import android.telephony.TelephonyManager import android.os.PersistableBundle import android.telephony.* import android.telephony.satellite.SatelliteManager import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.settings.network.telephony.scan.NetworkScanRepositoryTest import com.google.common.truth.Truth.assertThat import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.anyInt import org.mockito.kotlin.doReturn import org.mockito.kotlin.mock import org.mockito.kotlin.spy import org.mockito.kotlin.stub import org.mockito.kotlin.whenever @RunWith(AndroidJUnit4::class) class NetworkSelectRepositoryTest { Loading @@ -49,8 +50,16 @@ class NetworkSelectRepositoryTest { on { serviceState } doReturn mockServiceState } private val mockSatelliteManager = mock<SatelliteManager> { on { getSatellitePlmnsForCarrier(anyInt()) } doReturn SatellitePlmns } private var mockCarrierConfigManager = mock<CarrierConfigManager>() private val context: Context = spy(ApplicationProvider.getApplicationContext()) { on { getSystemService(TelephonyManager::class.java) } doReturn mockTelephonyManager on { getSystemService(SatelliteManager::class.java) } doReturn mockSatelliteManager on { getSystemService(CarrierConfigManager::class.java) } doReturn mockCarrierConfigManager } private val repository = NetworkSelectRepository(context, SUB_ID) Loading Loading @@ -105,6 +114,14 @@ class NetworkSelectRepositoryTest { on { forbiddenPlmns } doReturn arrayOf(FORBIDDEN_PLMN) } val config = PersistableBundle() config.putBoolean( CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL, false) whenever(mockCarrierConfigManager.getConfigForSubId( SUB_ID, CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL)) .thenReturn(config) val info = repository.getNetworkRegistrationInfo() assertThat(info).isEqualTo( Loading @@ -115,9 +132,76 @@ class NetworkSelectRepositoryTest { ) } @Test fun getNetworkRegistrationInfo_filterSatellitePlmn() { val info1 = createTestNetworkRegistrationInfo("310", "260") val info2 = createTestNetworkRegistrationInfo("310", "261") val satelliteInfo = createTestNetworkRegistrationInfo(satelliteMcc, satelliteMnc) val registrationInfos = listOf(info1, info2, satelliteInfo) val filteredRegistrationInfos = listOf(info1, info2) mockServiceState.stub { on { getNetworkRegistrationInfoListForTransportType( AccessNetworkConstants.TRANSPORT_TYPE_WWAN ) } doReturn registrationInfos } mockTelephonyManager.stub { on { forbiddenPlmns } doReturn arrayOf(FORBIDDEN_PLMN) } // disable satellite plmn filter var config = PersistableBundle() config.putBoolean( CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL, false) whenever(mockCarrierConfigManager.getConfigForSubId( SUB_ID, CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL)) .thenReturn(config) var infoList = repository.getNetworkRegistrationInfo() assertThat(infoList).isEqualTo( NetworkSelectRepository.NetworkRegistrationAndForbiddenInfo( networkList = registrationInfos, forbiddenPlmns = listOf(FORBIDDEN_PLMN), ) ) // enable satellite plmn filter config = PersistableBundle() config.putBoolean( CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL, true) whenever(mockCarrierConfigManager.getConfigForSubId( SUB_ID, CarrierConfigManager.KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL)) .thenReturn(config) infoList = repository.getNetworkRegistrationInfo() assertThat(infoList).isEqualTo( NetworkSelectRepository.NetworkRegistrationAndForbiddenInfo( networkList = filteredRegistrationInfos, forbiddenPlmns = listOf(FORBIDDEN_PLMN), ) ) } private companion object { const val SUB_ID = 1 val NetworkRegistrationInfos = listOf(NetworkRegistrationInfo.Builder().build()) const val FORBIDDEN_PLMN = "Forbidden PLMN" const val satelliteMcc = "310" const val satelliteMnc = "810" val SatellitePlmns = listOf(satelliteMcc + satelliteMnc) fun createTestNetworkRegistrationInfo(mcc: String, mnc: String): NetworkRegistrationInfo { val cellInfo = CellIdentityLte(0, 0, 0, 0, IntArray(2) { 0 }, 0, mcc, mnc, "", "", emptyList(), null) return NetworkRegistrationInfo.Builder().setCellIdentity(cellInfo).build() } } }