1 /* Copyright (c) 2016, The Linux Foundation. All rights reserved. 2 * 3 * Redistribution and use in source and binary forms, with or without 4 * modification, are permitted provided that the following conditions are 5 * met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above 9 * copyright notice, this list of conditions and the following 10 * disclaimer in the documentation and/or other materials provided 11 * with the distribution. 12 * * Neither the name of The Linux Foundation nor the names of its 13 * contributors may be used to endorse or promote products derived 14 * from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 */ 29 30 package com.android.internal.telephony.uicc; 31 32 import static com.android.internal.telephony.uicc.IccRecords.EVENT_APP_DETECTED; 33 import static com.android.internal.telephony.uicc.IccRecords.EVENT_APP_READY; 34 35 import static org.junit.Assert.assertEquals; 36 import static org.junit.Assert.assertFalse; 37 import static org.junit.Assert.assertNull; 38 import static org.junit.Assert.assertTrue; 39 import static org.mockito.Mockito.eq; 40 import static org.mockito.Mockito.isNull; 41 import static org.mockito.Mockito.verify; 42 43 import android.os.AsyncResult; 44 import android.os.HandlerThread; 45 import android.os.Message; 46 import android.os.SystemClock; 47 import android.util.Log; 48 import android.util.Pair; 49 50 import com.android.internal.telephony.TelephonyTest; 51 import com.android.internal.telephony.uicc.IccRecords.OperatorPlmnInfo; 52 import com.android.internal.telephony.uicc.IccRecords.PlmnNetworkName; 53 54 import org.junit.After; 55 import org.junit.Before; 56 import org.junit.Test; 57 58 import java.util.ArrayList; 59 import java.util.List; 60 61 public class IccRecordsTest extends TelephonyTest { 62 63 private IccRecords mIccRecords; 64 65 private class IccRecordsTestHandler extends HandlerThread { IccRecordsTestHandler(String name)66 private IccRecordsTestHandler(String name) { 67 super(name); 68 } 69 70 @Override onLooperPrepared()71 public void onLooperPrepared() { 72 mIccRecords = new SIMRecords(mUiccCardApplication3gpp, mContext, mSimulatedCommands); 73 setReady(true); 74 } 75 } 76 77 @Before setUp()78 public void setUp() throws Exception { 79 super.setUp(this.getClass().getSimpleName()); 80 new IccRecordsTestHandler(TAG).start(); 81 waitUntilReady(); 82 verify(mUiccCardApplication3gpp).registerForReady( 83 mIccRecords, EVENT_APP_READY, null); 84 verify(mUiccCardApplication3gpp).registerForDetected( 85 mIccRecords, EVENT_APP_DETECTED, null); 86 } 87 88 @After tearDown()89 public void tearDown() throws Exception { 90 mIccRecords = null; 91 super.tearDown(); 92 } 93 94 @Test testDisposeCallsUnregisterForIccRefresh()95 public void testDisposeCallsUnregisterForIccRefresh() { 96 // verify called below when IccRecords object is created 97 verify(mSimulatedCommandsVerifier).registerForIccRefresh(eq(mIccRecords), 98 eq(IccRecords.EVENT_REFRESH), isNull()); 99 mIccRecords.dispose(); 100 // verify called within dispose 101 verify(mSimulatedCommandsVerifier).unregisterForIccRefresh(eq(mIccRecords)); 102 103 } 104 105 @Test testSetImsiInvalid()106 public void testSetImsiInvalid() { 107 mIccRecords.setImsi("0123456789FFFFFF"); 108 assertEquals(mIccRecords.getIMSI(), "0123456789"); 109 mIccRecords.setImsi("0123456789ffffff"); 110 assertEquals(mIccRecords.getIMSI(), "0123456789"); 111 mIccRecords.setImsi("ffffff"); 112 assertEquals(mIccRecords.getIMSI(), null); 113 mIccRecords.setImsi("12F34F567890"); 114 assertEquals(mIccRecords.getIMSI(), null); 115 mIccRecords.setImsi("123456ABCDEF"); 116 assertEquals(mIccRecords.getIMSI(), null); 117 } 118 119 @Test testPendingTansaction()120 public void testPendingTansaction() { 121 Message msg = Message.obtain(); 122 Object obj = new Object(); 123 int key = mIccRecords.storePendingTransaction(msg, obj); 124 Pair<Message, Object> pair = mIccRecords.retrievePendingTransaction(key); 125 assertEquals(msg, pair.first); 126 assertEquals(obj, pair.second); 127 pair = mIccRecords.retrievePendingTransaction(key); 128 assertNull(pair); 129 } 130 131 @Test testGetSmsCapacityOnIcc()132 public void testGetSmsCapacityOnIcc() { 133 // set the number of records to 500 134 int[] records = new int[3]; 135 records[2] = 500; 136 Message fetchCapacityDone = mIccRecords.obtainMessage( 137 IccRecords.EVENT_GET_SMS_RECORD_SIZE_DONE); 138 AsyncResult.forMessage(fetchCapacityDone, records, null); 139 fetchCapacityDone.sendToTarget(); 140 141 // verify whether the count is 500 142 waitForLastHandlerAction(mIccRecords); 143 assertEquals(mIccRecords.getSmsCapacityOnIcc(), 500); 144 } 145 146 @Test testGetIccSimChallengeResponseNull()147 public void testGetIccSimChallengeResponseNull() { 148 long startTime; 149 long timeSpent; 150 151 // EAP-SIM rand is 16 bytes. 152 String base64Challenge = "ECcTqwuo6OfY8ddFRboD9WM="; 153 154 // Test for null result 155 mSimulatedCommands.setAuthenticationMode(mSimulatedCommands.ICC_AUTHENTICATION_MODE_NULL); 156 157 startTime = SystemClock.elapsedRealtime(); 158 assertNull("getIccAuthentication should return null for empty data.", 159 mIccRecords.getIccSimChallengeResponse(UiccCardApplication.AUTH_CONTEXT_EAP_AKA, 160 base64Challenge)); 161 timeSpent = SystemClock.elapsedRealtime() - startTime; 162 Log.d("IccRecordsTest", "Time (ms) for getIccSimChallengeResponse is " + timeSpent); 163 assertTrue("getIccAuthentication should not timeout", 164 timeSpent < mSimulatedCommands.ICC_SIM_CHALLENGE_TIMEOUT_MILLIS); 165 } 166 167 @Test testGetIccSimChallengeResponseTimeout()168 public void testGetIccSimChallengeResponseTimeout() { 169 long startTime; 170 long timeSpent; 171 172 // EAP-SIM rand is 16 bytes. 173 String base64Challenge = "ECcTqwuo6OfY8ddFRboD9WM="; 174 175 mSimulatedCommands.setAuthenticationMode( 176 mSimulatedCommands.ICC_AUTHENTICATION_MODE_TIMEOUT); 177 startTime = SystemClock.elapsedRealtime(); 178 assertNull("getIccAuthentication should return null for empty data.", 179 mIccRecords.getIccSimChallengeResponse(UiccCardApplication.AUTH_CONTEXT_EAP_AKA, 180 base64Challenge)); 181 timeSpent = SystemClock.elapsedRealtime() - startTime; 182 Log.d("IccRecordsTest", "Time (ms) for getIccSimChallengeResponse is " + timeSpent); 183 assertTrue("getIccAuthentication should timeout", 184 timeSpent >= mSimulatedCommands.ICC_SIM_CHALLENGE_TIMEOUT_MILLIS); 185 } 186 187 @Test testAppStateChange()188 public void testAppStateChange() { 189 assertFalse(mIccRecords.isLoaded()); 190 191 mIccRecords.obtainMessage(EVENT_APP_READY).sendToTarget(); 192 waitForLastHandlerAction(mIccRecords); 193 assertTrue(mIccRecords.isLoaded()); 194 195 mIccRecords.obtainMessage(EVENT_APP_DETECTED).sendToTarget(); 196 waitForLastHandlerAction(mIccRecords); 197 assertFalse(mIccRecords.isLoaded()); 198 199 mIccRecords.obtainMessage(EVENT_APP_READY).sendToTarget(); 200 waitForLastHandlerAction(mIccRecords); 201 assertTrue(mIccRecords.isLoaded()); 202 } 203 204 @Test testGetIccSimChallengeResponseDefault()205 public void testGetIccSimChallengeResponseDefault() { 206 long startTime; 207 long timeSpent; 208 209 // EAP-SIM rand is 16 bytes. 210 String base64Challenge = "ECcTqwuo6OfY8ddFRboD9WM="; 211 String base64Challenge2 = "EMNxjsFrPCpm+KcgCmQGnwQ="; 212 213 // Test for default setup 214 mSimulatedCommands.setAuthenticationMode( 215 mSimulatedCommands.ICC_AUTHENTICATION_MODE_DEFAULT); 216 217 // Test for null input 218 startTime = SystemClock.elapsedRealtime(); 219 assertNull("getIccAuthentication should return null for empty data.", 220 mIccRecords.getIccSimChallengeResponse( 221 UiccCardApplication.AUTH_CONTEXT_EAP_AKA, "")); 222 timeSpent = SystemClock.elapsedRealtime() - startTime; 223 Log.d("IccRecordsTest", "Time (ms) for getIccSimChallengeResponse is " + timeSpent); 224 assertTrue("getIccAuthentication should not timeout", 225 timeSpent < mSimulatedCommands.ICC_SIM_CHALLENGE_TIMEOUT_MILLIS); 226 227 // EAP-SIM 228 startTime = SystemClock.elapsedRealtime(); 229 String response = mIccRecords.getIccSimChallengeResponse( 230 UiccCardApplication.AUTH_CONTEXT_EAP_SIM, base64Challenge); 231 timeSpent = SystemClock.elapsedRealtime() - startTime; 232 Log.d("IccRecordsTest", "Time (ms) for getIccSimChallengeResponse is " + timeSpent); 233 Log.d("IccRecordsTest", "Result of getIccSimChallengeResponse is " + response); 234 assertTrue("Response to EAP-SIM Challenge must not be Null.", response != null); 235 236 startTime = SystemClock.elapsedRealtime(); 237 String response1 = mIccRecords.getIccSimChallengeResponse( 238 UiccCardApplication.AUTH_CONTEXT_EAP_SIM, base64Challenge); 239 timeSpent = SystemClock.elapsedRealtime() - startTime; 240 Log.d("IccRecordsTest", "Time (ms) for getIccSimChallengeResponse is " + timeSpent); 241 Log.d("IccRecordsTest", "Result of getIccSimChallengeResponse is " + response1); 242 assertTrue("Response to EAP-SIM Challenge must be consistent.", 243 response.equals(response1)); 244 245 startTime = SystemClock.elapsedRealtime(); 246 String response2 = mIccRecords.getIccSimChallengeResponse( 247 UiccCardApplication.AUTH_CONTEXT_EAP_SIM, base64Challenge2); 248 timeSpent = SystemClock.elapsedRealtime() - startTime; 249 Log.d("IccRecordsTest", "Time (ms) for getIccSimChallengeResponse is " + timeSpent); 250 assertTrue("Two responses must be different.", !response.equals(response2)); 251 } 252 253 @Test testOperatorPlmnInfo()254 public void testOperatorPlmnInfo() { 255 String plmn = "123456"; 256 int lacTacStart = 0x0000; 257 int lacTacEnd = 0xFFFE; 258 int pnnIndex = 2; 259 260 OperatorPlmnInfo opi = new OperatorPlmnInfo(plmn, lacTacStart, lacTacEnd, pnnIndex); 261 assertEquals(opi.getPnnIdx(plmn, lacTacStart), pnnIndex - 1); 262 assertEquals(opi.getPnnIdx(plmn, lacTacEnd), pnnIndex - 1); 263 assertEquals(opi.getPnnIdx(plmn, 0xFFFF), pnnIndex - 1); 264 assertEquals(opi.getPnnIdx("654321", 0xFFFF), -1); 265 assertEquals(opi.getPnnIdx("12345", 0xFFFF), -1); 266 267 lacTacStart = 0x0001; 268 lacTacEnd = 0x1FFF; 269 opi = new OperatorPlmnInfo(plmn, lacTacStart, lacTacEnd, pnnIndex); 270 assertEquals(opi.getPnnIdx(plmn, 2), pnnIndex - 1); 271 assertEquals(opi.getPnnIdx(plmn, 0x2FFF), -1); 272 assertEquals(opi.getPnnIdx(plmn, 0xFFFF), -1); 273 274 plmn = "123DDD"; 275 opi = new OperatorPlmnInfo(plmn, lacTacStart, lacTacEnd, pnnIndex); 276 assertEquals(opi.getPnnIdx("123123", lacTacStart), pnnIndex - 1); 277 assertEquals(opi.getPnnIdx("12345", lacTacStart), -1); 278 } 279 280 @Test testGetNetworkNameForPlmn()281 public void testGetNetworkNameForPlmn() { 282 // Set up PNN 283 String fullName1 = "Name full 1"; 284 String shortName1 = "Name short 1"; 285 String fullName2 = "Name full 2"; 286 String shortName2 = "Name short 2"; 287 List<PlmnNetworkName> pnns = new ArrayList<PlmnNetworkName>(); 288 pnns.add(new PlmnNetworkName(fullName1, shortName1)); 289 pnns.add(new PlmnNetworkName(fullName2, shortName2)); 290 pnns.add(new PlmnNetworkName(null, shortName2)); 291 PlmnNetworkName[] pnnsArray = pnns.toArray(new PlmnNetworkName[0]); 292 293 // Set up OPL 294 String plmn1 = "345678"; 295 String plmn2 = "456789"; 296 String plmn3 = "567890"; 297 int lacTacStart = 0x0000; 298 int lacTacEnd = 0xFFFE; 299 int pnnIndex = 1; 300 List<OperatorPlmnInfo> opl = new ArrayList<OperatorPlmnInfo>(); 301 opl.add(new OperatorPlmnInfo(plmn1, lacTacStart, lacTacEnd, pnnIndex)); 302 opl.add(new OperatorPlmnInfo(plmn2, lacTacStart, lacTacEnd, pnnIndex + 1)); 303 opl.add(new OperatorPlmnInfo(plmn3, lacTacStart, lacTacEnd, pnnIndex + 2)); 304 OperatorPlmnInfo[] oplArray = opl.toArray(new OperatorPlmnInfo[0]); 305 306 // Test 307 assertNull(IccRecords.getNetworkNameForPlmnFromPnnOpl(pnnsArray, oplArray, null, 0)); 308 assertEquals(fullName1, IccRecords.getNetworkNameForPlmnFromPnnOpl(pnnsArray, oplArray, 309 plmn1, 0)); 310 assertEquals(fullName2, IccRecords.getNetworkNameForPlmnFromPnnOpl(pnnsArray, oplArray, 311 plmn2, 0)); 312 assertEquals(shortName2, IccRecords.getNetworkNameForPlmnFromPnnOpl(pnnsArray, oplArray, 313 plmn3, 0)); 314 } 315 316 @Test testGetNetworkNameForPlmnFromPnnOpl()317 public void testGetNetworkNameForPlmnFromPnnOpl() { 318 // Set up PNN 319 String fullName1 = "Name full 1"; 320 String shortName1 = "Name short 1"; 321 String fullName2 = "Name full 2"; 322 String shortName2 = "Name short 2"; 323 List<PlmnNetworkName> pnns = new ArrayList<PlmnNetworkName>(); 324 pnns.add(new PlmnNetworkName(fullName1, shortName1)); 325 pnns.add(new PlmnNetworkName(fullName2, shortName2)); 326 pnns.add(new PlmnNetworkName(null, shortName2)); 327 PlmnNetworkName[] pnnsArray = pnns.toArray(new PlmnNetworkName[0]); 328 329 // Set up OPL 330 String plmn1 = "345678"; 331 String plmn2 = "456789"; 332 String plmn3 = "567890"; 333 int lacTacStart = 0x0000; 334 int lacTacEnd = 0xFFFE; 335 int pnnIndex = 1; 336 List<OperatorPlmnInfo> opl = new ArrayList<OperatorPlmnInfo>(); 337 opl.add(new OperatorPlmnInfo(plmn1, lacTacStart, lacTacEnd, pnnIndex)); 338 opl.add(new OperatorPlmnInfo(plmn2, lacTacStart, lacTacEnd, pnnIndex + 1)); 339 opl.add(new OperatorPlmnInfo(plmn3, lacTacStart, lacTacEnd, pnnIndex + 2)); 340 OperatorPlmnInfo[] oplArray = opl.toArray(new OperatorPlmnInfo[0]); 341 342 // Test 343 assertNull(IccRecords.getNetworkNameForPlmnFromPnnOpl(pnnsArray, oplArray, null, 0)); 344 assertEquals(fullName1, IccRecords.getNetworkNameForPlmnFromPnnOpl(pnnsArray, oplArray, 345 plmn1, 0)); 346 assertEquals(fullName2, IccRecords.getNetworkNameForPlmnFromPnnOpl(pnnsArray, oplArray, 347 plmn2, 0)); 348 assertEquals(shortName2, IccRecords.getNetworkNameForPlmnFromPnnOpl(pnnsArray, oplArray, 349 plmn3, 0)); 350 } 351 } 352