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

Commit 592e9428 authored by Malcolm Chen's avatar Malcolm Chen
Browse files

For back to back setPreferredDataCall, send failure on first callback.

If setPreferredDataSubscriptionId call is received while Telephony is
validating another subscription, we'll always stop previous validation
and failure will be sent to previous callback. Then we'll process the
new request.

Bug: 137297807
Test: unittest
Change-Id: Ib82d26ee7fc9cbc3bb2ce3e1ca46f5f1d17db7d8
Merged-In: Ib82d26ee7fc9cbc3bb2ce3e1ca46f5f1d17db7d8
parent 200623a0
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -1131,12 +1131,17 @@ public class PhoneSwitcher extends Handler {
            return;
        }

        // Remove EVENT_NETWORK_VALIDATION_DONE. Don't handle validation result of previously subId
        // if queued.
        removeMessages(EVENT_NETWORK_VALIDATION_DONE);

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

        if (mValidator.isValidating()
                && (!needValidation || subIdToValidate != mValidator.getSubIdInValidation())) {
        if (mValidator.isValidating()) {
            mValidator.stopValidation();
            sendSetOpptCallbackHelper(mSetOpptSubCallback, SET_OPPORTUNISTIC_SUB_VALIDATION_FAILED);
            mSetOpptSubCallback = null;
        }

        if (subId == mOpptDataSubId) {
+109 −0
Original line number Diff line number Diff line
@@ -16,6 +16,10 @@

package com.android.internal.telephony;

import static android.telephony.TelephonyManager.SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION;
import static android.telephony.TelephonyManager.SET_OPPORTUNISTIC_SUB_SUCCESS;
import static android.telephony.TelephonyManager.SET_OPPORTUNISTIC_SUB_VALIDATION_FAILED;

import static com.android.internal.telephony.PhoneSwitcher.EVENT_DATA_ENABLED_CHANGED;
import static com.android.internal.telephony.PhoneSwitcher.EVENT_PRECISE_CALL_STATE_CHANGED;

@@ -94,6 +98,10 @@ public class PhoneSwitcherTest extends TelephonyTest {
    private GsmCdmaCall mHoldingCall;
    @Mock
    private GsmCdmaCall mInactiveCall;
    @Mock
    private ISetOpportunisticDataCallback mSetOpptDataCallback1;
    @Mock
    private ISetOpportunisticDataCallback mSetOpptDataCallback2;

    // The thread that mPhoneSwitcher will handle events in.
    private HandlerThread mHandlerThread;
@@ -872,6 +880,107 @@ public class PhoneSwitcherTest extends TelephonyTest {
        mHandlerThread.quit();
    }

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

        // Mark sub 2 as opportunistic.
        doReturn(true).when(mSubscriptionController).isOpportunistic(2);
        // 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);
        waitABit();

        // Validating on sub 10 which is inactive.
        mPhoneSwitcher.trySetOpportunisticDataSubscription(10, true, mSetOpptDataCallback1);
        waitABit();
        verify(mSetOpptDataCallback1).onComplete(SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION);

        // Switch to active subId without validating. Should always succeed.
        mPhoneSwitcher.trySetOpportunisticDataSubscription(2, false, mSetOpptDataCallback1);
        waitABit();
        verify(mSetOpptDataCallback1).onComplete(SET_OPPORTUNISTIC_SUB_SUCCESS);

        // Validating on sub 1 and fails.
        clearInvocations(mSetOpptDataCallback1);
        mPhoneSwitcher.trySetOpportunisticDataSubscription(1, true, mSetOpptDataCallback1);
        waitABit();
        mPhoneSwitcher.mValidationCallback.onValidationResult(false, 1);
        waitABit();
        verify(mSetOpptDataCallback1).onComplete(SET_OPPORTUNISTIC_SUB_VALIDATION_FAILED);

        // Validating on sub 2 and succeeds.
        mPhoneSwitcher.trySetOpportunisticDataSubscription(2, true, mSetOpptDataCallback2);
        waitABit();
        mPhoneSwitcher.mValidationCallback.onValidationResult(true, 2);
        waitABit();
        verify(mSetOpptDataCallback2).onComplete(SET_OPPORTUNISTIC_SUB_SUCCESS);

        // Switching data back to primary and validation fails.
        clearInvocations(mSetOpptDataCallback2);
        mPhoneSwitcher.trySetOpportunisticDataSubscription(
                SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, true, mSetOpptDataCallback2);
        waitABit();
        mPhoneSwitcher.mValidationCallback.onValidationResult(false, 1);
        waitABit();
        verify(mSetOpptDataCallback1).onComplete(SET_OPPORTUNISTIC_SUB_VALIDATION_FAILED);

        // Switching data back to primary and succeeds.
        clearInvocations(mSetOpptDataCallback2);
        mPhoneSwitcher.trySetOpportunisticDataSubscription(
                SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, true, mSetOpptDataCallback2);
        waitABit();
        mPhoneSwitcher.mValidationCallback.onValidationResult(true, 1);
        waitABit();
        verify(mSetOpptDataCallback2).onComplete(SET_OPPORTUNISTIC_SUB_SUCCESS);

        // Back to back call on same subId.
        clearInvocations(mSetOpptDataCallback1);
        clearInvocations(mSetOpptDataCallback2);
        mPhoneSwitcher.trySetOpportunisticDataSubscription(2, true, mSetOpptDataCallback1);
        waitABit();
        verify(mCellularNetworkValidator).validate(eq(2), anyInt(), eq(false),
                eq(mPhoneSwitcher.mValidationCallback));
        doReturn(true).when(mCellularNetworkValidator).isValidating();
        mPhoneSwitcher.trySetOpportunisticDataSubscription(2, true, mSetOpptDataCallback2);
        waitABit();
        verify(mSetOpptDataCallback1).onComplete(SET_OPPORTUNISTIC_SUB_VALIDATION_FAILED);
        verify(mSetOpptDataCallback2, never()).onComplete(anyInt());
        // Validation succeeds.
        doReturn(false).when(mCellularNetworkValidator).isValidating();
        mPhoneSwitcher.mValidationCallback.onValidationResult(true, 2);
        waitABit();
        verify(mSetOpptDataCallback2).onComplete(SET_OPPORTUNISTIC_SUB_SUCCESS);

        mPhoneSwitcher.trySetOpportunisticDataSubscription(
                SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false, null);
        waitABit();
        clearInvocations(mSetOpptDataCallback1);
        clearInvocations(mSetOpptDataCallback2);
        clearInvocations(mCellularNetworkValidator);
        // Back to back call, call 1 to switch to subId 2, call 2 to switch back.
        mPhoneSwitcher.trySetOpportunisticDataSubscription(2, true, mSetOpptDataCallback1);
        waitABit();
        verify(mCellularNetworkValidator).validate(eq(2), anyInt(), eq(false),
                eq(mPhoneSwitcher.mValidationCallback));
        doReturn(true).when(mCellularNetworkValidator).isValidating();
        mPhoneSwitcher.trySetOpportunisticDataSubscription(
                SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, true, mSetOpptDataCallback2);
        waitABit();
        // Call 1 should be cancelled and failed. Call 2 return success immediately as there's no
        // change.
        verify(mSetOpptDataCallback1).onComplete(SET_OPPORTUNISTIC_SUB_VALIDATION_FAILED);
        verify(mSetOpptDataCallback2).onComplete(SET_OPPORTUNISTIC_SUB_SUCCESS);
        mHandlerThread.quit();
    }

    /* Private utility methods start here */

    private void setAllPhonesInactive() {