diff --git a/src/com/android/settings/network/apn/ApnEditor.java b/src/com/android/settings/network/apn/ApnEditor.java index 533fd292289..5ae280c37cc 100644 --- a/src/com/android/settings/network/apn/ApnEditor.java +++ b/src/com/android/settings/network/apn/ApnEditor.java @@ -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.
- * 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); @@ -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; diff --git a/src/com/android/settings/network/apn/ApnSettings.java b/src/com/android/settings/network/apn/ApnSettings.java index 0e3c3a4362d..55de5db5029 100644 --- a/src/com/android/settings/network/apn/ApnSettings.java +++ b/src/com/android/settings/network/apn/ApnSettings.java @@ -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 @@ -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 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; } diff --git a/src/com/android/settings/network/apn/ApnStatus.kt b/src/com/android/settings/network/apn/ApnStatus.kt index 68588bbd975..d33c8b3cc73 100644 --- a/src/com/android/settings/network/apn/ApnStatus.kt +++ b/src/com/android/settings/network/apn/ApnStatus.kt @@ -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" @@ -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(), diff --git a/src/com/android/settings/network/apn/ApnTypes.kt b/src/com/android/settings/network/apn/ApnTypes.kt index 4f84ac7fa70..ee192b262b4 100644 --- a/src/com/android/settings/network/apn/ApnTypes.kt +++ b/src/com/android/settings/network/apn/ApnTypes.kt @@ -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 @@ -51,9 +53,7 @@ object ApnTypes { private fun splitToList(apnType: String): List { 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 } } @@ -132,4 +132,32 @@ object ApnTypes { private fun defaultPreSelectedApnTypes(readOnlyApnTypes: List) = 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 { + 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): Boolean = + ApnSetting.TYPE_ALL_STRING in apnTypes || APN_TYPES.all { it in apnTypes } } diff --git a/tests/spa_unit/src/com/android/settings/network/apn/ApnTypesTest.kt b/tests/spa_unit/src/com/android/settings/network/apn/ApnTypesTest.kt index ce0d0f55ffd..13b5167095c 100644 --- a/tests/spa_unit/src/com/android/settings/network/apn/ApnTypesTest.kt +++ b/tests/spa_unit/src/com/android/settings/network/apn/ApnTypesTest.kt @@ -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" }