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

Commit ffe9936d authored by Chen Xu's avatar Chen Xu Committed by Android Partner Code Review
Browse files

Merge "UICC card and UICC controller Unit test" into mm-wireless-dev

parents 76c69fd1 9bf2a929
Loading
Loading
Loading
Loading
+35 −4
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.telephony.CellInfoGsm;
import android.telephony.Rlog;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.IccOpenLogicalChannelResponse;

import com.android.internal.telephony.BaseCommands;
import com.android.internal.telephony.CommandException;
@@ -39,6 +40,8 @@ import com.android.internal.telephony.CallFailCause;
import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
import com.android.internal.telephony.gsm.SuppServiceNotification;
import com.android.internal.telephony.LastCallFailCause;
import com.android.internal.telephony.uicc.IccCardStatus;
import com.android.internal.telephony.uicc.IccIoResult;

import java.util.ArrayList;
import java.util.List;
@@ -94,6 +97,9 @@ public class SimulatedCommands extends BaseCommands
    private SignalStrength mSignalStrength;
    private List<CellInfo> mCellInfoList;
    private int[] mImsRegState;
    private IccCardStatus mIccCardStatus;
    private IccIoResult mIccIoResultForApduLogicalChannel;
    private int mChannelId = IccOpenLogicalChannelResponse.INVALID_CHANNEL;

    int mPausedResponseCount;
    ArrayList<Message> mPausedResponses = new ArrayList<Message>();
@@ -124,7 +130,11 @@ public class SimulatedCommands extends BaseCommands

    @Override
    public void getIccCardStatus(Message result) {
        unimplemented(result);
        if(mIccCardStatus!=null) {
            resultSuccess(result, mIccCardStatus);
        } else {
            resultFail(result, new RuntimeException("IccCardStatus not set"));
        }
    }

    @Override
@@ -1768,7 +1778,9 @@ public class SimulatedCommands extends BaseCommands

    @Override
    public void iccOpenLogicalChannel(String AID, Message response) {
        unimplemented(response);
        SimulatedCommandsVerifier.getInstance().iccOpenLogicalChannel(AID, response);
        Object result = new int[]{mChannelId};
        resultSuccess(response, result);
    }

    @Override
@@ -1778,8 +1790,15 @@ public class SimulatedCommands extends BaseCommands

    @Override
    public void iccTransmitApduLogicalChannel(int channel, int cla, int instruction,
            int p1, int p2, int p3, String data, Message response) {
        unimplemented(response);
                                              int p1, int p2, int p3, String data,
                                              Message response) {
        SimulatedCommandsVerifier.getInstance().iccTransmitApduLogicalChannel(channel, cla,
                                                 instruction, p1, p2, p3, data, response);
        if(mIccIoResultForApduLogicalChannel!=null) {
            resultSuccess(response, mIccIoResultForApduLogicalChannel);
        }else {
            resultFail(response, new RuntimeException("IccIoResult not set"));
        }
    }

    @Override
@@ -1859,4 +1878,16 @@ public class SimulatedCommands extends BaseCommands
    public void notifyRadioOn() {
        mOnRegistrants.notifyRegistrants();
    }

    public void setIccCardStatus(IccCardStatus iccCardStatus){
        mIccCardStatus = iccCardStatus;
    }

    public void setIccIoResultForApduLogicalChannel(IccIoResult iccIoResult) {
        mIccIoResultForApduLogicalChannel = iccIoResult;
    }

    public void setOpenChannelId(int channelId) {
        mChannelId = channelId;
    }
}
+88 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.internal.telephony;

import android.test.suitebuilder.annotation.SmallTest;
import android.util.Log;

import com.android.internal.telephony.uicc.IccCardApplicationStatus;
import com.android.internal.telephony.uicc.IccCardStatus;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import static org.junit.Assert.assertEquals;

public class IccCardStatusTest {

