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 */ 16package com.android.internal.telephony.uicc; 17import android.os.Handler; 18import android.os.HandlerThread; 19import android.os.Message; 20import android.test.suitebuilder.annotation.SmallTest; 21import org.junit.After; 22import org.junit.Before; 23import org.junit.Test; 24 25import com.android.internal.telephony.CommandsInterface; 26import com.android.internal.telephony.TelephonyTest; 27 28import org.mockito.ArgumentCaptor; 29import org.mockito.Mock; 30import static org.junit.Assert.assertEquals; 31import static org.junit.Assert.assertNotNull; 32import static org.junit.Assert.assertNull; 33import static org.mockito.Mockito.atLeast; 34import static org.mockito.Mockito.doReturn; 35import static org.mockito.Mockito.verify; 36import static com.android.internal.telephony.TelephonyTestUtils.waitForMs; 37 38public class UiccControllerTest extends TelephonyTest { 39 private UiccController mUiccControllerUT; 40 private UiccControllerHandlerThread mUiccControllerHandlerThread; 41 private static final int PHONE_COUNT = 1; 42 private static int ICC_CHANGED_EVENT = 0; 43 @Mock 44 private Handler mMockedHandler; 45 @Mock 46 private IccCardStatus mIccCardStatus; 47 48 private class UiccControllerHandlerThread extends HandlerThread { 49 50 private UiccControllerHandlerThread(String name) { 51 super(name); 52 } 53 @Override 54 public void onLooperPrepared() { 55 /* create a new UICC Controller associated with the simulated Commands */ 56 mUiccControllerUT = UiccController.make(mContext, 57 new CommandsInterface[]{mSimulatedCommands}); 58 setReady(true); 59 } 60 } 61 62 private IccCardApplicationStatus composeUiccApplicationStatus( 63 IccCardApplicationStatus.AppType appType, 64 IccCardApplicationStatus.AppState appState, String aid) { 65 IccCardApplicationStatus mIccCardAppStatus = new IccCardApplicationStatus(); 66 mIccCardAppStatus.aid = aid; 67 mIccCardAppStatus.app_type = appType; 68 mIccCardAppStatus.app_state = appState; 69 mIccCardAppStatus.pin1 = mIccCardAppStatus.pin2 = 70 IccCardStatus.PinState.PINSTATE_ENABLED_VERIFIED; 71 return mIccCardAppStatus; 72 } 73 74 @Before 75 public void setUp() throws Exception { 76 super.setUp(this.getClass().getSimpleName()); 77 78 doReturn(PHONE_COUNT).when(mTelephonyManager).getPhoneCount(); 79 doReturn(PHONE_COUNT).when(mTelephonyManager).getSimCount(); 80 81 replaceInstance(UiccController.class, "mInstance", null, null); 82 83 /* null Application associated with any FAM */ 84 mIccCardStatus.mApplications = new IccCardApplicationStatus[]{}; 85 mIccCardStatus.mCdmaSubscriptionAppIndex = 86 mIccCardStatus.mImsSubscriptionAppIndex = 87 mIccCardStatus.mGsmUmtsSubscriptionAppIndex = -1; 88 mSimulatedCommands.setIccCardStatus(mIccCardStatus); 89 mUiccControllerHandlerThread = new UiccControllerHandlerThread(TAG); 90 mUiccControllerHandlerThread.start(); 91 waitUntilReady(); 92 /* expected to get new UiccCards being created 93 wait till the async result and message delay */ 94 waitForMs(100); 95 } 96 97 @After 98 public void tearDown() throws Exception { 99 mUiccControllerHandlerThread.quitSafely(); 100 super.tearDown(); 101 } 102 103 @Test @SmallTest 104 public void testSanity() { 105 assertEquals(PHONE_COUNT, mUiccControllerUT.getUiccCards().length); 106 assertNotNull(mUiccControllerUT.getUiccCard(0)); 107 assertNull(mUiccControllerUT.getIccRecords(0, UiccController.APP_FAM_3GPP)); 108 assertNull(mUiccControllerUT.getIccRecords(0, UiccController.APP_FAM_3GPP2)); 109 assertNull(mUiccControllerUT.getIccRecords(0, UiccController.APP_FAM_IMS)); 110 assertNull(mUiccControllerUT.getIccFileHandler(0, UiccController.APP_FAM_3GPP)); 111 assertNull(mUiccControllerUT.getIccFileHandler(0, UiccController.APP_FAM_3GPP2)); 112 assertNull(mUiccControllerUT.getIccFileHandler(0, UiccController.APP_FAM_IMS)); 113 } 114 115 @Test @SmallTest 116 public void testPowerOff() { 117 /* Uicc Controller registered for event off to unavail */ 118 logd("radio power state transition from off to unavail, dispose UICC Card"); 119 testSanity(); 120 mSimulatedCommands.requestShutdown(null); 121 waitForMs(50); 122 assertNull(mUiccControllerUT.getUiccCard(0)); 123 assertEquals(CommandsInterface.RadioState.RADIO_UNAVAILABLE, 124 mSimulatedCommands.getRadioState()); 125 } 126 127 @Test@SmallTest 128 public void testPowerOn() { 129 mSimulatedCommands.setRadioPower(true, null); 130 waitForMs(500); 131 assertNotNull(mUiccControllerUT.getUiccCard(0)); 132 assertEquals(CommandsInterface.RadioState.RADIO_ON, mSimulatedCommands.getRadioState()); 133 } 134 135 @Test @SmallTest 136 public void testPowerOffPowerOnWithApp() { 137 /* update app status and index */ 138 IccCardApplicationStatus cdmaApp = composeUiccApplicationStatus( 139 IccCardApplicationStatus.AppType.APPTYPE_CSIM, 140 IccCardApplicationStatus.AppState.APPSTATE_UNKNOWN, "0xA0"); 141 IccCardApplicationStatus imsApp = composeUiccApplicationStatus( 142 IccCardApplicationStatus.AppType.APPTYPE_ISIM, 143 IccCardApplicationStatus.AppState.APPSTATE_UNKNOWN, "0xA1"); 144 IccCardApplicationStatus umtsApp = composeUiccApplicationStatus( 145 IccCardApplicationStatus.AppType.APPTYPE_USIM, 146 IccCardApplicationStatus.AppState.APPSTATE_UNKNOWN, "0xA2"); 147 mIccCardStatus.mApplications = new IccCardApplicationStatus[]{cdmaApp, imsApp, umtsApp}; 148 mIccCardStatus.mCdmaSubscriptionAppIndex = 0; 149 mIccCardStatus.mImsSubscriptionAppIndex = 1; 150 mIccCardStatus.mGsmUmtsSubscriptionAppIndex = 2; 151 152 mSimulatedCommands.setIccCardStatus(mIccCardStatus); 153 logd("radio power state transition from off to unavail"); 154 testPowerOff(); 155 /* UICC controller registered for event unavailable to on */ 156 logd("radio power state transition from unavail to on, update IccCardStatus with app"); 157 testPowerOn(); 158 159 logd("validate Card status with Applications on it followed by Power on"); 160 assertNotNull(mUiccControllerUT.getUiccCard(0)); 161 assertNotNull(mUiccControllerUT.getIccRecords(0, UiccController.APP_FAM_3GPP)); 162 assertNotNull(mUiccControllerUT.getIccRecords(0, UiccController.APP_FAM_3GPP2)); 163 assertNotNull(mUiccControllerUT.getIccRecords(0, UiccController.APP_FAM_IMS)); 164 assertNotNull(mUiccControllerUT.getIccFileHandler(0, UiccController.APP_FAM_3GPP)); 165 assertNotNull(mUiccControllerUT.getIccFileHandler(0, UiccController.APP_FAM_3GPP2)); 166 assertNotNull(mUiccControllerUT.getIccFileHandler(0, UiccController.APP_FAM_IMS)); 167 } 168 169 @Test @SmallTest 170 public void testIccChangedListener() { 171 mUiccControllerUT.registerForIccChanged(mMockedHandler, ICC_CHANGED_EVENT, null); 172 testPowerOff(); 173 ArgumentCaptor<Message> mCaptorMessage = ArgumentCaptor.forClass(Message.class); 174 ArgumentCaptor<Long> mCaptorLong = ArgumentCaptor.forClass(Long.class); 175 verify(mMockedHandler, atLeast(1)).sendMessageDelayed(mCaptorMessage.capture(), 176 mCaptorLong.capture()); 177 assertEquals(ICC_CHANGED_EVENT, mCaptorMessage.getValue().what); 178 } 179} 180