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

Commit 7816b8a7 authored by Hui Wang's avatar Hui Wang Committed by Automerger Merge Worker
Browse files

Merge "Reset cell broadcast config cache on radio off or sub changed" into udc-dev am: 0ccbc010

parents 4fa2f6d2 0ccbc010
Loading
Loading
Loading
Loading
+66 −7
Original line number Original line Diff line number Diff line
@@ -20,9 +20,11 @@ import android.annotation.NonNull;
import android.os.AsyncResult;
import android.os.AsyncResult;
import android.os.Build;
import android.os.Build;
import android.os.Handler;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.Message;
import android.os.Message;
import android.telephony.CellBroadcastIdRange;
import android.telephony.CellBroadcastIdRange;
import android.telephony.SmsCbMessage;
import android.telephony.SmsCbMessage;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.TelephonyManager;


import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting;
@@ -46,6 +48,8 @@ public final class CellBroadcastConfigTracker extends StateMachine {
    private static final int EVENT_REQUEST = 1;
    private static final int EVENT_REQUEST = 1;
    private static final int EVENT_CONFIGURATION_DONE = 2;
    private static final int EVENT_CONFIGURATION_DONE = 2;
    private static final int EVENT_ACTIVATION_DONE = 3;
    private static final int EVENT_ACTIVATION_DONE = 3;
    private static final int EVENT_RADIO_OFF = 4;
    private static final int EVENT_SUBSCRIPTION_CHANGED = 5;


    private static final int SMS_CB_CODE_SCHEME_MIN = 0;
    private static final int SMS_CB_CODE_SCHEME_MIN = 0;
    private static final int SMS_CB_CODE_SCHEME_MAX = 255;
    private static final int SMS_CB_CODE_SCHEME_MAX = 255;
@@ -55,7 +59,16 @@ public final class CellBroadcastConfigTracker extends StateMachine {
    // Cache of current cell broadcast id ranges of 3gpp2
    // Cache of current cell broadcast id ranges of 3gpp2
    private List<CellBroadcastIdRange> mCbRanges3gpp2 = new CopyOnWriteArrayList<>();
    private List<CellBroadcastIdRange> mCbRanges3gpp2 = new CopyOnWriteArrayList<>();
    private Phone mPhone;
    private Phone mPhone;

    @VisibleForTesting
    public int mSubId;
    @VisibleForTesting
    public final SubscriptionManager.OnSubscriptionsChangedListener mSubChangedListener =
            new SubscriptionManager.OnSubscriptionsChangedListener() {
                @Override
                public void onSubscriptionsChanged() {
                    sendMessage(EVENT_SUBSCRIPTION_CHANGED);
                }
            };


    /**
    /**
     * The class is to present the request to set cell broadcast id ranges
     * The class is to present the request to set cell broadcast id ranges
@@ -98,6 +111,40 @@ public final class CellBroadcastConfigTracker extends StateMachine {
        }
        }
    }
    }


    /**
     * The default state.
     */
    private class DefaultState extends State {
        @Override
        public boolean processMessage(Message msg) {
            boolean retVal = HANDLED;
            if (DBG) {
                logd("DefaultState message:" + msg.what);
            }
            switch (msg.what) {
                case EVENT_RADIO_OFF:
                    resetConfig();
                    break;
                case EVENT_SUBSCRIPTION_CHANGED:
                    int subId = mPhone.getSubId();
                    if (mSubId != subId) {
                        log("SubId changed from " + mSubId + " to " + subId);
                        mSubId = subId;
                        resetConfig();
                    }
                    break;
                default:
                    log("unexpected message!");
                    break;

            }

            return retVal;
        }
    }

    private DefaultState mDefaultState = new DefaultState();

    /*
    /*
     * The idle state which does not have ongoing radio request.
     * The idle state which does not have ongoing radio request.
     */
     */
@@ -335,12 +382,19 @@ public final class CellBroadcastConfigTracker extends StateMachine {
    private void init(Phone phone) {
    private void init(Phone phone) {
        logd("init");
        logd("init");
        mPhone = phone;
        mPhone = phone;

        mSubId = mPhone.getSubId();
        addState(mIdleState);

        addState(mGsmConfiguringState);
        mPhone.registerForRadioOffOrNotAvailable(getHandler(), EVENT_RADIO_OFF, null);
        addState(mGsmActivatingState);
        mPhone.getContext().getSystemService(SubscriptionManager.class)
        addState(mCdmaConfiguringState);
                .addOnSubscriptionsChangedListener(new HandlerExecutor(getHandler()),
        addState(mCdmaActivatingState);
                        mSubChangedListener);

        addState(mDefaultState);
        addState(mIdleState, mDefaultState);
        addState(mGsmConfiguringState, mDefaultState);
        addState(mGsmActivatingState, mDefaultState);
        addState(mCdmaConfiguringState, mDefaultState);
        addState(mCdmaActivatingState, mDefaultState);
        setInitialState(mIdleState);
        setInitialState(mIdleState);
    }
    }


@@ -413,6 +467,11 @@ public final class CellBroadcastConfigTracker extends StateMachine {
        return newRanges;
        return newRanges;
    }
    }


    private void resetConfig() {
        mCbRanges3gpp.clear();
        mCbRanges3gpp2.clear();
    }

    private void setGsmConfig(List<CellBroadcastIdRange> ranges, Request request) {
    private void setGsmConfig(List<CellBroadcastIdRange> ranges, Request request) {
        if (DBG) {
        if (DBG) {
            logd("setGsmConfig with " + ranges);
            logd("setGsmConfig with " + ranges);
+2 −1
Original line number Original line Diff line number Diff line
@@ -247,7 +247,8 @@ public class GsmCdmaPhone extends Phone {
    private String mVmNumber;
    private String mVmNumber;
    private int mImeiType = IMEI_TYPE_UNKNOWN;
    private int mImeiType = IMEI_TYPE_UNKNOWN;


    CellBroadcastConfigTracker mCellBroadcastConfigTracker =
    @VisibleForTesting
    public CellBroadcastConfigTracker mCellBroadcastConfigTracker =
            CellBroadcastConfigTracker.make(this, null);
            CellBroadcastConfigTracker.make(this, null);


    private boolean mIsNullCipherAndIntegritySupported = false;
    private boolean mIsNullCipherAndIntegritySupported = false;
+2 −1
Original line number Original line Diff line number Diff line
@@ -183,7 +183,8 @@ public abstract class Phone extends Handler implements PhoneInternalInterface {
    protected static final int EVENT_RADIO_ON                    = 5;
    protected static final int EVENT_RADIO_ON                    = 5;
    protected static final int EVENT_GET_BASEBAND_VERSION_DONE   = 6;
    protected static final int EVENT_GET_BASEBAND_VERSION_DONE   = 6;
    protected static final int EVENT_USSD                        = 7;
    protected static final int EVENT_USSD                        = 7;
    protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE  = 8;
    @VisibleForTesting
    public static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE  = 8;
    private static final int EVENT_GET_SIM_STATUS_DONE           = 11;
    private static final int EVENT_GET_SIM_STATUS_DONE           = 11;
    protected static final int EVENT_SET_CALL_FORWARD_DONE       = 12;
    protected static final int EVENT_SET_CALL_FORWARD_DONE       = 12;
    protected static final int EVENT_GET_CALL_FORWARD_DONE       = 13;
    protected static final int EVENT_GET_CALL_FORWARD_DONE       = 13;
+496 −0

File added.

Preview size limit exceeded, changes collapsed.

+0 −376
Original line number Original line Diff line number Diff line
@@ -16,7 +16,6 @@


package com.android.internal.telephony;
package com.android.internal.telephony;


import static com.android.internal.telephony.CellBroadcastConfigTracker.mergeRangesAsNeeded;
import static com.android.internal.telephony.CommandsInterface.CF_ACTION_ENABLE;
import static com.android.internal.telephony.CommandsInterface.CF_ACTION_ENABLE;
import static com.android.internal.telephony.CommandsInterface.CF_REASON_UNCONDITIONAL;
import static com.android.internal.telephony.CommandsInterface.CF_REASON_UNCONDITIONAL;
import static com.android.internal.telephony.Phone.EVENT_ICC_CHANGED;
import static com.android.internal.telephony.Phone.EVENT_ICC_CHANGED;
@@ -33,7 +32,6 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.any;
@@ -70,7 +68,6 @@ import android.provider.DeviceConfig;
import android.telecom.VideoProfile;
import android.telecom.VideoProfile;
import android.telephony.AccessNetworkConstants;
import android.telephony.AccessNetworkConstants;
import android.telephony.CarrierConfigManager;
import android.telephony.CarrierConfigManager;
import android.telephony.CellBroadcastIdRange;
import android.telephony.CellIdentity;
import android.telephony.CellIdentity;
import android.telephony.CellIdentityCdma;
import android.telephony.CellIdentityCdma;
import android.telephony.CellIdentityGsm;
import android.telephony.CellIdentityGsm;
@@ -78,7 +75,6 @@ import android.telephony.LinkCapacityEstimate;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.RadioAccessFamily;
import android.telephony.RadioAccessFamily;
import android.telephony.ServiceState;
import android.telephony.ServiceState;
import android.telephony.SmsCbMessage;
import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.TelephonyManager;
import android.telephony.ims.ImsCallProfile;
import android.telephony.ims.ImsCallProfile;
@@ -90,9 +86,7 @@ import android.util.Log;


import androidx.test.filters.FlakyTest;
import androidx.test.filters.FlakyTest;


import com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo;
import com.android.internal.telephony.domainselection.DomainSelectionResolver;
import com.android.internal.telephony.domainselection.DomainSelectionResolver;
import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
import com.android.internal.telephony.imsphone.ImsPhone;
import com.android.internal.telephony.imsphone.ImsPhone;
import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
import com.android.internal.telephony.subscription.SubscriptionManagerService;
import com.android.internal.telephony.subscription.SubscriptionManagerService;
@@ -120,7 +114,6 @@ import org.mockito.InOrder;
import org.mockito.Mockito;
import org.mockito.Mockito;


import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.List;


@RunWith(AndroidTestingRunner.class)
@RunWith(AndroidTestingRunner.class)
@@ -2428,375 +2421,6 @@ public class GsmCdmaPhoneTest extends TelephonyTest {
        verify(mImsPhone).dial(eq("1234567890"), any(PhoneInternalInterface.DialArgs.class));
        verify(mImsPhone).dial(eq("1234567890"), any(PhoneInternalInterface.DialArgs.class));
    }
    }


    @Test
    @SmallTest
    public void testSetCellBroadcastIdRangesSuccess() throws Exception {
        final int[][] channelValues = {
            {0, 999}, {1000, 1003}, {1004, 0x0FFF}, {0x1000, 0x10FF}, {0x1100, 0x112F},
            {0x1130, 0x1900}, {0x1901, 0x9FFF}, {0xA000, 0xFFFE}, {0xFFFF, 0xFFFF}};
        List<CellBroadcastIdRange> ranges = new ArrayList<>();
        for (int i = 0; i < channelValues.length; i++) {
            ranges.add(new CellBroadcastIdRange(channelValues[i][0], channelValues[i][1],
                    SmsCbMessage.MESSAGE_FORMAT_3GPP, i > 0 ? true : false));
        }

        List<SmsBroadcastConfigInfo> gsmConfigs = new ArrayList<>();
        gsmConfigs.add(new SmsBroadcastConfigInfo(0, 999, 0, 255, false));
        gsmConfigs.add(new SmsBroadcastConfigInfo(1000, 0xFFFF, 0, 255, true));

        ArgumentCaptor<SmsBroadcastConfigInfo[]> gsmCaptor = ArgumentCaptor.forClass(
                SmsBroadcastConfigInfo[].class);
        ArgumentCaptor<Message> msgCaptor = ArgumentCaptor.forClass(Message.class);

        mPhoneUT.mCi = mMockCi;

        mPhoneUT.setCellBroadcastIdRanges(ranges, r -> assertTrue(
                TelephonyManager.CELL_BROADCAST_RESULT_SUCCESS == r));
        waitForMs(100);

        verify(mMockCi, times(1)).setGsmBroadcastConfig(gsmCaptor.capture(), msgCaptor.capture());
        List<SmsBroadcastConfigInfo> gsmArgs = Arrays.asList(
                (SmsBroadcastConfigInfo[]) gsmCaptor.getValue());
        assertEquals(gsmConfigs, gsmArgs);

        Message msg = msgCaptor.getValue();
        assertNotNull(msg);
        AsyncResult.forMessage(msg);
        msg.sendToTarget();
        waitForMs(100);

        verify(mMockCi, times(1)).setGsmBroadcastActivation(eq(true), msgCaptor.capture());

        msg = msgCaptor.getValue();
        assertNotNull(msg);
        AsyncResult.forMessage(msg);
        msg.sendToTarget();
        waitForMs(100);

        verify(mMockCi, never()).setCdmaBroadcastConfig(any(), any());
        verify(mMockCi, never()).setCdmaBroadcastActivation(anyBoolean(), any());

        assertEquals(mPhoneUT.getCellBroadcastIdRanges(), mergeRangesAsNeeded(ranges));

        //Verify to set cdma config and activate, but no more for gsm as no change
        for (int i = 0; i < channelValues.length; i++) {
            ranges.add(new CellBroadcastIdRange(channelValues[i][0], channelValues[i][1],
                    SmsCbMessage.MESSAGE_FORMAT_3GPP2, i > 0 ? true : false));
        }
        List<CdmaSmsBroadcastConfigInfo> cdmaConfigs = new ArrayList<>();
        cdmaConfigs.add(new CdmaSmsBroadcastConfigInfo(0, 999, 1, false));
        cdmaConfigs.add(new CdmaSmsBroadcastConfigInfo(1000, 0xFFFF, 1, true));
        ArgumentCaptor<CdmaSmsBroadcastConfigInfo[]> cdmaCaptor = ArgumentCaptor.forClass(
                CdmaSmsBroadcastConfigInfo[].class);

        mPhoneUT.setCellBroadcastIdRanges(ranges, r -> assertTrue(
                TelephonyManager.CELL_BROADCAST_RESULT_SUCCESS == r));
        waitForMs(100);

        verify(mMockCi, times(1)).setGsmBroadcastConfig(any(), any());
        verify(mMockCi, times(1)).setCdmaBroadcastConfig(cdmaCaptor.capture(), msgCaptor.capture());
        List<CdmaSmsBroadcastConfigInfo> cdmaArgs = Arrays.asList(
                (CdmaSmsBroadcastConfigInfo[]) cdmaCaptor.getValue());
        assertEquals(cdmaConfigs, cdmaArgs);

        msg = msgCaptor.getValue();
        assertNotNull(msg);
        AsyncResult.forMessage(msg);
        msg.sendToTarget();
        waitForMs(100);

        verify(mMockCi, times(1)).setGsmBroadcastActivation(anyBoolean(), any());
        verify(mMockCi, times(1)).setCdmaBroadcastActivation(eq(true), msgCaptor.capture());

        msg = msgCaptor.getValue();
        assertNotNull(msg);
        AsyncResult.forMessage(msg);
        msg.sendToTarget();
        waitForMs(100);

        assertEquals(mPhoneUT.getCellBroadcastIdRanges(), mergeRangesAsNeeded(ranges));

        // Verify not to set cdma or gsm config as the config is not changed
        mPhoneUT.setCellBroadcastIdRanges(ranges, r -> assertTrue(
                TelephonyManager.CELL_BROADCAST_RESULT_SUCCESS == r));
        waitForMs(100);

        verify(mMockCi, times(1)).setCdmaBroadcastConfig(any(), any());
        verify(mMockCi, times(1)).setCdmaBroadcastActivation(anyBoolean(), any());
        verify(mMockCi, times(1)).setGsmBroadcastConfig(any(), any());
        verify(mMockCi, times(1)).setGsmBroadcastActivation(anyBoolean(), any());

        assertEquals(mPhoneUT.getCellBroadcastIdRanges(), mergeRangesAsNeeded(ranges));

        // Verify to reset ranges with empty ranges list
        mPhoneUT.setCellBroadcastIdRanges(new ArrayList<>(), r -> assertTrue(
                TelephonyManager.CELL_BROADCAST_RESULT_SUCCESS == r));

        waitForMs(100);

        verify(mMockCi, times(2)).setGsmBroadcastConfig(gsmCaptor.capture(), msgCaptor.capture());
        assertEquals(0, ((SmsBroadcastConfigInfo[]) gsmCaptor.getValue()).length);

        msg = msgCaptor.getValue();
        assertNotNull(msg);
        AsyncResult.forMessage(msg);
        msg.sendToTarget();
        waitForMs(100);

        // Verify to deavtivate gsm broadcast on empty ranges
        verify(mMockCi, times(1)).setGsmBroadcastActivation(eq(false), msgCaptor.capture());

        msg = msgCaptor.getValue();
        assertNotNull(msg);
        AsyncResult.forMessage(msg);
        msg.sendToTarget();
        waitForMs(100);

        verify(mMockCi, times(2)).setCdmaBroadcastConfig(cdmaCaptor.capture(), msgCaptor.capture());
        assertEquals(0, ((CdmaSmsBroadcastConfigInfo[]) cdmaCaptor.getValue()).length);

        msg = msgCaptor.getValue();
        assertNotNull(msg);
        AsyncResult.forMessage(msg);
        msg.sendToTarget();
        processAllMessages();
        waitForMs(100);

        // Verify to deavtivate cdma broadcast on empty ranges
        verify(mMockCi, times(1)).setCdmaBroadcastActivation(eq(false), msgCaptor.capture());

        msg = msgCaptor.getValue();
        assertNotNull(msg);
        AsyncResult.forMessage(msg);
        msg.sendToTarget();
        processAllMessages();
        waitForMs(100);

        assertTrue(mPhoneUT.getCellBroadcastIdRanges().isEmpty());

        //Verify to set gsm and cdma config then activate again
        mPhoneUT.setCellBroadcastIdRanges(ranges, r -> assertTrue(
                TelephonyManager.CELL_BROADCAST_RESULT_SUCCESS == r));

        waitForMs(100);

        verify(mMockCi, times(3)).setGsmBroadcastConfig(gsmCaptor.capture(), msgCaptor.capture());
        gsmArgs = Arrays.asList((SmsBroadcastConfigInfo[]) gsmCaptor.getValue());
        assertEquals(gsmConfigs, gsmArgs);

        msg = msgCaptor.getValue();
        assertNotNull(msg);
        AsyncResult.forMessage(msg);
        msg.sendToTarget();
        waitForMs(100);

        verify(mMockCi, times(2)).setGsmBroadcastActivation(eq(true), msgCaptor.capture());

        msg = msgCaptor.getValue();
        assertNotNull(msg);
        AsyncResult.forMessage(msg);
        msg.sendToTarget();
        waitForMs(100);

        verify(mMockCi, times(3)).setCdmaBroadcastConfig(cdmaCaptor.capture(), msgCaptor.capture());
        cdmaArgs = Arrays.asList((CdmaSmsBroadcastConfigInfo[]) cdmaCaptor.getValue());
        assertEquals(cdmaConfigs, cdmaArgs);

        msg = msgCaptor.getValue();
        assertNotNull(msg);
        AsyncResult.forMessage(msg);
        msg.sendToTarget();
        waitForMs(100);

        verify(mMockCi, times(2)).setCdmaBroadcastActivation(eq(true), msgCaptor.capture());

        msg = msgCaptor.getValue();
        assertNotNull(msg);
        AsyncResult.forMessage(msg);
        msg.sendToTarget();
        waitForMs(100);

        assertEquals(mPhoneUT.getCellBroadcastIdRanges(), mergeRangesAsNeeded(ranges));
    }

    @Test
    @SmallTest
    public void testSetCellBroadcastIdRangesFailure() throws Exception {
        List<CellBroadcastIdRange> ranges = new ArrayList<>();

        // Verify to throw exception for invalid ranges
        ranges.add(new CellBroadcastIdRange(0, 999, SmsCbMessage.MESSAGE_FORMAT_3GPP, true));
        ranges.add(new CellBroadcastIdRange(0, 999, SmsCbMessage.MESSAGE_FORMAT_3GPP, false));

        assertThrows(IllegalArgumentException.class,
                () -> mPhoneUT.setCellBroadcastIdRanges(ranges, r -> {}));

        ArgumentCaptor<Message> msgCaptor = ArgumentCaptor.forClass(Message.class);
        ranges.clear();
        ranges.add(new CellBroadcastIdRange(0, 999, SmsCbMessage.MESSAGE_FORMAT_3GPP, true));
        ranges.add(new CellBroadcastIdRange(0, 999, SmsCbMessage.MESSAGE_FORMAT_3GPP2, true));
        mPhoneUT.mCi = mMockCi;

        // Verify the result on setGsmBroadcastConfig failure
        mPhoneUT.setCellBroadcastIdRanges(ranges, r -> assertTrue(
                TelephonyManager.CELL_BROADCAST_RESULT_FAIL_CONFIG == r));
        waitForMs(100);

        verify(mMockCi, times(1)).setGsmBroadcastConfig(any(), msgCaptor.capture());

        Message msg = msgCaptor.getValue();
        assertNotNull(msg);
        AsyncResult.forMessage(msg).exception = new RuntimeException();
        msg.sendToTarget();
        waitForMs(100);

        verify(mMockCi, times(0)).setGsmBroadcastActivation(anyBoolean(), any());
        verify(mMockCi, times(0)).setCdmaBroadcastConfig(any(), any());
        verify(mMockCi, times(0)).setCdmaBroadcastActivation(anyBoolean(), any());
        assertTrue(mPhoneUT.getCellBroadcastIdRanges().isEmpty());

        // Verify the result on setGsmBroadcastActivation failure
        mPhoneUT.setCellBroadcastIdRanges(ranges, r -> assertTrue(
                TelephonyManager.CELL_BROADCAST_RESULT_FAIL_ACTIVATION == r));
        waitForMs(100);

        verify(mMockCi, times(2)).setGsmBroadcastConfig(any(), msgCaptor.capture());

        msg = msgCaptor.getValue();
        assertNotNull(msg);
        AsyncResult.forMessage(msg);
        msg.sendToTarget();
        waitForMs(100);

        verify(mMockCi, times(1)).setGsmBroadcastActivation(anyBoolean(), msgCaptor.capture());

        msg = msgCaptor.getValue();
        assertNotNull(msg);
        AsyncResult.forMessage(msg).exception = new RuntimeException();
        msg.sendToTarget();
        waitForMs(100);

        verify(mMockCi, times(0)).setCdmaBroadcastConfig(any(), any());
        verify(mMockCi, times(0)).setCdmaBroadcastActivation(anyBoolean(), any());
        assertTrue(mPhoneUT.getCellBroadcastIdRanges().isEmpty());

        // Verify the result on setCdmaBroadcastConfig failure
        mPhoneUT.setCellBroadcastIdRanges(ranges, r -> assertTrue(
                TelephonyManager.CELL_BROADCAST_RESULT_FAIL_CONFIG == r));
        waitForMs(100);

        verify(mMockCi, times(3)).setGsmBroadcastConfig(any(), msgCaptor.capture());

        msg = msgCaptor.getValue();
        assertNotNull(msg);
        AsyncResult.forMessage(msg);
        msg.sendToTarget();
        waitForMs(100);

        verify(mMockCi, times(2)).setGsmBroadcastActivation(anyBoolean(), msgCaptor.capture());

        msg = msgCaptor.getValue();
        assertNotNull(msg);
        AsyncResult.forMessage(msg);
        msg.sendToTarget();
        waitForMs(100);

        verify(mMockCi, times(1)).setCdmaBroadcastConfig(any(), msgCaptor.capture());

        msg = msgCaptor.getValue();
        assertNotNull(msg);
        AsyncResult.forMessage(msg).exception = new RuntimeException();
        msg.sendToTarget();
        waitForMs(100);

        verify(mMockCi, times(0)).setCdmaBroadcastActivation(anyBoolean(), any());

        List<CellBroadcastIdRange> ranges3gpp = new ArrayList<>();
        ranges3gpp.add(new CellBroadcastIdRange(0, 999, SmsCbMessage.MESSAGE_FORMAT_3GPP, true));

        assertEquals(mPhoneUT.getCellBroadcastIdRanges(), ranges3gpp);

        // Verify the result on setCdmaBroadcastActivation failure
        mPhoneUT.setCellBroadcastIdRanges(ranges, r -> assertTrue(
                TelephonyManager.CELL_BROADCAST_RESULT_FAIL_ACTIVATION == r));
        waitForMs(200);

        // Verify no more calls as there is no change of ranges for 3gpp
        verify(mMockCi, times(3)).setGsmBroadcastConfig(any(), any());
        verify(mMockCi, times(2)).setGsmBroadcastActivation(anyBoolean(), any());
        verify(mMockCi, times(2)).setCdmaBroadcastConfig(any(), msgCaptor.capture());

        msg = msgCaptor.getValue();
        assertNotNull(msg);
        AsyncResult.forMessage(msg);
        msg.sendToTarget();
        waitForMs(100);

        verify(mMockCi, times(1)).setCdmaBroadcastActivation(anyBoolean(), msgCaptor.capture());

        msg = msgCaptor.getValue();
        assertNotNull(msg);
        AsyncResult.forMessage(msg).exception = new RuntimeException();
        msg.sendToTarget();
        waitForMs(100);

        assertEquals(mPhoneUT.getCellBroadcastIdRanges(), ranges3gpp);
    }

    @Test
    @SmallTest
    public void testMergeCellBroadcastIdRangesAsNeeded() {
        final int[][] channelValues = {
                {0, 999}, {1000, 1003}, {1004, 0x0FFF}, {0x1000, 0x10FF}, {0x1100, 0x112F},
                {0x1130, 0x1900}, {0x1901, 0x9FFF}, {0xA000, 0xFFFE}, {0xFFFF, 0xFFFF}};
        final int[] typeValues = {
                SmsCbMessage.MESSAGE_FORMAT_3GPP, SmsCbMessage.MESSAGE_FORMAT_3GPP2};
        final boolean[] enabledValues = {true, false};

        List<CellBroadcastIdRange> ranges = new ArrayList<>();
        for (int i = 0; i < channelValues.length; i++) {
            ranges.add(new CellBroadcastIdRange(channelValues[i][0], channelValues[i][1],
                    typeValues[0], enabledValues[0]));
        }

        ranges = mergeRangesAsNeeded(ranges);

        assertEquals(ranges.size(), 1);
        assertEquals(ranges.get(0).getStartId(), channelValues[0][0]);
        assertEquals(ranges.get(0).getEndId(), channelValues[channelValues.length - 1][0]);

        // Verify not to merge the ranges with different types.
        ranges.clear();
        for (int i = 0; i < channelValues.length; i++) {
            ranges.add(new CellBroadcastIdRange(channelValues[i][0], channelValues[i][1],
                    typeValues[0], enabledValues[0]));
            ranges.add(new CellBroadcastIdRange(channelValues[i][0], channelValues[i][1],
                    typeValues[1], enabledValues[0]));
        }

        ranges = mergeRangesAsNeeded(ranges);

        assertEquals(ranges.size(), 2);
        assertEquals(ranges.get(0).getStartId(), channelValues[0][0]);
        assertEquals(ranges.get(0).getEndId(), channelValues[channelValues.length - 1][0]);
        assertEquals(ranges.get(1).getStartId(), channelValues[0][0]);
        assertEquals(ranges.get(1).getEndId(), channelValues[channelValues.length - 1][0]);
        assertTrue(ranges.get(0).getType() != ranges.get(1).getType());

        // Verify to throw IllegalArgumentException if the same range is enabled and disabled
        // in the range list.
        final List<CellBroadcastIdRange> ranges2 = new ArrayList<>();
        for (int i = 0; i < channelValues.length; i++) {
            ranges2.add(new CellBroadcastIdRange(channelValues[i][0], channelValues[i][1],
                    typeValues[0], enabledValues[0]));
            ranges2.add(new CellBroadcastIdRange(channelValues[i][0], channelValues[i][1],
                    typeValues[0], enabledValues[1]));
        }

        assertThrows(IllegalArgumentException.class, () ->
                mergeRangesAsNeeded(ranges2));
    }

    @Test
    @Test
    public void getImeiType_primary() {
    public void getImeiType_primary() {
        Message message = mPhoneUT.obtainMessage(Phone.EVENT_GET_DEVICE_IMEI_DONE);
        Message message = mPhoneUT.obtainMessage(Phone.EVENT_GET_DEVICE_IMEI_DONE);
Loading