    private IccCardStatus mIccCardStatus;
    private static final String TAG = "ICCCardStatusTest";
    @Mock
    private IccCardApplicationStatus mApplicationStatus;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        mIccCardStatus = new IccCardStatus();
        /* set only one applications for cdma */
        mIccCardStatus.mApplications = new IccCardApplicationStatus[]{mApplicationStatus};
        mIccCardStatus.mCdmaSubscriptionAppIndex = 0;
        mIccCardStatus.mGsmUmtsSubscriptionAppIndex = -1;
        mIccCardStatus.mCdmaSubscriptionAppIndex = -1;

    }

    @After
    public void tearDown() throws Exception {
        mIccCardStatus = null;
    }

    @Test
    @SmallTest
    public void testSetCardState() {
        mIccCardStatus.setCardState(IccCardStatus.CardState.CARDSTATE_ABSENT.ordinal());
        assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mIccCardStatus.mCardState);
        logd(mIccCardStatus.toString());

        mIccCardStatus.setCardState(IccCardStatus.CardState.CARDSTATE_PRESENT.ordinal());
        assertEquals(IccCardStatus.CardState.CARDSTATE_PRESENT, mIccCardStatus.mCardState);
        logd(mIccCardStatus.toString());

        mIccCardStatus.setCardState(IccCardStatus.CardState.CARDSTATE_ERROR.ordinal());
        assertEquals(IccCardStatus.CardState.CARDSTATE_ERROR, mIccCardStatus.mCardState);
        logd(mIccCardStatus.toString());
    }

    @Test
    @SmallTest
    public void testSetPinState() {
        mIccCardStatus.setUniversalPinState(IccCardStatus.PinState.PINSTATE_UNKNOWN.ordinal());
        assertEquals(IccCardStatus.PinState.PINSTATE_UNKNOWN, mIccCardStatus.mUniversalPinState);
        logd(mIccCardStatus.toString());

        mIccCardStatus.setUniversalPinState(
                IccCardStatus.PinState.PINSTATE_ENABLED_BLOCKED.ordinal());
        assertEquals(IccCardStatus.PinState.PINSTATE_ENABLED_BLOCKED,
                     mIccCardStatus.mUniversalPinState);
        logd(mIccCardStatus.toString());
    }

    private static void logd(String s) {
        Log.d(TAG, s);
    }
}
+299 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.internal.telephony;

import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.test.suitebuilder.annotation.SmallTest;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import android.util.Log;
import com.android.internal.telephony.cat.CatService;
import com.android.internal.telephony.test.SimulatedCommands;
import com.android.internal.telephony.uicc.IccCardApplicationStatus;
import com.android.internal.telephony.uicc.IccCardStatus;
import com.android.internal.telephony.uicc.UiccCard;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import static org.mockito.Mockito.*;

import org.mockito.MockitoAnnotations;

import java.lang.reflect.Field;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import com.android.internal.telephony.test.SimulatedCommandsVerifier;
import com.android.internal.telephony.uicc.IccIoResult;

public class UiccCardTest {
    private UiccCard mUicccard;

    public UiccCardTest() {
        super();
    }

    private IccIoResult mIccIoResult;
    private SimulatedCommands mSimulatedCommands;
    private ContextFixture mContextFixture;
    private Object mLock = new Object();
    private boolean mReady;
    private UiccCardHandlerThread mTestHandlerThread;
    private Handler mHandler;
    private static final String TAG = "UiccCardTest";
    private static final int UICCCARD_UPDATE_CARD_STATE_EVENT = 1;
    private static final int UICCCARD_UPDATE_CARD_APPLICATION_EVENT = 2;
    private static final int UICCCARD_CARRIER_PRIVILEDGE_LOADED_EVENT = 3;
    private static final int UICCCARD_ABSENT = 4;

    @Mock
    private CatService mCAT;
    @Mock
    private SubscriptionController mSubscriptionController;
    @Mock
    private SimulatedCommandsVerifier mSimulatedCommandsVerifier;
    @Mock
    private IccCardStatus mIccCardStatus;
    @Mock
    private Handler mMockedHandler;


    private class UiccCardHandlerThread extends HandlerThread {

        private UiccCardHandlerThread(String name) {
            super(name);
        }

        @Override
        public void onLooperPrepared() {
            mUicccard = new UiccCard(mContextFixture.getTestDouble(),
                                     mSimulatedCommands, mIccCardStatus);
            /* create a custom handler for the Handler Thread */
            mHandler = new Handler(mTestHandlerThread.getLooper()) {
                @Override
                public void handleMessage(Message msg) {
                    switch (msg.what) {
                        case UICCCARD_UPDATE_CARD_STATE_EVENT:
                            /* Upon handling this event, new CarrierPrivilegeRule
                            will be created with the looper of HandlerThread */
                            logd("Update UICC Card State");
                            mUicccard.update(mContextFixture.getTestDouble(),
                                    mSimulatedCommands, mIccCardStatus);
                            setReadyFlag(true);
                            break;
                        case UICCCARD_UPDATE_CARD_APPLICATION_EVENT:
                            logd("Update UICC Card Applications");
                            mUicccard.update(mContextFixture.getTestDouble(),
                                    mSimulatedCommands, mIccCardStatus);
                            setReadyFlag(true);
                            break;
                        default:
                            logd("Unknown Event " + msg.what);
                    }
                }
            };

            setReadyFlag(true);
            logd("create UiccCard");
        }
    }

