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

Commit 5f852753 authored by Thomas Stuart's avatar Thomas Stuart Committed by Automerger Merge Worker
Browse files

Merge "fix No Call Preference bug afer switch to DSDS mode" into tm-dev am: 0e19c38b

parents 283739dc 0e19c38b
Loading
Loading
Loading
Loading
+18 −0
Original line number Original line Diff line number Diff line
@@ -397,6 +397,24 @@ public class PhoneConfigurationManager {
                registerForRadioState(phone);
                registerForRadioState(phone);
                phone.mCi.onSlotActiveStatusChange(SubscriptionManager.isValidPhoneId(phoneId));
                phone.mCi.onSlotActiveStatusChange(SubscriptionManager.isValidPhoneId(phoneId));
            }
            }

            // When the user enables DSDS mode, the default VOICE and SMS subId should be switched
            // to "No Preference".  Doing so will sync the network/sim settings and telephony.
            // (see b/198123192)
            if (numOfActiveModems > oldNumOfActiveModems && numOfActiveModems == 2) {
                Log.i(LOG_TAG, " onMultiSimConfigChanged: DSDS mode enabled; "
                        + "setting VOICE & SMS subId to -1 (No Preference)");

                //Set the default VOICE subId to -1 ("No Preference")
                SubscriptionController.getInstance().setDefaultVoiceSubId(
                        SubscriptionManager.INVALID_SUBSCRIPTION_ID);

                //TODO:: Set the default SMS sub to "No Preference". Tracking this bug (b/227386042)
            } else {
                Log.i(LOG_TAG,
                        "onMultiSimConfigChanged: DSDS mode NOT detected.  NOT setting the "
                                + "default VOICE and SMS subId to -1 (No Preference)");
            }
        }
        }
    }
    }


+101 −45
Original line number Original line Diff line number Diff line
@@ -26,6 +26,7 @@ import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.never;
@@ -37,6 +38,7 @@ import android.os.AsyncResult;
import android.os.Handler;
import android.os.Handler;
import android.os.Message;
import android.os.Message;
import android.telephony.PhoneCapability;
import android.telephony.PhoneCapability;
import android.telephony.SubscriptionManager;
import android.test.suitebuilder.annotation.SmallTest;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper;
@@ -46,6 +48,7 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;


