1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.internal.telephony.uicc; 17 18 import static com.android.internal.telephony.TelephonyTestUtils.waitForMs; 19 20 import static org.junit.Assert.assertEquals; 21 import static org.junit.Assert.assertFalse; 22 import static org.junit.Assert.assertNull; 23 24 import android.os.Handler; 25 import android.os.HandlerThread; 26 import android.os.Message; 27 import android.test.suitebuilder.annotation.SmallTest; 28 29 import com.android.internal.telephony.TelephonyTest; 30 31 import org.junit.After; 32 import org.junit.Before; 33 import org.junit.Test; 34 import org.mockito.Mock; 35 36 public class UiccCardTest extends TelephonyTest { 37 private UiccCard mUicccard; 38 39 public UiccCardTest() { 40 super(); 41 } 42 43 private IccIoResult mIccIoResult; 44 45 private UiccCardHandlerThread mTestHandlerThread; 46 private Handler mHandler; 47 private static final int UICCCARD_UPDATE_CARD_STATE_EVENT = 1; 48 private static final int UICCCARD_UPDATE_CARD_APPLICATION_EVENT = 2; 49 private static final int UICCCARD_CARRIER_PRIVILEDGE_LOADED_EVENT = 3; 50 51 @Mock 52 private IccCardStatus mIccCardStatus; 53 @Mock 54 private Handler mMockedHandler; 55 56 57 private class UiccCardHandlerThread extends HandlerThread { 58 59 private UiccCardHandlerThread(String name) { 60 super(name); 61 } 62 63 @Override 64 public void onLooperPrepared() { 65 mUicccard = new UiccCard(mContextFixture.getTestDouble(), 66 mSimulatedCommands, mIccCardStatus, 0 /* phoneId */, 67 new Object()); 68 /* create a custom handler for the Handler Thread */ 69 mHandler = new Handler(mTestHandlerThread.getLooper()) { 70 @Override 71 public void handleMessage(Message msg) { 72 switch (msg.what) { 73 case UICCCARD_UPDATE_CARD_STATE_EVENT: 74 /* Upon handling this event, new CarrierPrivilegeRule 75 will be created with the looper of HandlerThread */ 76 logd("Update UICC Card State"); 77 mUicccard.update(mContextFixture.getTestDouble(), 78 mSimulatedCommands, mIccCardStatus); 79 setReady(true); 80 break; 81 case UICCCARD_UPDATE_CARD_APPLICATION_EVENT: 82 logd("Update UICC Card Applications"); 83 mUicccard.update(mContextFixture.getTestDouble(), 84 mSimulatedCommands, mIccCardStatus); 85 setReady(true); 86 break; 87 default: 88 logd("Unknown Event " + msg.what); 89 } 90 } 91 }; 92 93 setReady(true); 94 logd("create UiccCard"); 95 } 96 } 97 98 private IccCardApplicationStatus composeUiccApplicationStatus( 99 IccCardApplicationStatus.AppType appType, 100 IccCardApplicationStatus.AppState appState, String aid) { 101 IccCardApplicationStatus mIccCardAppStatus = new IccCardApplicationStatus(); 102 mIccCardAppStatus.aid = aid; 103 mIccCardAppStatus.app_type = appType; 104 mIccCardAppStatus.app_state = appState; 105 mIccCardAppStatus.pin1 = mIccCardAppStatus.pin2 = 106 IccCardStatus.PinState.PINSTATE_ENABLED_VERIFIED; 107 return mIccCardAppStatus; 108 } 109 110 @Before 111 public void setUp() throws Exception { 112 113 super.setUp(getClass().getSimpleName()); 114 /* initially there are no application available */ 115 mIccCardStatus.mApplications = new IccCardApplicationStatus[]{}; 116 mIccCardStatus.mCdmaSubscriptionAppIndex = 117 mIccCardStatus.mImsSubscriptionAppIndex = 118 mIccCardStatus.mGsmUmtsSubscriptionAppIndex = -1; 119 mIccCardStatus.mCardState = IccCardStatus.CardState.CARDSTATE_PRESENT; 120 121 mIccIoResult = new IccIoResult(0x90, 0x00, IccUtils.hexStringToBytes("FF40")); 122 mSimulatedCommands.setIccIoResultForApduLogicalChannel(mIccIoResult); 123 /* starting the Handler Thread */ 124 mTestHandlerThread = new UiccCardHandlerThread(getClass().getSimpleName()); 125 mTestHandlerThread.start(); 126 127 waitUntilReady(); 128 } 129 130 @After 131 public void tearDown() throws Exception { 132 mTestHandlerThread.quit(); 133 super.tearDown(); 134 } 135 136 @Test 137 @SmallTest 138 public void tesUiccCartdInfoSanity() { 139 /* before update sanity test */ 140 assertEquals(0, mUicccard.getNumApplications()); 141 assertEquals(IccCardStatus.CardState.CARDSTATE_PRESENT, mUicccard.getCardState()); 142 assertNull(mUicccard.getUniversalPinState()); 143 assertNull(mUicccard.getOperatorBrandOverride()); 144 /* UiccProfile mock should return false */ 145 assertFalse(mUicccard.areCarrierPriviligeRulesLoaded()); 146 for (IccCardApplicationStatus.AppType mAppType : 147 IccCardApplicationStatus.AppType.values()) { 148 assertFalse(mUicccard.isApplicationOnIcc(mAppType)); 149 } 150 } 151 152 @Test @SmallTest 153 public void testUpdateUiccCardState() { 154 int mChannelId = 1; 155 /* set card as present */ 156 mIccCardStatus.mCardState = IccCardStatus.CardState.CARDSTATE_PRESENT; 157 /* Mock open Channel ID 1 */ 158 mSimulatedCommands.setOpenChannelId(mChannelId); 159 Message mCardUpdate = mHandler.obtainMessage(UICCCARD_UPDATE_CARD_STATE_EVENT); 160 setReady(false); 161 mCardUpdate.sendToTarget(); 162 /* try to create a new CarrierPrivilege, loading state -> loaded state */ 163 /* wait till the async result and message delay */ 164 waitUntilReady(); 165 166 assertEquals(IccCardStatus.CardState.CARDSTATE_PRESENT, mUicccard.getCardState()); 167 168 waitForMs(50); 169 170 /* todo: This part should move to UiccProfileTest 171 assertTrue(mUicccard.areCarrierPriviligeRulesLoaded()); 172 verify(mSimulatedCommandsVerifier, times(2)).iccOpenLogicalChannel(isA(String.class), 173 anyInt(), isA(Message.class)); 174 verify(mSimulatedCommandsVerifier, times(2)).iccTransmitApduLogicalChannel( 175 eq(mChannelId), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyString(), 176 isA(Message.class) 177 ); 178 */ 179 } 180 } 181