    private void waitUntilReady() {
        while (true) {
            synchronized (mLock) {
                if (mReady) {
                    break;
                }
            }
        }
    }

    private void setReadyFlag(boolean val) {
        synchronized (mLock) {
            mReady = val;
        }
    }

    private IccCardApplicationStatus composeUiccApplicationStatus(
            IccCardApplicationStatus.AppType appType,
            IccCardApplicationStatus.AppState appState, String aid) {
        IccCardApplicationStatus mIccCardAppStatus = new IccCardApplicationStatus();
        mIccCardAppStatus.aid = aid;
        mIccCardAppStatus.app_type = appType;
        mIccCardAppStatus.app_state = appState;
        mIccCardAppStatus.pin1 = mIccCardAppStatus.pin2 =
                IccCardStatus.PinState.PINSTATE_ENABLED_VERIFIED;
        return mIccCardAppStatus;
    }

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        mContextFixture = new ContextFixture();
        /* initially there are no application available */
        mIccCardStatus.mApplications = new IccCardApplicationStatus[]{};
        mIccCardStatus.mCdmaSubscriptionAppIndex =
                mIccCardStatus.mImsSubscriptionAppIndex =
                        mIccCardStatus.mGsmUmtsSubscriptionAppIndex = -1;
        mSimulatedCommands = new SimulatedCommands();
        Field field = SubscriptionController.class.getDeclaredField("sInstance");
        field.setAccessible(true);
        field.set(null, mSubscriptionController);
        field = SimulatedCommandsVerifier.class.getDeclaredField("sInstance");
        field.setAccessible(true);
        field.set(null, mSimulatedCommandsVerifier);
        mIccIoResult = new IccIoResult(0x90, 0x00, IccUtils.hexStringToBytes("FF40"));
        mSimulatedCommands.setIccIoResultForApduLogicalChannel(mIccIoResult);
        /* starting the Handler Thread */
        setReadyFlag(false);
        mTestHandlerThread = new UiccCardHandlerThread(TAG);
        mTestHandlerThread.start();

