Loading src/com/android/settings/network/apn/ApnEditor.java +0 −104 Original line number Diff line number Diff line Loading @@ -23,88 +23,21 @@ import android.app.settings.SettingsEnums; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.os.PersistableBundle; import android.os.UserManager; import android.provider.Telephony; import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; import android.util.Log; import androidx.annotation.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.settings.SettingsPreferenceFragment; import com.android.settings.spa.SpaActivity; import java.util.Arrays; import java.util.List; /** Use to edit apn settings. */ public class ApnEditor extends SettingsPreferenceFragment { private static final String TAG = ApnEditor.class.getSimpleName(); /** * APN types for data connections. These are usage categories for an APN * entry. One APN entry may support multiple APN types, eg, a single APN * may service regular internet traffic ("default") as well as MMS-specific * connections.<br/> * APN_TYPE_ALL is a special type to indicate that this APN entry can * service all data connections. */ public static final String APN_TYPE_ALL = "*"; /** APN type for default data traffic */ public static final String APN_TYPE_DEFAULT = "default"; /** APN type for MMS traffic */ public static final String APN_TYPE_MMS = "mms"; /** APN type for SUPL assisted GPS */ public static final String APN_TYPE_SUPL = "supl"; /** APN type for DUN traffic */ public static final String APN_TYPE_DUN = "dun"; /** APN type for HiPri traffic */ public static final String APN_TYPE_HIPRI = "hipri"; /** APN type for FOTA */ public static final String APN_TYPE_FOTA = "fota"; /** APN type for IMS */ public static final String APN_TYPE_IMS = "ims"; /** APN type for CBS */ public static final String APN_TYPE_CBS = "cbs"; /** APN type for IA Initial Attach APN */ public static final String APN_TYPE_IA = "ia"; /** APN type for Emergency PDN. This is not an IA apn, but is used * for access to carrier services in an emergency call situation. */ public static final String APN_TYPE_EMERGENCY = "emergency"; /** APN type for Mission Critical Services */ public static final String APN_TYPE_MCX = "mcx"; /** APN type for XCAP */ public static final String APN_TYPE_XCAP = "xcap"; /** APN type for OEM_PAID networks (Automotive PANS) */ public static final String APN_TYPE_OEM_PAID = "oem_paid"; /** APN type for OEM_PRIVATE networks (Automotive PANS) */ public static final String APN_TYPE_OEM_PRIVATE = "oem_private"; /** Array of all APN types */ public static final String[] APN_TYPES = {APN_TYPE_DEFAULT, APN_TYPE_MMS, APN_TYPE_SUPL, APN_TYPE_DUN, APN_TYPE_HIPRI, APN_TYPE_FOTA, APN_TYPE_IMS, APN_TYPE_CBS, APN_TYPE_IA, APN_TYPE_EMERGENCY, APN_TYPE_MCX, APN_TYPE_XCAP, APN_TYPE_OEM_PAID, APN_TYPE_OEM_PRIVATE, }; /** Array of APN types that are never user-editable */ private static final String[] ALWAYS_READ_ONLY_APN_TYPES = new String[] { APN_TYPE_OEM_PAID, APN_TYPE_OEM_PRIVATE, }; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); Loading Loading @@ -143,43 +76,6 @@ public class ApnEditor extends SettingsPreferenceFragment { } } /** * Fetch complete list of read only APN types. * * The list primarily comes from carrier config, but is also supplied by APN types which are * always read only. */ static String[] getReadOnlyApnTypes(PersistableBundle b) { String[] carrierReadOnlyApnTypes = b.getStringArray( CarrierConfigManager.KEY_READ_ONLY_APN_TYPES_STRING_ARRAY); return ArrayUtils.concat(String.class, carrierReadOnlyApnTypes, ALWAYS_READ_ONLY_APN_TYPES); } /** * Check if passed in array of APN types indicates all APN types * @param apnTypes array of APN types. "*" indicates all types. * @return true if all apn types are included in the array, false otherwise */ static boolean hasAllApns(String[] apnTypes) { if (ArrayUtils.isEmpty(apnTypes)) { return false; } final List apnList = Arrays.asList(apnTypes); if (apnList.contains(APN_TYPE_ALL)) { Log.d(TAG, "hasAllApns: true because apnList.contains(APN_TYPE_ALL)"); return true; } for (String apn : APN_TYPES) { if (!apnList.contains(apn)) { return false; } } Log.d(TAG, "hasAllApns: true"); return true; } @Override public int getMetricsCategory() { return SettingsEnums.APN_EDITOR; Loading src/com/android/settings/network/apn/ApnSettings.java +3 −2 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import kotlin.Unit; import java.util.ArrayList; import java.util.List; /** Handle each different apn setting. */ public class ApnSettings extends RestrictedSettingsFragment Loading Loading @@ -135,9 +136,9 @@ public class ApnSettings extends RestrictedSettingsFragment mHideImsApn = b.getBoolean(CarrierConfigManager.KEY_HIDE_IMS_APN_BOOL); mAllowAddingApns = b.getBoolean(CarrierConfigManager.KEY_ALLOW_ADDING_APNS_BOOL); if (mAllowAddingApns) { final String[] readOnlyApnTypes = ApnEditor.getReadOnlyApnTypes(b); final List<String> readOnlyApnTypes = ApnTypes.getReadOnlyApnTypes(b); // if no apn type can be edited, do not allow adding APNs if (ApnEditor.hasAllApns(readOnlyApnTypes)) { if (ApnTypes.hasAllApnTypes(readOnlyApnTypes)) { Log.d(TAG, "not allowing adding APN because all APN types are read only"); mAllowAddingApns = false; } Loading src/com/android/settings/network/apn/ApnStatus.kt +2 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.telephony.CarrierConfigManager import android.util.Log import com.android.settings.R import com.android.settings.network.apn.ApnTypes.getPreSelectedApnType import com.android.settings.network.apn.ApnTypes.getReadOnlyApnTypes private const val TAG = "ApnStatus" Loading Loading @@ -204,7 +205,7 @@ fun getCarrierCustomizedConfig( CarrierConfigManager.KEY_ALLOW_ADDING_APNS_BOOL ) val customizedConfig = CustomizedConfig( readOnlyApnTypes = ApnEditor.getReadOnlyApnTypes(b)?.toList() ?: emptyList(), readOnlyApnTypes = b.getReadOnlyApnTypes(), readOnlyApnFields = b.getStringArray( CarrierConfigManager.KEY_READ_ONLY_APN_FIELDS_STRING_ARRAY )?.toList() ?: emptyList(), Loading src/com/android/settings/network/apn/ApnTypes.kt +31 −3 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ package com.android.settings.network.apn import android.content.Context import android.os.PersistableBundle import android.telephony.CarrierConfigManager import android.telephony.data.ApnSetting import android.util.Log import android.widget.Toast Loading Loading @@ -51,9 +53,7 @@ object ApnTypes { private fun splitToList(apnType: String): List<String> { val types = apnType.split(',').map { it.trim().toLowerCase(Locale.current) } if (ApnSetting.TYPE_ALL_STRING in types || APN_TYPES.all { it in types }) { return listOf(ApnSetting.TYPE_ALL_STRING) } if (hasAllApnTypes(types)) return listOf(ApnSetting.TYPE_ALL_STRING) return APN_TYPES.filter { it in types } } Loading Loading @@ -132,4 +132,32 @@ object ApnTypes { private fun defaultPreSelectedApnTypes(readOnlyApnTypes: List<String>) = if (ApnSetting.TYPE_ALL_STRING in readOnlyApnTypes) emptyList() else PreSelectedTypes.filterNot { it in readOnlyApnTypes } /** Array of APN types that are never user-editable */ private val ALWAYS_READ_ONLY_APN_TYPES = arrayOf(ApnSetting.TYPE_OEM_PAID_STRING, ApnSetting.TYPE_OEM_PRIVATE_STRING) /** * Fetch complete list of read only APN types. * * The list primarily comes from carrier config, but is also supplied by APN types which are * always read only. */ @JvmStatic fun PersistableBundle.getReadOnlyApnTypes(): List<String> { val carrierReadOnlyApnTypes = getStringArray(CarrierConfigManager.KEY_READ_ONLY_APN_TYPES_STRING_ARRAY)?.toList() ?: emptyList() return carrierReadOnlyApnTypes + ALWAYS_READ_ONLY_APN_TYPES } /** * Check if passed in array of APN types indicates all APN types * * @param apnTypes array of APN types. "*" indicates all types. * @return true if all apn types are included in the array, false otherwise */ @JvmStatic fun hasAllApnTypes(apnTypes: List<String>): Boolean = ApnSetting.TYPE_ALL_STRING in apnTypes || APN_TYPES.all { it in apnTypes } } tests/spa_unit/src/com/android/settings/network/apn/ApnTypesTest.kt +62 −0 Original line number Diff line number Diff line Loading @@ -91,6 +91,68 @@ class ApnTypesTest { assertThat(apnType).isEqualTo("default,mms,supl,hipri,fota,cbs,xcap") } @Test fun hasAllApnTypes_allString() { val apnTypes = listOf(ApnSetting.TYPE_ALL_STRING) val hasAllApnTypes = ApnTypes.hasAllApnTypes(apnTypes) assertThat(hasAllApnTypes).isTrue() } @Test fun hasAllApnTypes_allTypes() { val apnTypes = listOf( ApnSetting.TYPE_DEFAULT_STRING, ApnSetting.TYPE_MMS_STRING, ApnSetting.TYPE_SUPL_STRING, ApnSetting.TYPE_DUN_STRING, ApnSetting.TYPE_HIPRI_STRING, ApnSetting.TYPE_FOTA_STRING, ApnSetting.TYPE_IMS_STRING, ApnSetting.TYPE_CBS_STRING, ApnSetting.TYPE_IA_STRING, ApnSetting.TYPE_EMERGENCY_STRING, ApnSetting.TYPE_MCX_STRING, ApnSetting.TYPE_XCAP_STRING, ApnSetting.TYPE_VSIM_STRING, ApnSetting.TYPE_BIP_STRING, ApnSetting.TYPE_ENTERPRISE_STRING, ApnSetting.TYPE_OEM_PAID_STRING, ApnSetting.TYPE_OEM_PRIVATE_STRING, ) val hasAllApnTypes = ApnTypes.hasAllApnTypes(apnTypes) assertThat(hasAllApnTypes).isTrue() } @Test fun hasAllApnTypes_allTypesExceptDefault() { val apnTypes = listOf( ApnSetting.TYPE_MMS_STRING, ApnSetting.TYPE_SUPL_STRING, ApnSetting.TYPE_DUN_STRING, ApnSetting.TYPE_HIPRI_STRING, ApnSetting.TYPE_FOTA_STRING, ApnSetting.TYPE_IMS_STRING, ApnSetting.TYPE_CBS_STRING, ApnSetting.TYPE_IA_STRING, ApnSetting.TYPE_EMERGENCY_STRING, ApnSetting.TYPE_MCX_STRING, ApnSetting.TYPE_XCAP_STRING, ApnSetting.TYPE_VSIM_STRING, ApnSetting.TYPE_BIP_STRING, ApnSetting.TYPE_ENTERPRISE_STRING, ApnSetting.TYPE_OEM_PAID_STRING, ApnSetting.TYPE_OEM_PRIVATE_STRING, ) val hasAllApnTypes = ApnTypes.hasAllApnTypes(apnTypes) assertThat(hasAllApnTypes).isFalse() } private companion object { const val APN_TYPE = "type" } Loading Loading
src/com/android/settings/network/apn/ApnEditor.java +0 −104 Original line number Diff line number Diff line Loading @@ -23,88 +23,21 @@ import android.app.settings.SettingsEnums; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.os.PersistableBundle; import android.os.UserManager; import android.provider.Telephony; import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; import android.util.Log; import androidx.annotation.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.settings.SettingsPreferenceFragment; import com.android.settings.spa.SpaActivity; import java.util.Arrays; import java.util.List; /** Use to edit apn settings. */ public class ApnEditor extends SettingsPreferenceFragment { private static final String TAG = ApnEditor.class.getSimpleName(); /** * APN types for data connections. These are usage categories for an APN * entry. One APN entry may support multiple APN types, eg, a single APN * may service regular internet traffic ("default") as well as MMS-specific * connections.<br/> * APN_TYPE_ALL is a special type to indicate that this APN entry can * service all data connections. */ public static final String APN_TYPE_ALL = "*"; /** APN type for default data traffic */ public static final String APN_TYPE_DEFAULT = "default"; /** APN type for MMS traffic */ public static final String APN_TYPE_MMS = "mms"; /** APN type for SUPL assisted GPS */ public static final String APN_TYPE_SUPL = "supl"; /** APN type for DUN traffic */ public static final String APN_TYPE_DUN = "dun"; /** APN type for HiPri traffic */ public static final String APN_TYPE_HIPRI = "hipri"; /** APN type for FOTA */ public static final String APN_TYPE_FOTA = "fota"; /** APN type for IMS */ public static final String APN_TYPE_IMS = "ims"; /** APN type for CBS */ public static final String APN_TYPE_CBS = "cbs"; /** APN type for IA Initial Attach APN */ public static final String APN_TYPE_IA = "ia"; /** APN type for Emergency PDN. This is not an IA apn, but is used * for access to carrier services in an emergency call situation. */ public static final String APN_TYPE_EMERGENCY = "emergency"; /** APN type for Mission Critical Services */ public static final String APN_TYPE_MCX = "mcx"; /** APN type for XCAP */ public static final String APN_TYPE_XCAP = "xcap"; /** APN type for OEM_PAID networks (Automotive PANS) */ public static final String APN_TYPE_OEM_PAID = "oem_paid"; /** APN type for OEM_PRIVATE networks (Automotive PANS) */ public static final String APN_TYPE_OEM_PRIVATE = "oem_private"; /** Array of all APN types */ public static final String[] APN_TYPES = {APN_TYPE_DEFAULT, APN_TYPE_MMS, APN_TYPE_SUPL, APN_TYPE_DUN, APN_TYPE_HIPRI, APN_TYPE_FOTA, APN_TYPE_IMS, APN_TYPE_CBS, APN_TYPE_IA, APN_TYPE_EMERGENCY, APN_TYPE_MCX, APN_TYPE_XCAP, APN_TYPE_OEM_PAID, APN_TYPE_OEM_PRIVATE, }; /** Array of APN types that are never user-editable */ private static final String[] ALWAYS_READ_ONLY_APN_TYPES = new String[] { APN_TYPE_OEM_PAID, APN_TYPE_OEM_PRIVATE, }; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); Loading Loading @@ -143,43 +76,6 @@ public class ApnEditor extends SettingsPreferenceFragment { } } /** * Fetch complete list of read only APN types. * * The list primarily comes from carrier config, but is also supplied by APN types which are * always read only. */ static String[] getReadOnlyApnTypes(PersistableBundle b) { String[] carrierReadOnlyApnTypes = b.getStringArray( CarrierConfigManager.KEY_READ_ONLY_APN_TYPES_STRING_ARRAY); return ArrayUtils.concat(String.class, carrierReadOnlyApnTypes, ALWAYS_READ_ONLY_APN_TYPES); } /** * Check if passed in array of APN types indicates all APN types * @param apnTypes array of APN types. "*" indicates all types. * @return true if all apn types are included in the array, false otherwise */ static boolean hasAllApns(String[] apnTypes) { if (ArrayUtils.isEmpty(apnTypes)) { return false; } final List apnList = Arrays.asList(apnTypes); if (apnList.contains(APN_TYPE_ALL)) { Log.d(TAG, "hasAllApns: true because apnList.contains(APN_TYPE_ALL)"); return true; } for (String apn : APN_TYPES) { if (!apnList.contains(apn)) { return false; } } Log.d(TAG, "hasAllApns: true"); return true; } @Override public int getMetricsCategory() { return SettingsEnums.APN_EDITOR; Loading
src/com/android/settings/network/apn/ApnSettings.java +3 −2 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import kotlin.Unit; import java.util.ArrayList; import java.util.List; /** Handle each different apn setting. */ public class ApnSettings extends RestrictedSettingsFragment Loading Loading @@ -135,9 +136,9 @@ public class ApnSettings extends RestrictedSettingsFragment mHideImsApn = b.getBoolean(CarrierConfigManager.KEY_HIDE_IMS_APN_BOOL); mAllowAddingApns = b.getBoolean(CarrierConfigManager.KEY_ALLOW_ADDING_APNS_BOOL); if (mAllowAddingApns) { final String[] readOnlyApnTypes = ApnEditor.getReadOnlyApnTypes(b); final List<String> readOnlyApnTypes = ApnTypes.getReadOnlyApnTypes(b); // if no apn type can be edited, do not allow adding APNs if (ApnEditor.hasAllApns(readOnlyApnTypes)) { if (ApnTypes.hasAllApnTypes(readOnlyApnTypes)) { Log.d(TAG, "not allowing adding APN because all APN types are read only"); mAllowAddingApns = false; } Loading
src/com/android/settings/network/apn/ApnStatus.kt +2 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.telephony.CarrierConfigManager import android.util.Log import com.android.settings.R import com.android.settings.network.apn.ApnTypes.getPreSelectedApnType import com.android.settings.network.apn.ApnTypes.getReadOnlyApnTypes private const val TAG = "ApnStatus" Loading Loading @@ -204,7 +205,7 @@ fun getCarrierCustomizedConfig( CarrierConfigManager.KEY_ALLOW_ADDING_APNS_BOOL ) val customizedConfig = CustomizedConfig( readOnlyApnTypes = ApnEditor.getReadOnlyApnTypes(b)?.toList() ?: emptyList(), readOnlyApnTypes = b.getReadOnlyApnTypes(), readOnlyApnFields = b.getStringArray( CarrierConfigManager.KEY_READ_ONLY_APN_FIELDS_STRING_ARRAY )?.toList() ?: emptyList(), Loading
src/com/android/settings/network/apn/ApnTypes.kt +31 −3 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ package com.android.settings.network.apn import android.content.Context import android.os.PersistableBundle import android.telephony.CarrierConfigManager import android.telephony.data.ApnSetting import android.util.Log import android.widget.Toast Loading Loading @@ -51,9 +53,7 @@ object ApnTypes { private fun splitToList(apnType: String): List<String> { val types = apnType.split(',').map { it.trim().toLowerCase(Locale.current) } if (ApnSetting.TYPE_ALL_STRING in types || APN_TYPES.all { it in types }) { return listOf(ApnSetting.TYPE_ALL_STRING) } if (hasAllApnTypes(types)) return listOf(ApnSetting.TYPE_ALL_STRING) return APN_TYPES.filter { it in types } } Loading Loading @@ -132,4 +132,32 @@ object ApnTypes { private fun defaultPreSelectedApnTypes(readOnlyApnTypes: List<String>) = if (ApnSetting.TYPE_ALL_STRING in readOnlyApnTypes) emptyList() else PreSelectedTypes.filterNot { it in readOnlyApnTypes } /** Array of APN types that are never user-editable */ private val ALWAYS_READ_ONLY_APN_TYPES = arrayOf(ApnSetting.TYPE_OEM_PAID_STRING, ApnSetting.TYPE_OEM_PRIVATE_STRING) /** * Fetch complete list of read only APN types. * * The list primarily comes from carrier config, but is also supplied by APN types which are * always read only. */ @JvmStatic fun PersistableBundle.getReadOnlyApnTypes(): List<String> { val carrierReadOnlyApnTypes = getStringArray(CarrierConfigManager.KEY_READ_ONLY_APN_TYPES_STRING_ARRAY)?.toList() ?: emptyList() return carrierReadOnlyApnTypes + ALWAYS_READ_ONLY_APN_TYPES } /** * Check if passed in array of APN types indicates all APN types * * @param apnTypes array of APN types. "*" indicates all types. * @return true if all apn types are included in the array, false otherwise */ @JvmStatic fun hasAllApnTypes(apnTypes: List<String>): Boolean = ApnSetting.TYPE_ALL_STRING in apnTypes || APN_TYPES.all { it in apnTypes } }
tests/spa_unit/src/com/android/settings/network/apn/ApnTypesTest.kt +62 −0 Original line number Diff line number Diff line Loading @@ -91,6 +91,68 @@ class ApnTypesTest { assertThat(apnType).isEqualTo("default,mms,supl,hipri,fota,cbs,xcap") } @Test fun hasAllApnTypes_allString() { val apnTypes = listOf(ApnSetting.TYPE_ALL_STRING) val hasAllApnTypes = ApnTypes.hasAllApnTypes(apnTypes) assertThat(hasAllApnTypes).isTrue() } @Test fun hasAllApnTypes_allTypes() { val apnTypes = listOf( ApnSetting.TYPE_DEFAULT_STRING, ApnSetting.TYPE_MMS_STRING, ApnSetting.TYPE_SUPL_STRING, ApnSetting.TYPE_DUN_STRING, ApnSetting.TYPE_HIPRI_STRING, ApnSetting.TYPE_FOTA_STRING, ApnSetting.TYPE_IMS_STRING, ApnSetting.TYPE_CBS_STRING, ApnSetting.TYPE_IA_STRING, ApnSetting.TYPE_EMERGENCY_STRING, ApnSetting.TYPE_MCX_STRING, ApnSetting.TYPE_XCAP_STRING, ApnSetting.TYPE_VSIM_STRING, ApnSetting.TYPE_BIP_STRING, ApnSetting.TYPE_ENTERPRISE_STRING, ApnSetting.TYPE_OEM_PAID_STRING, ApnSetting.TYPE_OEM_PRIVATE_STRING, ) val hasAllApnTypes = ApnTypes.hasAllApnTypes(apnTypes) assertThat(hasAllApnTypes).isTrue() } @Test fun hasAllApnTypes_allTypesExceptDefault() { val apnTypes = listOf( ApnSetting.TYPE_MMS_STRING, ApnSetting.TYPE_SUPL_STRING, ApnSetting.TYPE_DUN_STRING, ApnSetting.TYPE_HIPRI_STRING, ApnSetting.TYPE_FOTA_STRING, ApnSetting.TYPE_IMS_STRING, ApnSetting.TYPE_CBS_STRING, ApnSetting.TYPE_IA_STRING, ApnSetting.TYPE_EMERGENCY_STRING, ApnSetting.TYPE_MCX_STRING, ApnSetting.TYPE_XCAP_STRING, ApnSetting.TYPE_VSIM_STRING, ApnSetting.TYPE_BIP_STRING, ApnSetting.TYPE_ENTERPRISE_STRING, ApnSetting.TYPE_OEM_PAID_STRING, ApnSetting.TYPE_OEM_PRIVATE_STRING, ) val hasAllApnTypes = ApnTypes.hasAllApnTypes(apnTypes) assertThat(hasAllApnTypes).isFalse() } private companion object { const val APN_TYPE = "type" } Loading