@RunWith(AndroidTestingRunner.class)
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
@TestableLooper.RunWithLooper
@@ -148,29 +151,27 @@ public class PhoneConfigurationManagerTest extends TelephonyTest {
    @SmallTest
    @SmallTest
    public void testSwitchMultiSimConfig_dsdsCapable_noRebootRequired() throws Exception {
    public void testSwitchMultiSimConfig_dsdsCapable_noRebootRequired() throws Exception {
        init(1);
        init(1);
        testSwitchFromSingleToDualSimModeNoReboot();
    }

    @Test
    @SmallTest
    public void testSwitchMultiSimConfig_multiSimToSingleSim() throws Exception {
        mPhones = new Phone[]{mPhone, mPhone1};
        replaceInstance(PhoneFactory.class, "sPhones", null, mPhones);
        init(2);
        verify(mMockCi0, times(1)).registerForAvailable(any(), anyInt(), any());
        verify(mMockCi0, times(1)).registerForAvailable(any(), anyInt(), any());
        verify(mMockCi1, times(1)).registerForAvailable(any(), anyInt(), any());


        // Register for multi SIM config change.
        // Register for multi SIM config change.
        mPcm.registerForMultiSimConfigChange(mHandler, EVENT_MULTI_SIM_CONFIG_CHANGED, null);
        mPcm.registerForMultiSimConfigChange(mHandler, EVENT_MULTI_SIM_CONFIG_CHANGED, null);
        verify(mHandler, never()).sendMessageAtTime(any(), anyLong());
        verify(mHandler, never()).sendMessageAtTime(any(), anyLong());


        // Try switching to dual SIM. Shouldn't work as we haven't indicated DSDS is supported.
        // Switch to single sim.
        mPcm.switchMultiSimConfig(2);
        verify(mMockRadioConfig, never()).setNumOfLiveModems(anyInt(), any());

        // Send static capability back to indicate DSDS is supported.
        clearInvocations(mMockRadioConfig);
        testGetDsdsCapability();
        // testGetDsdsCapability leads to another call to registerForAvailable()
        verify(mMockCi0, times(2)).registerForAvailable(any(), anyInt(), any());

        // Try to switch to DSDS.
        setRebootRequiredForConfigSwitch(false);
        setRebootRequiredForConfigSwitch(false);
        mPhones = new Phone[]{mPhone, mPhone1};
        mPcm.switchMultiSimConfig(1);
        replaceInstance(PhoneFactory.class, "sPhones", null, mPhones);
        mPcm.switchMultiSimConfig(2);
        ArgumentCaptor<Message> captor = ArgumentCaptor.forClass(Message.class);
        ArgumentCaptor<Message> captor = ArgumentCaptor.forClass(Message.class);
        verify(mMockRadioConfig).setNumOfLiveModems(eq(2), captor.capture());
        verify(mMockRadioConfig).setNumOfLiveModems(eq(1), captor.capture());


        // Send message back to indicate switch success.
        // Send message back to indicate switch success.
        Message message = captor.getValue();
        Message message = captor.getValue();
@@ -179,50 +180,107 @@ public class PhoneConfigurationManagerTest extends TelephonyTest {
        processAllMessages();
        processAllMessages();


        // Verify set system property being called.
        // Verify set system property being called.
        verify(mMi).setMultiSimProperties(2);
        verify(mMi).setMultiSimProperties(1);
        verify(mMi).notifyPhoneFactoryOnMultiSimConfigChanged(any(), eq(2));
        verify(mMi).notifyPhoneFactoryOnMultiSimConfigChanged(any(), eq(1));


        // Capture and verify registration notification.
        // Capture and verify registration notification.
        verify(mHandler).sendMessageAtTime(captor.capture(), anyLong());
        verify(mHandler).sendMessageAtTime(captor.capture(), anyLong());
        message = captor.getValue();
        message = captor.getValue();
        assertEquals(EVENT_MULTI_SIM_CONFIG_CHANGED, message.what);
        assertEquals(EVENT_MULTI_SIM_CONFIG_CHANGED, message.what);
        assertEquals(2, ((AsyncResult) message.obj).result);
        assertEquals(1, ((AsyncResult) message.obj).result);


        // Capture and verify broadcast.
        // Capture and verify broadcast.
        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
        verify(mContext).sendBroadcast(intentCaptor.capture());
        verify(mContext).sendBroadcast(intentCaptor.capture());
        Intent intent = intentCaptor.getValue();
        Intent intent = intentCaptor.getValue();
        assertEquals(ACTION_MULTI_SIM_CONFIG_CHANGED, intent.getAction());
        assertEquals(ACTION_MULTI_SIM_CONFIG_CHANGED, intent.getAction());
        assertEquals(2, intent.getIntExtra(
        assertEquals(1, intent.getIntExtra(
                EXTRA_ACTIVE_SIM_SUPPORTED_COUNT, 0));
                EXTRA_ACTIVE_SIM_SUPPORTED_COUNT, 0));


        // Verify registerForAvailable() and onSlotActiveStatusChange() are called for the second
        // Verify clearSubInfoRecord() and onSlotActiveStatusChange() are called for second phone,
        // phone, and not for the first phone (registerForAvailable() was already called twice
        // and not for the first one
        // earlier so verify that the count is still at 2)
        verify(mSubscriptionController).clearSubInfoRecord(1);
        verify(mMockCi0, times(2)).registerForAvailable(any(), anyInt(), any());
        verify(mMockCi1).onSlotActiveStatusChange(anyBoolean());
        verify(mSubscriptionController, never()).clearSubInfoRecord(0);
        verify(mMockCi0, never()).onSlotActiveStatusChange(anyBoolean());
        verify(mMockCi0, never()).onSlotActiveStatusChange(anyBoolean());
        verify(mMockCi1, times(1)).registerForAvailable(any(), anyInt(), any());

        verify(mMockCi1, times(1)).onSlotActiveStatusChange(anyBoolean());
        // Verify onPhoneRemoved() gets called on MultiSimSettingController phone
        verify(mMultiSimSettingController).onPhoneRemoved();
    }
    }


    @Test
    @Test
    @SmallTest
    @SmallTest
    public void testSwitchMultiSimConfig_multiSimToSingleSim() throws Exception {
    public void testNoCallPreferenceIsSetAfterSwitchToDsdsMode() throws Exception {
        mPhones = new Phone[]{mPhone, mPhone1};
        final int startingDefaultSubscriptionId = 2; // arbitrary value (can't be -1 which
        replaceInstance(PhoneFactory.class, "sPhones", null, mPhones);
        // represents the "No Call Preference" value)
        init(2);

        /*
            TL;DR:  the following mockito code block dynamically changes the last call to the getter

            doAnswer(invocation -> {
                Integer value = (Integer) invocation.getArguments()[0];
                Mockito.when(object.getter()).thenReturn(value);
                return null;
            }).when(object).setter(anyInt());

            read the code block as, whenever we call the setter, change the Mock call
            of the getter to whatever argument value we last passed to the setter.

            ex.)    object.set( 2 )   --> next call to object.get() will return 2
         */

        // setup mocks for  VOICE mSubscriptionController. getter/setter
        doAnswer(invocation -> {
            Integer value = (Integer) invocation.getArguments()[0];
            Mockito.when(mSubscriptionController.getDefaultVoiceSubId()).thenReturn(value);
            return null;
        }).when(mSubscriptionController).setDefaultVoiceSubId(anyInt());

        // start off the phone stat with 1 active sim. reset values for new test.
        init(1);

        mSubscriptionController.setDefaultVoiceSubId(startingDefaultSubscriptionId);

        // assert the mSubscriptionController registers the change
        assertEquals(startingDefaultSubscriptionId, mSubscriptionController.getDefaultVoiceSubId());

        // Perform the switch to DSDS mode and ensure all existing checks are not altered
        testSwitchFromSingleToDualSimModeNoReboot();

        // VOICE check
        assertEquals(SubscriptionManager.INVALID_SUBSCRIPTION_ID /* No CALL Preference value */,
                mSubscriptionController.getDefaultVoiceSubId()); //  Now, when the user goes to
        // place a CALL, they will be prompted on which sim to use.
    }

    /**
     * must call init(1) from the parent test before calling this helper test
     * @throws Exception
     */
    public void testSwitchFromSingleToDualSimModeNoReboot() throws Exception {
        verify(mMockCi0, times(1)).registerForAvailable(any(), anyInt(), any());
        verify(mMockCi0, times(1)).registerForAvailable(any(), anyInt(), any());
        verify(mMockCi1, times(1)).registerForAvailable(any(), anyInt(), any());


        // Register for multi SIM config change.
        // Register for multi SIM config change.
        mPcm.registerForMultiSimConfigChange(mHandler, EVENT_MULTI_SIM_CONFIG_CHANGED, null);
        mPcm.registerForMultiSimConfigChange(mHandler, EVENT_MULTI_SIM_CONFIG_CHANGED, null);
        verify(mHandler, never()).sendMessageAtTime(any(), anyLong());
        verify(mHandler, never()).sendMessageAtTime(any(), anyLong());


        // Switch to single sim.
        // Try switching to dual SIM. Shouldn't work as we haven't indicated DSDS is supported.
        mPcm.switchMultiSimConfig(2);
        verify(mMockRadioConfig, never()).setNumOfLiveModems(anyInt(), any());

        // Send static capability back to indicate DSDS is supported.
        clearInvocations(mMockRadioConfig);
        testGetDsdsCapability();
        // testGetDsdsCapability leads to another call to registerForAvailable()
        verify(mMockCi0, times(2)).registerForAvailable(any(), anyInt(), any());

        // Try to switch to DSDS.
        setRebootRequiredForConfigSwitch(false);
        setRebootRequiredForConfigSwitch(false);
        mPcm.switchMultiSimConfig(1);
        mPhones = new Phone[]{mPhone, mPhone1};
        replaceInstance(PhoneFactory.class, "sPhones", null, mPhones);
        mPcm.switchMultiSimConfig(2);
        ArgumentCaptor<Message> captor = ArgumentCaptor.forClass(Message.class);
        ArgumentCaptor<Message> captor = ArgumentCaptor.forClass(Message.class);
        verify(mMockRadioConfig).setNumOfLiveModems(eq(1), captor.capture());
        verify(mMockRadioConfig).setNumOfLiveModems(eq(2), captor.capture());


        // Send message back to indicate switch success.
        // Send message back to indicate switch success.
        Message message = captor.getValue();
        Message message = captor.getValue();
@@ -231,31 +289,29 @@ public class PhoneConfigurationManagerTest extends TelephonyTest {
        processAllMessages();
        processAllMessages();


        // Verify set system property being called.
        // Verify set system property being called.
        verify(mMi).setMultiSimProperties(1);
        verify(mMi).setMultiSimProperties(2);
        verify(mMi).notifyPhoneFactoryOnMultiSimConfigChanged(any(), eq(1));
        verify(mMi).notifyPhoneFactoryOnMultiSimConfigChanged(any(), eq(2));


        // Capture and verify registration notification.
        // Capture and verify registration notification.
        verify(mHandler).sendMessageAtTime(captor.capture(), anyLong());
        verify(mHandler).sendMessageAtTime(captor.capture(), anyLong());
        message = captor.getValue();
        message = captor.getValue();
        assertEquals(EVENT_MULTI_SIM_CONFIG_CHANGED, message.what);
        assertEquals(EVENT_MULTI_SIM_CONFIG_CHANGED, message.what);
        assertEquals(1, ((AsyncResult) message.obj).result);
        assertEquals(2, ((AsyncResult) message.obj).result);


        // Capture and verify broadcast.
        // Capture and verify broadcast.
        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
        verify(mContext).sendBroadcast(intentCaptor.capture());
        verify(mContext).sendBroadcast(intentCaptor.capture());
        Intent intent = intentCaptor.getValue();
        Intent intent = intentCaptor.getValue();
        assertEquals(ACTION_MULTI_SIM_CONFIG_CHANGED, intent.getAction());
        assertEquals(ACTION_MULTI_SIM_CONFIG_CHANGED, intent.getAction());
        assertEquals(1, intent.getIntExtra(
        assertEquals(2, intent.getIntExtra(
                EXTRA_ACTIVE_SIM_SUPPORTED_COUNT, 0));
                EXTRA_ACTIVE_SIM_SUPPORTED_COUNT, 0));


        // Verify clearSubInfoRecord() and onSlotActiveStatusChange() are called for second phone,
        // Verify registerForAvailable() and onSlotActiveStatusChange() are called for the second
        // and not for the first one
        // phone, and not for the first phone (registerForAvailable() was already called twice
        verify(mSubscriptionController).clearSubInfoRecord(1);
        // earlier so verify that the count is still at 2)
        verify(mMockCi1).onSlotActiveStatusChange(anyBoolean());
        verify(mMockCi0, times(2)).registerForAvailable(any(), anyInt(), any());
        verify(mSubscriptionController, never()).clearSubInfoRecord(0);
        verify(mMockCi0, never()).onSlotActiveStatusChange(anyBoolean());
        verify(mMockCi0, never()).onSlotActiveStatusChange(anyBoolean());

        verify(mMockCi1, times(1)).registerForAvailable(any(), anyInt(), any());
        // Verify onPhoneRemoved() gets called on MultiSimSettingController phone
        verify(mMockCi1, times(1)).onSlotActiveStatusChange(anyBoolean());
        verify(mMultiSimSettingController).onPhoneRemoved();
    }
    }
}
}