        waitUntilReady();
        field = UiccCard.class.getDeclaredField("mCatService");
        field.setAccessible(true);
        field.set(mUicccard, mCAT);
    }

    @Test
    @SmallTest
    public void tesUiccCartdInfoSanity() {
        /* before update sanity test */
        assertEquals(mUicccard.getNumApplications(), 0);
        assertNull(mUicccard.getCardState());
        assertNull(mUicccard.getUniversalPinState());
        assertNull(mUicccard.getOperatorBrandOverride());
        /* CarrierPrivilegeRule equals null, return true */
        assertTrue(mUicccard.areCarrierPriviligeRulesLoaded());
        for (IccCardApplicationStatus.AppType mAppType :
                IccCardApplicationStatus.AppType.values()) {
            assertFalse(mUicccard.isApplicationOnIcc(mAppType));
        }
    }

    @Test @SmallTest
    public void testUpdateUiccCardApplication() {
        /* update app status and index */
        IccCardApplicationStatus cdmaApp = composeUiccApplicationStatus(
                IccCardApplicationStatus.AppType.APPTYPE_CSIM,
                IccCardApplicationStatus.AppState.APPSTATE_UNKNOWN, "0xA0");
        IccCardApplicationStatus imsApp = composeUiccApplicationStatus(
                IccCardApplicationStatus.AppType.APPTYPE_ISIM,
                IccCardApplicationStatus.AppState.APPSTATE_UNKNOWN, "0xA1");
        IccCardApplicationStatus umtsApp = composeUiccApplicationStatus(
                IccCardApplicationStatus.AppType.APPTYPE_USIM,
                IccCardApplicationStatus.AppState.APPSTATE_UNKNOWN, "0xA2");
        mIccCardStatus.mApplications = new IccCardApplicationStatus[]{cdmaApp, imsApp, umtsApp};
        mIccCardStatus.mCdmaSubscriptionAppIndex = 0;
        mIccCardStatus.mImsSubscriptionAppIndex = 1;
        mIccCardStatus.mGsmUmtsSubscriptionAppIndex = 2;
        Message mCardUpdate = mHandler.obtainMessage(UICCCARD_UPDATE_CARD_APPLICATION_EVENT);
        setReadyFlag(false);
        mCardUpdate.sendToTarget();

        waitUntilReady();

        assertEquals(mUicccard.getNumApplications(), 3);
        assertTrue(mUicccard.isApplicationOnIcc(IccCardApplicationStatus.AppType.APPTYPE_CSIM));
        assertTrue(mUicccard.isApplicationOnIcc(IccCardApplicationStatus.AppType.APPTYPE_ISIM));
        assertTrue(mUicccard.isApplicationOnIcc(IccCardApplicationStatus.AppType.APPTYPE_USIM));
    }

    @Test @SmallTest
    public void testUpdateUiccCardState() {
        int mChannelId = 1;
        /* set card as present */
        mIccCardStatus.mCardState = IccCardStatus.CardState.CARDSTATE_PRESENT;
        /* Mock open Channel ID 1 */
        mSimulatedCommands.setOpenChannelId(mChannelId);
        Message mCardUpdate = mHandler.obtainMessage(UICCCARD_UPDATE_CARD_STATE_EVENT);
        setReadyFlag(false);
        mCardUpdate.sendToTarget();
        /* try to create a new CarrierPrivilege, loading state -> loaded state */
        /* wait till the async result and message delay */
        waitUntilReady();

        assertFalse(mUicccard.areCarrierPriviligeRulesLoaded());
        assertEquals(mUicccard.getCardState(),
                IccCardStatus.CardState.CARDSTATE_PRESENT);

        TelephonyTestUtils.waitForMs(50);

        assertTrue(mUicccard.areCarrierPriviligeRulesLoaded());
        verify(mSimulatedCommandsVerifier, times(1)).iccOpenLogicalChannel(isA(String.class),
                isA(Message.class));
        verify(mSimulatedCommandsVerifier, times(1)).iccTransmitApduLogicalChannel(
                eq(mChannelId), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyString(),
                isA(Message.class)
        );
    }

    @Test @SmallTest
    public void testUpdateUiccCardPinState() {
        mIccCardStatus.mUniversalPinState = IccCardStatus.PinState.PINSTATE_ENABLED_VERIFIED;
        mUicccard.update(mContextFixture.getTestDouble(), mSimulatedCommands, mIccCardStatus);
        assertEquals(mUicccard.getUniversalPinState(),
                IccCardStatus.PinState.PINSTATE_ENABLED_VERIFIED);
    }

    @Test @SmallTest
    public void testCarrierPriviledgeLoadedListener() {
        mUicccard.registerForCarrierPrivilegeRulesLoaded(mMockedHandler,
                UICCCARD_CARRIER_PRIVILEDGE_LOADED_EVENT, null);
        ArgumentCaptor<Message> mCaptorMessage = ArgumentCaptor.forClass(Message.class);
        ArgumentCaptor<Long>    mCaptorLong = ArgumentCaptor.forClass(Long.class);
        testUpdateUiccCardState();
        verify(mMockedHandler, atLeast(1)).sendMessageDelayed(mCaptorMessage.capture(),
                mCaptorLong.capture());
        assertEquals(UICCCARD_CARRIER_PRIVILEDGE_LOADED_EVENT, mCaptorMessage.getValue().what);
    }

    @Test @SmallTest
    public void testCardAbsentListener() {
        mUicccard.registerForAbsent(mMockedHandler, UICCCARD_ABSENT, null);
        /* assume hotswap capable, avoid bootup on card removal */
        mContextFixture.putBooleanResource(com.android.internal.R.bool.config_hotswapCapable, true);
        mSimulatedCommands.setRadioPower(true, null);

        /* Mock Card State transition from card_present to card_absent */
        logd("UICC Card Present update");
        mIccCardStatus.mCardState = IccCardStatus.CardState.CARDSTATE_PRESENT;
        Message mCardUpdate = mHandler.obtainMessage(UICCCARD_UPDATE_CARD_STATE_EVENT);
        mCardUpdate.sendToTarget();
        TelephonyTestUtils.waitForMs(50);

        logd("UICC Card absent update");
        mIccCardStatus.mCardState = IccCardStatus.CardState.CARDSTATE_ABSENT;
        mUicccard.update(mContextFixture.getTestDouble(), mSimulatedCommands, mIccCardStatus);
        TelephonyTestUtils.waitForMs(50);

        ArgumentCaptor<Message> mCaptorMessage = ArgumentCaptor.forClass(Message.class);
        ArgumentCaptor<Long>    mCaptorLong = ArgumentCaptor.forClass(Long.class);
        verify(mMockedHandler, atLeast(1)).sendMessageDelayed(mCaptorMessage.capture(),
                                                             mCaptorLong.capture());
        assertEquals(UICCCARD_ABSENT, mCaptorMessage.getValue().what);
    }

    private static void logd(String s) {
        Log.d(TAG, s);
    }

}
+223 −0

File added.

Preview size limit exceeded, changes collapsed.