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

Commit c95c2ee8 authored by Malcolm Chen's avatar Malcolm Chen
Browse files

Allow validation when switching data back from CBRS to primary.

We used to assume switching data from CBRS back to primary subscription
never needs validation. But we want to remove that assmption so that to
provide more choices to external caller.

Bug: 131384820
Test: manual
Change-Id: I7d92601cdb42e87afb9b255f907562644ce9956c
Merged-In: I7d92601cdb42e87afb9b255f907562644ce9956c
parent 57d9bb44
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -94,7 +94,7 @@ public class CellularNetworkValidator {
    /**
     * Check whether this feature is supported or not.
     */
    public static boolean isValidationFeatureSupported() {
    public boolean isValidationFeatureSupported() {
        return PhoneConfigurationManager.getInstance().getCurrentPhoneCapability()
                .validationBeforeSwitchSupported;
    }
+52 −30
Original line number Diff line number Diff line
@@ -104,7 +104,8 @@ public class PhoneSwitcher extends Handler {
    @VisibleForTesting
    public final PhoneStateListener mPhoneStateListener;
    private final CellularNetworkValidator mValidator;
    private final CellularNetworkValidator.ValidationCallback mValidationCallback =
    @VisibleForTesting
    public final CellularNetworkValidator.ValidationCallback mValidationCallback =
            (validated, subId) -> Message.obtain(PhoneSwitcher.this,
                    EVENT_NETWORK_VALIDATION_DONE, subId, validated ? 1 : 0).sendToTarget();
    @UnsupportedAppUsage
@@ -405,11 +406,7 @@ public class PhoneSwitcher extends Handler {
                boolean needValidation = (msg.arg2 == 1);
                ISetOpportunisticDataCallback callback =
                        (ISetOpportunisticDataCallback) msg.obj;
                if (SubscriptionManager.isUsableSubscriptionId(subId)) {
                setOpportunisticDataSubscription(subId, needValidation, callback);
                } else {
                    unsetOpportunisticDataSubscription(callback);
                }
                break;
            }
            case EVENT_RADIO_AVAILABLE: {
@@ -909,18 +906,31 @@ public class PhoneSwitcher extends Handler {
    /**
     * Set opportunistic data subscription. It's an indication to switch Internet data to this
     * subscription. It has to be an active subscription, and PhoneSwitcher will try to validate
     * it first if needed.
     * it first if needed. If subId is DEFAULT_SUBSCRIPTION_ID, it means we are un-setting
     * opportunistic data sub and switch data back to primary sub.
     *
     * @param subId the opportunistic data subscription to switch to. pass DEFAULT_SUBSCRIPTION_ID
     *              if un-setting it.
     * @param needValidation whether Telephony will wait until the network is validated by
     *              connectivity service before switching data to it. More details see
     *              {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED}.
     * @param callback Callback will be triggered once it succeeds or failed.
     *                 Pass null if don't care about the result.
     */
    private void setOpportunisticDataSubscription(int subId, boolean needValidation,
            ISetOpportunisticDataCallback callback) {
        if (!mSubscriptionController.isActiveSubId(subId)) {
        if (!mSubscriptionController.isActiveSubId(subId)
                && subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
            log("Can't switch data to inactive subId " + subId);
            sendSetOpptCallbackHelper(callback, SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION);
            return;
        }

        int subIdToValidate = (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)
                ? mPrimaryDataSubId : subId;

        if (mValidator.isValidating()
                && (!needValidation || subId != mValidator.getSubIdInValidation())) {
                && (!needValidation || subIdToValidate != mValidator.getSubIdInValidation())) {
            mValidator.stopValidation();
        }

@@ -931,11 +941,11 @@ public class PhoneSwitcher extends Handler {

        // If validation feature is not supported, set it directly. Otherwise,
        // start validation on the subscription first.
        if (CellularNetworkValidator.isValidationFeatureSupported() && needValidation) {
        if (mValidator.isValidationFeatureSupported() && needValidation) {
            logDataSwitchEvent(subId, TelephonyEvent.EventState.EVENT_STATE_START,
                    DataSwitch.Reason.DATA_SWITCH_REASON_CBRS);
            mSetOpptSubCallback = callback;
            mValidator.validate(subId, DEFAULT_VALIDATION_EXPIRATION_TIME,
            mValidator.validate(subIdToValidate, DEFAULT_VALIDATION_EXPIRATION_TIME,
                    false, mValidationCallback);
        } else {
            setOpportunisticSubscriptionInternal(subId);
@@ -943,21 +953,6 @@ public class PhoneSwitcher extends Handler {
        }
    }

    /**
     * Unset opportunistic data subscription. It's an indication to switch Internet data back
     * from opportunistic subscription to primary subscription.
     */
    private void unsetOpportunisticDataSubscription(ISetOpportunisticDataCallback callback) {
        if (mValidator.isValidating()) {
            mValidator.stopValidation();
        }

        // Set mOpptDataSubId back to DEFAULT_SUBSCRIPTION_ID. This will trigger
        // data switch to mPrimaryDataSubId.
        setOpportunisticSubscriptionInternal(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
        sendSetOpptCallbackHelper(callback, SET_OPPORTUNISTIC_SUB_SUCCESS);
    }

    private void sendSetOpptCallbackHelper(ISetOpportunisticDataCallback callback, int result) {
        if (callback == null) return;
        try {
@@ -983,18 +978,45 @@ public class PhoneSwitcher extends Handler {
    }

    private void onValidationDone(int subId, boolean passed) {
        log("Network validation " + (passed ? "passed" : "failed")
        log("onValidationDone: " + (passed ? "passed" : "failed")
                + " on subId " + subId);
        if (passed) setOpportunisticSubscriptionInternal(subId);
        int resultForCallBack;

        if (!mSubscriptionController.isActiveSubId(subId)) {
            log("onValidationDone: subId " + subId + " is no longer active");
            resultForCallBack = SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION;
        } else if (!passed) {
            resultForCallBack = SET_OPPORTUNISTIC_SUB_VALIDATION_FAILED;
        } else {
            if (mSubscriptionController.isOpportunistic(subId)) {
                setOpportunisticSubscriptionInternal(subId);
            } else {
                // Switching data back to primary subscription.
                setOpportunisticSubscriptionInternal(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
            }
            resultForCallBack = SET_OPPORTUNISTIC_SUB_SUCCESS;
        }

        // Trigger callback if needed
        sendSetOpptCallbackHelper(mSetOpptSubCallback, passed ? SET_OPPORTUNISTIC_SUB_SUCCESS
                : SET_OPPORTUNISTIC_SUB_VALIDATION_FAILED);
        sendSetOpptCallbackHelper(mSetOpptSubCallback, resultForCallBack);
        mSetOpptSubCallback = null;
    }

    /**
     * Notify PhoneSwitcher to try to switch data to an opportunistic subscription.
     *
     * Set opportunistic data subscription. It's an indication to switch Internet data to this
     * subscription. It has to be an active subscription, and PhoneSwitcher will try to validate
     * it first if needed. If subId is DEFAULT_SUBSCRIPTION_ID, it means we are un-setting
     * opportunistic data sub and switch data back to primary sub.
     *
     * @param subId the opportunistic data subscription to switch to. pass DEFAULT_SUBSCRIPTION_ID
     *              if un-setting it.
     * @param needValidation whether Telephony will wait until the network is validated by
     *              connectivity service before switching data to it. More details see
     *              {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED}.
     * @param callback Callback will be triggered once it succeeds or failed.
     *                 Pass null if don't care about the result.
     */
    public void trySetOpportunisticDataSubscription(int subId, boolean needValidation,
            ISetOpportunisticDataCallback callback) {
+51 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.internal.telephony;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
@@ -472,6 +473,56 @@ public class PhoneSwitcherTest extends TelephonyTest {

    }

    @Test
    @SmallTest
    public void testSetPreferredDataWithValidation() throws Exception {
        final int numPhones = 2;
        final int maxActivePhones = 1;
        doReturn(true).when(mMockRadioConfig).isSetPreferredDataCommandSupported();
        initialize(numPhones, maxActivePhones);

        // Phone 0 has sub 1, phone 1 has sub 2.
        // Sub 1 is default data sub.
        // Both are active subscriptions are active sub, as they are in both active slots.
        setSlotIndexToSubId(0, 1);
        setSlotIndexToSubId(1, 2);
        setDefaultDataSubId(1);
        // Mark sub 2 as opportunistic.
        doReturn(true).when(mSubscriptionController).isOpportunistic(2);

        // Phone 0 (sub 1) should be activated as it has default data sub.
        assertEquals(0, mPhoneSwitcher.getPreferredDataPhoneId());

        // Set sub 2 as preferred sub should make phone 1 activated and phone 0 deactivated.
        mPhoneSwitcher.trySetOpportunisticDataSubscription(2, true, null);
        waitABit();
        verify(mCellularNetworkValidator).validate(eq(2), anyInt(), eq(false),
                eq(mPhoneSwitcher.mValidationCallback));
        // Validation failed. Preferred data sub should remain 1, data phone should remain 0.
        mPhoneSwitcher.mValidationCallback.onValidationResult(false, 2);
        waitABit();
        assertEquals(0, mPhoneSwitcher.getPreferredDataPhoneId());

        // Validation succeeds. Preferred data sub changes to 2, data phone changes to 1.
        mPhoneSwitcher.trySetOpportunisticDataSubscription(2, true, null);
        waitABit();
        mPhoneSwitcher.mValidationCallback.onValidationResult(true, 2);
        waitABit();
        assertEquals(1, mPhoneSwitcher.getPreferredDataPhoneId());

        // Switching data back to primary (subId 1).
        mPhoneSwitcher.trySetOpportunisticDataSubscription(
                SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, true, null);
        waitABit();
        verify(mCellularNetworkValidator).validate(eq(1), anyInt(), eq(false),
                eq(mPhoneSwitcher.mValidationCallback));
        mPhoneSwitcher.mValidationCallback.onValidationResult(true, 1);
        waitABit();
        assertEquals(0, mPhoneSwitcher.getPreferredDataPhoneId());

        mHandlerThread.quit();
    }

    @Test
    @SmallTest
    public void testNonDefaultDataPhoneInCall() throws Exception {
+1 −0
Original line number Diff line number Diff line
@@ -527,6 +527,7 @@ public abstract class TelephonyTest {
        // CellularNetworkValidator
        doReturn(SubscriptionManager.INVALID_PHONE_INDEX)
                .when(mCellularNetworkValidator).getSubIdInValidation();
        doReturn(true).when(mCellularNetworkValidator).isValidationFeatureSupported();

        //Use reflection to mock singletons
        replaceInstance(CallManager.class, "INSTANCE", null, mCallManager);