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

Commit f2bbe8d0 authored by Ling Ma's avatar Ling Ma
Browse files

Add anomaly report for invalid APN configuration

when read from APN db.

Bug: 232632618
Test: manually verified
Change-Id: Ib8af6bfff7459a8ccef6184422684cbd00b38eca
parent c2e87eef
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -218,6 +218,8 @@ public class DataConfigManager extends Handler {
    /** DeviceConfig key of anomaly report threshold for DataNetwork stuck in handover state. */
    private static final String KEY_ANOMALY_NETWORK_HANDOVER_TIMEOUT =
            "anomaly_network_handover_timeout";
    /** DeviceConfig key of anomaly report: True for enabling APN config invalidity detection */
    private static final String KEY_ANOMALY_APN_CONFIG_ENABLED = "anomaly_apn_config_enabled";

    /** Anomaly report thresholds for frequent setup data call failure. */
    private EventFrequency mSetupDataCallAnomalyReportThreshold;
@@ -260,6 +262,11 @@ public class DataConfigManager extends Handler {
     */
    private int mNetworkHandoverTimeout;

    /**
     * True if enabled anomaly detection for APN config that's read from {@link DataProfileManager}
     */
    private boolean mIsApnConfigAnomalyReportEnabled;

    private @NonNull final Phone mPhone;
    private @NonNull final String mLogTag;

@@ -423,6 +430,8 @@ public class DataConfigManager extends Handler {
                DEFAULT_NETWORK_TRANSIT_STATE_TIMEOUT_MS);
        mNetworkHandoverTimeout = properties.getInt(
                KEY_ANOMALY_NETWORK_HANDOVER_TIMEOUT, DEFAULT_NETWORK_TRANSIT_STATE_TIMEOUT_MS);
        mIsApnConfigAnomalyReportEnabled = properties.getBoolean(
                KEY_ANOMALY_APN_CONFIG_ENABLED, false);
    }

    /**
@@ -883,6 +892,14 @@ public class DataConfigManager extends Handler {
        return mNetworkHandoverTimeout;
    }

    /**
     * @return {@code true} if enabled anomaly report for invalid APN config
     * at {@link DataProfileManager}
     */
    public boolean isApnConfigAnomalyReportEnabled() {
        return mIsApnConfigAnomalyReportEnabled;
    }

    /**
     * Get the TCP config string, used by {@link LinkProperties#setTcpBufferSizes(String)}.
     * The config string will have the following form, with values in bytes:
@@ -1261,6 +1278,7 @@ public class DataConfigManager extends Handler {
        pw.println("mNetworkConnectingTimeout=" + mNetworkConnectingTimeout);
        pw.println("mNetworkDisconnectingTimeout=" + mNetworkDisconnectingTimeout);
        pw.println("mNetworkHandoverTimeout=" + mNetworkHandoverTimeout);
        pw.println("mIsApnConfigAnomalyReportEnabled=" + mIsApnConfigAnomalyReportEnabled);
        pw.println("Metered APN types=" + mMeteredApnTypes.stream()
                .map(ApnSetting::getApnTypeString).collect(Collectors.joining(",")));
        pw.println("Roaming metered APN types=" + mRoamingMeteredApnTypes.stream()
+89 −1
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import android.os.Message;
import android.provider.Telephony;
import android.telephony.Annotation;
import android.telephony.Annotation.NetworkType;
import android.telephony.AnomalyReporter;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@@ -55,6 +56,7 @@ import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;

@@ -242,7 +244,7 @@ public class DataProfileManager extends Handler {
                loge("Cannot access APN database through telephony provider.");
                return;
            }

            boolean isInternetSupported = false;
            while (cursor.moveToNext()) {
                ApnSetting apn = ApnSetting.makeApnSetting(cursor);
                if (apn != null) {
@@ -253,9 +255,21 @@ public class DataProfileManager extends Handler {
                            .build();
                    profiles.add(dataProfile);
                    log("Added " + dataProfile);

                    isInternetSupported |= apn.canHandleType(ApnSetting.TYPE_DEFAULT);
                    if (mDataConfigManager.isApnConfigAnomalyReportEnabled()) {
                        checkApnSetting(apn);
                    }
                }
            }
            cursor.close();

            if (!isInternetSupported
                    && !profiles.isEmpty() // APN database has been read successfully
                    && mDataConfigManager.isApnConfigAnomalyReportEnabled()) {
                reportAnomaly("Carrier doesn't support internet.",
                        "9af73e18-b523-4dc5-adab-363eb6613305");
            }
        }

        // Check if any of the profile already supports ENTERPRISE, if not, check if DPC has
@@ -302,6 +316,10 @@ public class DataProfileManager extends Handler {

        dedupeDataProfiles(profiles);

        if (mDataConfigManager.isApnConfigAnomalyReportEnabled()) {
            checkDataProfiles(profiles);
        }

        log("Found " + profiles.size() + " data profiles. profiles = " + profiles);

        boolean profilesChanged = false;
@@ -747,6 +765,65 @@ public class DataProfileManager extends Handler {
        }
    }

    /**
     * Trigger anomaly report if APN Setting contains invalid info.
     *
     * @param setting The Apn setting to be checked.
     */
    private void checkApnSetting(@NonNull ApnSetting setting) {
        if (setting.canHandleType(ApnSetting.TYPE_MMS)) {
            if (setting.getMmsc() == null) {
                reportAnomaly("MMS is supported but no MMSC configured " + setting,
                        "9af73e18-b523-4dc5-adab-19d86c6a3685");
            } else if (!setting.getMmsc().toString().matches("^https?:\\/\\/.+")) {
                reportAnomaly("Apn config mmsc should start with http but is "
                                + setting.getMmsc(),
                        "9af73e18-b523-4dc5-adab-ec754d959d4d");
            }
            if (!TextUtils.isEmpty(setting.getMmsProxyAddressAsString())
                    && setting.getMmsProxyAddressAsString().matches("^https?:\\/\\/.+")) {
                reportAnomaly("Apn config mmsc_proxy should NOT start with http but is "
                                + setting.getMmsc(), "9af73e18-b523-4dc5-adab-ec754d959d4d");
            }
        }
    }

    /**
     * Trigger anomaly report if any two Apn Settings share the same APN name while having
     * overlapped network types.
     *
     * @param profiles The list of data profiles to be checked.
     */
    private void checkDataProfiles(List<DataProfile> profiles) {
        for (int i = 0; i < profiles.size(); i++) {
            ApnSetting a = profiles.get(i).getApnSetting();
            if (a == null) continue;
            if ((a.getNetworkTypeBitmask() | a.getLingeringNetworkTypeBitmask())
                    != a.getLingeringNetworkTypeBitmask()) {
                reportAnomaly("Apn[" + a.getApnName()
                                + "] supported network should be a subset of the lingering network",
                        "9af73e18-b523-4dc5-adab-4bb24355d838");
            }
            for (int j = i + 1; j < profiles.size(); j++) {
                ApnSetting b = profiles.get(j).getApnSetting();
                if (b == null) continue;
                String apnNameA = a.getApnName();
                String apnNameB = b.getApnName();
                if (TextUtils.equals(apnNameA, apnNameB)
                        // TelephonyManager.NETWORK_TYPE_BITMASK_UNKNOWN means all network types
                        && (a.getNetworkTypeBitmask()
                        == (int) TelephonyManager.NETWORK_TYPE_BITMASK_UNKNOWN
                        || b.getNetworkTypeBitmask()
                        == (int) TelephonyManager.NETWORK_TYPE_BITMASK_UNKNOWN
                        || (a.getNetworkTypeBitmask() & b.getNetworkTypeBitmask()) != 0)) {
                    reportAnomaly("Found overlapped network type under the APN name"
                                    + a.getApnName(),
                            "9af73e18-b523-4dc5-adab-4bb24555d839");
                }
            }
        }
    }

    /**
     * Merge two data profiles if possible.
     *
@@ -885,6 +962,17 @@ public class DataProfileManager extends Handler {
        mDataProfileManagerCallbacks.remove(callback);
    }

    /**
     * Trigger the anomaly report with the specified UUID.
     *
     * @param anomalyMsg Description of the event
     * @param uuid UUID associated with that event
     */
    private void reportAnomaly(@NonNull String anomalyMsg, @NonNull String uuid) {
        logl(anomalyMsg);
        AnomalyReporter.reportAnomaly(UUID.fromString(uuid), anomalyMsg, mPhone.getCarrierId());
    }

    /**
     * Log debug messages.
     * @param s debug messages