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

Commit 81b21b4c authored by Ling Ma's avatar Ling Ma Committed by Android (Google) Code Review
Browse files

Merge "Configure auto data switch score table" into udc-qpr-dev

parents c65b068c 08c3ef76
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -2264,7 +2264,7 @@ public abstract class Phone extends Handler implements PhoneInternalInterface {
     *
     * @return Current signal strength as SignalStrength
     */
    public SignalStrength getSignalStrength() {
    public @NonNull SignalStrength getSignalStrength() {
        SignalStrengthController ssc = getSignalStrengthController();
        if (ssc == null) {
            return new SignalStrength();
+94 −9
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import android.telephony.Annotation.NetCapability;
import android.telephony.Annotation.NetworkType;
import android.telephony.CarrierConfigManager;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyDisplayInfo;
import android.telephony.TelephonyManager;
@@ -199,8 +200,6 @@ public class DataConfigManager extends Handler {
            "anomaly_setup_data_call_failure";
    /** DeviceConfig key of anomaly report threshold for frequent network-unwanted call. */
    private static final String KEY_ANOMALY_NETWORK_UNWANTED = "anomaly_network_unwanted";
    /** DeviceConfig key of anomaly report threshold for frequent change of preferred network. */
    private static final String KEY_ANOMALY_QNS_CHANGE_NETWORK = "anomaly_qns_change_network";
    /** DeviceConfig key of anomaly report threshold for invalid QNS params. */
    private static final String KEY_ANOMALY_QNS_PARAM = "anomaly_qns_param";
    /** DeviceConfig key of anomaly report threshold for DataNetwork stuck in connecting state. */
@@ -214,13 +213,8 @@ public class DataConfigManager extends Handler {
            "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";
    /** DeviceConfig key of the time threshold in ms for defining a network status to be stable. **/
    private static final String KEY_AUTO_DATA_SWITCH_AVAILABILITY_STABILITY_TIME_THRESHOLD =
            "auto_data_switch_availability_stability_time_threshold";
    /** DeviceConfig key of the maximum number of retries when a validation for switching failed.**/
    private static final String KEY_AUTO_DATA_SWITCH_VALIDATION_MAX_RETRY =
            "auto_data_switch_validation_max_retry";

    /** Invalid auto data switch score. */
    private static final int INVALID_AUTO_DATA_SWITCH_SCORE = -1;
    /** Anomaly report thresholds for frequent setup data call failure. */
    private EventFrequency mSetupDataCallAnomalyReportThreshold;

@@ -301,6 +295,12 @@ public class DataConfigManager extends Handler {
    private @NonNull final List<HandoverRule> mHandoverRuleList = new ArrayList<>();
    /** {@code True} keep IMS network in case of moving to non VOPS area; {@code false} otherwise.*/
    private boolean mShouldKeepNetworkUpInNonVops = false;
    /**
     * A map of network types to the estimated downlink values by signal strength 0 - 4 for that
     * network type
     */
    private @NonNull final @DataConfigNetworkType Map<String, int[]>
            mAutoDataSwitchNetworkTypeSignalMap = new ConcurrentHashMap<>();

    /**
     * Constructor
@@ -452,6 +452,7 @@ public class DataConfigManager extends Handler {
        updateBandwidths();
        updateTcpBuffers();
        updateHandoverRules();
        updateAutoDataSwitchConfig();

        log("Carrier config updated. Config is " + (isConfigCarrierSpecific() ? "" : "not ")
                + "carrier specific.");
@@ -917,6 +918,84 @@ public class DataConfigManager extends Handler {
        return mIsApnConfigAnomalyReportEnabled;
    }

    /**
     * Update the network type and signal strength score table for auto data switch decisions.
     */
    private void updateAutoDataSwitchConfig() {
        synchronized (this) {
            mAutoDataSwitchNetworkTypeSignalMap.clear();
            final PersistableBundle table = mCarrierConfig.getPersistableBundle(
                    CarrierConfigManager.KEY_AUTO_DATA_SWITCH_RAT_SIGNAL_SCORE_BUNDLE);
            String[] networkTypeKeys = {
                    DATA_CONFIG_NETWORK_TYPE_GPRS,
                    DATA_CONFIG_NETWORK_TYPE_EDGE,
                    DATA_CONFIG_NETWORK_TYPE_UMTS,
                    DATA_CONFIG_NETWORK_TYPE_CDMA,
                    DATA_CONFIG_NETWORK_TYPE_1xRTT,
                    DATA_CONFIG_NETWORK_TYPE_EVDO_0,
                    DATA_CONFIG_NETWORK_TYPE_EVDO_A,
                    DATA_CONFIG_NETWORK_TYPE_HSDPA,
                    DATA_CONFIG_NETWORK_TYPE_HSUPA,
                    DATA_CONFIG_NETWORK_TYPE_HSPA,
                    DATA_CONFIG_NETWORK_TYPE_EVDO_B,
                    DATA_CONFIG_NETWORK_TYPE_EHRPD,
                    DATA_CONFIG_NETWORK_TYPE_IDEN,
                    DATA_CONFIG_NETWORK_TYPE_LTE,
                    DATA_CONFIG_NETWORK_TYPE_HSPAP,
                    DATA_CONFIG_NETWORK_TYPE_GSM,
                    DATA_CONFIG_NETWORK_TYPE_TD_SCDMA,
                    DATA_CONFIG_NETWORK_TYPE_NR_NSA,
                    DATA_CONFIG_NETWORK_TYPE_NR_NSA_MMWAVE,
                    DATA_CONFIG_NETWORK_TYPE_NR_SA,
                    DATA_CONFIG_NETWORK_TYPE_NR_SA_MMWAVE
            };
            if (table != null) {
                for (String networkType : networkTypeKeys) {
                    int[] scores = table.getIntArray(networkType);
                    if (scores != null
                            && scores.length == SignalStrength.NUM_SIGNAL_STRENGTH_BINS) {
                        for (int i = 0; i < scores.length; i++) {
                            if (scores[i] < 0) {
                                loge("Auto switch score must not < 0 for network type "
                                        + networkType);
                                break;
                            }
                            if (i == scores.length - 1) {
                                mAutoDataSwitchNetworkTypeSignalMap.put(networkType, scores);
                            }
                        }
                    } else {
                        loge("Auto switch score table should specify "
                                + SignalStrength.NUM_SIGNAL_STRENGTH_BINS
                                + " signal strength for network type " + networkType);
                    }
                }
            }
        }
    }

    /**
     * @param displayInfo The displayed network info.
     * @param signalStrength The signal strength.
     * @return Score base on network type and signal strength to inform auto data switch decision.
     */
    public int getAutoDataSwitchScore(@NonNull TelephonyDisplayInfo displayInfo,
            @NonNull SignalStrength signalStrength) {
        int[] scores = mAutoDataSwitchNetworkTypeSignalMap.get(
                getDataConfigNetworkType(displayInfo));
        return scores != null ? scores[signalStrength.getLevel()] : INVALID_AUTO_DATA_SWITCH_SCORE;
    }

    /**
     * @return The tolerated gap of score for auto data switch decision, larger than which the
     * device will switch to the SIM with higher score. If 0, the device always switch to the higher
     * score SIM. If < 0, the network type and signal strength based auto switch is disabled.
     */
    public int getAutoDataSwitchScoreTolerance() {
        return mResources.getInteger(com.android.internal.R.integer
                .auto_data_switch_score_tolerance);
    }

    /**
     * @return The maximum number of retries when a validation for switching failed.
     */
@@ -1324,9 +1403,15 @@ public class DataConfigManager extends Handler {
        pw.println("mNetworkDisconnectingTimeout=" + mNetworkDisconnectingTimeout);
        pw.println("mNetworkHandoverTimeout=" + mNetworkHandoverTimeout);
        pw.println("mIsApnConfigAnomalyReportEnabled=" + mIsApnConfigAnomalyReportEnabled);
        pw.println("Auto data switch:");
        pw.increaseIndent();
        pw.println("getAutoDataSwitchScoreTolerance=" + getAutoDataSwitchScoreTolerance());
        mAutoDataSwitchNetworkTypeSignalMap.forEach((key, value) -> pw.println(key + ":"
                + Arrays.toString(value)));
        pw.println("getAutoDataSwitchAvailabilityStabilityTimeThreshold="
                + getAutoDataSwitchAvailabilityStabilityTimeThreshold());
        pw.println("getAutoDataSwitchValidationMaxRetry=" + getAutoDataSwitchValidationMaxRetry());
        pw.decreaseIndent();
        pw.println("Metered APN types=" + mMeteredApnTypes.stream()
                .map(ApnSetting::getApnTypeString).collect(Collectors.joining(",")));
        pw.println("Roaming metered APN types=" + mRoamingMeteredApnTypes.stream()
+49 −0
Original line number Diff line number Diff line
@@ -20,10 +20,16 @@ import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import android.os.Looper;
import android.os.PersistableBundle;
import android.telephony.CarrierConfigManager;
import android.telephony.SignalStrength;
import android.telephony.TelephonyDisplayInfo;
import android.telephony.TelephonyManager;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;

@@ -96,4 +102,47 @@ public class DataConfigManagerTest extends TelephonyTest {
        assertThat(invalidFormat3.timeWindow).isEqualTo(defaultValue.timeWindow);
        assertThat(invalidFormat3.eventNumOccurrence).isEqualTo(defaultValue.eventNumOccurrence);
    }

    @Test
    public void testParseAutoDataSwitchScoreTable() {
        SignalStrength signalStrength = mock(SignalStrength.class);
        int tolerance = 100;
        PersistableBundle auto_data_switch_rat_signal_score_string_bundle = new PersistableBundle();
        auto_data_switch_rat_signal_score_string_bundle.putIntArray(
                "NR_NSA_MMWAVE", new int[]{10000, 10227, 12488, 15017, 15278});
        auto_data_switch_rat_signal_score_string_bundle.putIntArray(
                "LTE", new int[]{-3731, 5965, 8618, 11179, 13384});
        mBundle.putPersistableBundle(
                CarrierConfigManager.KEY_AUTO_DATA_SWITCH_RAT_SIGNAL_SCORE_BUNDLE,
                auto_data_switch_rat_signal_score_string_bundle);

        mContextFixture.putIntResource(com.android.internal.R.integer
                .auto_data_switch_score_tolerance, tolerance);

        mDataConfigManagerUT.sendEmptyMessage(1/*EVENT_CARRIER_CONFIG_CHANGED*/);
        processAllMessages();

        assertThat(mDataConfigManagerUT.getAutoDataSwitchScoreTolerance()).isEqualTo(tolerance);

        // Verify NSA_MMWAVE
        doReturn(SignalStrength.SIGNAL_STRENGTH_POOR).when(signalStrength).getLevel();
        assertThat(mDataConfigManagerUT.getAutoDataSwitchScore(new TelephonyDisplayInfo(
                        TelephonyManager.NETWORK_TYPE_LTE,
                        TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED, false/*isRoaming*/),
                signalStrength)).isEqualTo(10227);
        // Verify if entry contains any invalid negative scores, should yield -1.
        doReturn(SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN).when(signalStrength).getLevel();
        assertThat(mDataConfigManagerUT.getAutoDataSwitchScore(new TelephonyDisplayInfo(
                        TelephonyManager.NETWORK_TYPE_LTE,
                        TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE, false/*isRoaming*/),
                signalStrength))
                .isEqualTo(-1/*INVALID_AUTO_DATA_SWITCH_SCORE*/);
        // Verify non-existent entry should yield -1
        doReturn(SignalStrength.SIGNAL_STRENGTH_POOR).when(signalStrength).getLevel();
        assertThat(mDataConfigManagerUT.getAutoDataSwitchScore(new TelephonyDisplayInfo(
                        TelephonyManager.NETWORK_TYPE_EDGE,
                        TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE, false/*isRoaming*/),
                signalStrength))
                .isEqualTo(-1/*INVALID_AUTO_DATA_SWITCH_SCORE*/);
    }
}