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

Commit 2ea75685 authored by Chaohui Wang's avatar Chaohui Wang Committed by Android (Google) Code Review
Browse files

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

parents 70b962a8 4e4ee743
Loading
Loading
Loading
Loading
+0 −104
Original line number Diff line number Diff line
@@ -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;
+3 −2
Original line number Diff line number Diff line
@@ -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;
            }
+2 −1
Original line number Diff line number Diff line
@@ -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(),
+31 −3
Original line number Diff line number Diff line
@@ -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 }
}
+62 −0
Original line number Diff line number Diff line
@@ -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"
    }