Merge "Unify and merge two hasAllApns()" into main

This commit is contained in:
Chaohui Wang
2024-11-13 03:32:28 +00:00
committed by Android (Google) Code Review
5 changed files with 98 additions and 110 deletions

View File

@@ -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);
@@ -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;

View File

@@ -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<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;
}

View File

@@ -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(),

View File

@@ -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<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 }
}
@@ -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 }
}

View File

@@ -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"
}