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 super.tearDown(); 91 } 92 93 @Test testDisposeCallsUnregisterForIccRefresh()94 public void testDisposeCallsUnregisterForIccRefresh() { 95 // verify called below when IccRecords object is created 96 verify(mSimulatedCommandsVerifier).registerForIccRefresh(eq(mIccRecords), 97 eq(IccRecords.EVENT_REFRESH), isNull()); 98 mIccRecords.dispose(); 99 // verify called within dispose 100 verify(mSimulatedCommandsVerifier).unregisterForIccRefresh(eq(mIccRecords)); 101 102 } 103 104 @Test testSetImsiInvalid()105 public void testSetImsiInvalid() { 106 mIccRecords.setImsi("0123456789FFFFFF"); 107 assertEquals(mIccRecords.getIMSI(), "0123456789"); 108 mIccRecords.setImsi("0123456789ffffff"); 109 assertEquals(mIccRecords.getIMSI(), "0123456789"); 110 mIccRecords.setImsi("ffffff"); 111 assertEquals(mIccRecords.getIMSI(), null); 112 mIccRecords.setImsi("12F34F567890"); 113 assertEquals(mIccRecords.getIMSI(), null); 114 mIccRecords.setImsi("123456ABCDEF"); 115 assertEquals(mIccRecords.getIMSI(), null); 116 } 117 118 @Test testPendingTansaction()119 public void testPendingTansaction() { 120 Message msg = Message.obtain(); 121 Object obj = new Object(); 122 int key = mIccRecords.storePendingTransaction(msg, obj); 123 Pair<Message, Object> pair = mIccRecords.retrievePendingTransaction(key); 124 assertEquals(msg, pair.first); 125 assertEquals(obj, pair.second); 126 pair = mIccRecords.retrievePendingTransaction(key); 127 assertNull(pair); 128 } 129 130 @Test testGetSmsCapacityOnIcc()131 public void testGetSmsCapacityOnIcc() { 132 // set the number of records to 500 133 int[] records = new int[3]; 134 records[2] = 500; 135 Message fetchCapacityDone = mIccRecords.obtainMessage( 136 IccRecords.EVENT_GET_SMS_RECORD_SIZE_DONE); 137 AsyncResult.forMessage(fetchCapacityDone, records, null); 138 fetchCapacityDone.sendToTarget(); 139 140 // verify whether the count is 500 141 waitForLastHandlerAction(mIccRecords); 142 assertEquals(mIccRecords.getSmsCapacityOnIcc(), 500); 143 } 144 145 @Test testGetIccSimChallengeResponseNull()146 public void testGetIccSimChallengeResponseNull() { 147 long startTime; 148 long timeSpent; 149 150 // EAP-SIM rand is 16 bytes. 151 String base64Challenge = "ECcTqwuo6OfY8ddFRboD9WM="; 152 153 // Test for null result 154 mSimulatedCommands.setAuthenticationMode(mSimulatedCommands.ICC_AUTHENTICATION_MODE_NULL); 155 156 startTime = SystemClock.elapsedRealtime(); 157 assertNull("getIccAuthentication should return null for empty data.", 158 mIccRecords.getIccSimChallengeResponse(UiccCardApplication.AUTH_CONTEXT_EAP_AKA, 159 base64Challenge)); 160 timeSpent = SystemClock.elapsedRealtime() - startTime; 161 Log.d("IccRecordsTest", "Time (ms) for getIccSimChallengeResponse is " + timeSpent); 162 assertTrue("getIccAuthentication should not timeout", 163 timeSpent < mSimulatedCommands.ICC_SIM_CHALLENGE_TIMEOUT_MILLIS); 164 } 165 166 @Test testGetIccSimChallengeResponseTimeout()167 public void testGetIccSimChallengeResponseTimeout() { 168 long startTime; 169 long timeSpent; 170 171 // EAP-SIM rand is 16 bytes. 172 String base64Challenge = "ECcTqwuo6OfY8ddFRboD9WM="; 173 174 mSimulatedCommands.setAuthenticationMode( 175 mSimulatedCommands.ICC_AUTHENTICATION_MODE_TIMEOUT); 176 startTime = SystemClock.elapsedRealtime(); 177 assertNull("getIccAuthentication should return null for empty data.", 178 mIccRecords.getIccSimChallengeResponse(UiccCardApplication.AUTH_CONTEXT_EAP_AKA, 179 base64Challenge)); 180 timeSpent = SystemClock.elapsedRealtime() - startTime; 181 Log.d("IccRecordsTest", "Time (ms) for getIccSimChallengeResponse is " + timeSpent); 182 assertTrue("getIccAuthentication should timeout", 183 timeSpent >= mSimulatedCommands.ICC_SIM_CHALLENGE_TIMEOUT_MILLIS); 184 } 185 186 @Test testAppStateChange()187 public void testAppStateChange() { 188 assertFalse(mIccRecords.isLoaded()); 189 190 mIccRecords.obtainMessage(EVENT_APP_READY).sendToTarget(); 191 waitForLastHandlerAction(mIccRecords); 192 assertTrue(mIccRecords.isLoaded()); 193 194 mIccRecords.obtainMessage(EVENT_APP_DETECTED).sendToTarget(); 195 waitForLastHandlerAction(mIccRecords); 196 assertFalse(mIccRecords.isLoaded()); 197 198 mIccRecords.obtainMessage(EVENT_APP_READY).sendToTarget(); 199 waitForLastHandlerAction(mIccRecords); 200 assertTrue(mIccRecords.isLoaded()); 201 } 202 203 @Test testGetIccSimChallengeResponseDefault()204 public void testGetIccSimChallengeResponseDefault() { 205 long startTime; 206 long timeSpent; 207 208 // EAP-SIM rand is 16 bytes. 209 String base64Challenge = "ECcTqwuo6OfY8ddFRboD9WM="; 210 String base64Challenge2 = "EMNxjsFrPCpm+KcgCmQGnwQ="; 211 212 // Test for default setup 213 mSimulatedCommands.setAuthenticationMode( 214 mSimulatedCommands.ICC_AUTHENTICATION_MODE_DEFAULT); 215 216 // Test for null input 217 startTime = SystemClock.elapsedRealtime(); 218 assertNull("getIccAuthentication should return null for empty data.", 219 mIccRecords.getIccSimChallengeResponse( 220 UiccCardApplication.AUTH_CONTEXT_EAP_AKA, "")); 221 timeSpent = SystemClock.elapsedRealtime() - startTime; 222 Log.d("IccRecordsTest", "Time (ms) for getIccSimChallengeResponse is " + timeSpent); 223 assertTrue("getIccAuthentication should not timeout", 224 timeSpent < mSimulatedCommands.ICC_SIM_CHALLENGE_TIMEOUT_MILLIS); 225 226 // EAP-SIM 227 startTime = SystemClock.elapsedRealtime(); 228 String response = mIccRecords.getIccSimChallengeResponse( 229 UiccCardApplication.AUTH_CONTEXT_EAP_SIM, base64Challenge); 230 timeSpent = SystemClock.elapsedRealtime() - startTime; 231 Log.d("IccRecordsTest", "Time (ms) for getIccSimChallengeResponse is " + timeSpent); 232 Log.d("IccRecordsTest", "Result of getIccSimChallengeResponse is " + response); 233 assertTrue("Response to EAP-SIM Challenge must not be Null.", response != null); 234 235 startTime = SystemClock.elapsedRealtime(); 236 String response1 = mIccRecords.getIccSimChallengeResponse( 237 UiccCardApplication.AUTH_CONTEXT_EAP_SIM, base64Challenge); 238 timeSpent = SystemClock.elapsedRealtime() - startTime; 239 Log.d("IccRecordsTest", "Time (ms) for getIccSimChallengeResponse is " + timeSpent); 240 Log.d("IccRecordsTest", "Result of getIccSimChallengeResponse is " + response1); 241 assertTrue("Response to EAP-SIM Challenge must be consistent.", 242 response.equals(response1)); 243 244 startTime = SystemClock.elapsedRealtime(); 245 String response2 = mIccRecords.getIccSimChallengeResponse( 246 UiccCardApplication.AUTH_CONTEXT_EAP_SIM, base64Challenge2); 247 timeSpent = SystemClock.elapsedRealtime() - startTime; 248 Log.d("IccRecordsTest", "Time (ms) for getIccSimChallengeResponse is " + timeSpent); 249 assertTrue("Two responses must be different.", !response.equals(response2)); 250 } 251 252 @Test testOperatorPlmnInfo()253 public void testOperatorPlmnInfo() { 254 String plmn = "123456"; 255 int lacTacStart = 0x0000; 256 int lacTacEnd = 0xFFFE; 257 int pnnIndex = 2; 258 259 OperatorPlmnInfo opi = new OperatorPlmnInfo(plmn, lacTacStart, lacTacEnd, pnnIndex); 260 assertEquals(opi.getPnnIdx(plmn, lacTacStart), pnnIndex - 1); 261 assertEquals(opi.getPnnIdx(plmn, lacTacEnd), pnnIndex - 1); 262 assertEquals(opi.getPnnIdx(plmn, 0xFFFF), pnnIndex - 1); 263 assertEquals(opi.getPnnIdx("654321", 0xFFFF), -1); 264 assertEquals(opi.getPnnIdx("12345", 0xFFFF), -1); 265 266 lacTacStart = 0x0001; 267 lacTacEnd = 0x1FFF; 268 opi = new OperatorPlmnInfo(plmn, lacTacStart, lacTacEnd, pnnIndex); 269 assertEquals(opi.getPnnIdx(plmn, 2), pnnIndex - 1); 270 assertEquals(opi.getPnnIdx(plmn, 0x2FFF), -1); 271 assertEquals(opi.getPnnIdx(plmn, 0xFFFF), -1); 272 273 plmn = "123DDD"; 274 opi = new OperatorPlmnInfo(plmn, lacTacStart, lacTacEnd, pnnIndex); 275 assertEquals(opi.getPnnIdx("123123", lacTacStart), pnnIndex - 1); 276 assertEquals(opi.getPnnIdx("12345", lacTacStart), -1); 277 } 278 279 @Test testGetNetworkNameForPlmn()280 public void testGetNetworkNameForPlmn() { 281 // Set up PNN 282 String fullName1 = "Name full 1"; 283 String shortName1 = "Name short 1"; 284 String fullName2 = "Name full 2"; 285 String shortName2 = "Name short 2"; 286 List<PlmnNetworkName> pnns = new ArrayList<PlmnNetworkName>(); 287 pnns.add(new PlmnNetworkName(fullName1, shortName1)); 288 pnns.add(new PlmnNetworkName(fullName2, shortName2)); 289 pnns.add(new PlmnNetworkName(null, shortName2)); 290 PlmnNetworkName[] pnnsArray = pnns.toArray(new PlmnNetworkName[0]); 291 292 // Set up OPL 293 String plmn1 = "345678"; 294 String plmn2 = "456789"; 295 String plmn3 = "567890"; 296 int lacTacStart = 0x0000; 297 int lacTacEnd = 0xFFFE; 298 int pnnIndex = 1; 299 List<OperatorPlmnInfo> opl = new ArrayList<OperatorPlmnInfo>(); 300 opl.add(new OperatorPlmnInfo(plmn1, lacTacStart, lacTacEnd, pnnIndex)); 301 opl.add(new OperatorPlmnInfo(plmn2, lacTacStart, lacTacEnd, pnnIndex + 1)); 302 opl.add(new OperatorPlmnInfo(plmn3, lacTacStart, lacTacEnd, pnnIndex + 2)); 303 OperatorPlmnInfo[] oplArray = opl.toArray(new OperatorPlmnInfo[0]); 304 305 // Test 306 assertNull(IccRecords.getNetworkNameForPlmnFromPnnOpl(pnnsArray, oplArray, null, 0)); 307 assertEquals(fullName1, IccRecords.getNetworkNameForPlmnFromPnnOpl(pnnsArray, oplArray, 308 plmn1, 0)); 309 assertEquals(fullName2, IccRecords.getNetworkNameForPlmnFromPnnOpl(pnnsArray, oplArray, 310 plmn2, 0)); 311 assertEquals(shortName2, IccRecords.getNetworkNameForPlmnFromPnnOpl(pnnsArray, oplArray, 312 plmn3, 0)); 313 } 314 315 @Test testGetNetworkNameForPlmnFromPnnOpl()316 public void testGetNetworkNameForPlmnFromPnnOpl() { 317 // Set up PNN 318 String fullName1 = "Name full 1"; 319 String shortName1 = "Name short 1"; 320 String fullName2 = "Name full 2"; 321 String shortName2 = "Name short 2"; 322 List<PlmnNetworkName> pnns = new ArrayList<PlmnNetworkName>(); 323 pnns.add(new PlmnNetworkName(fullName1, shortName1)); 324 pnns.add(new PlmnNetworkName(fullName2, shortName2)); 325 pnns.add(new PlmnNetworkName(null, shortName2)); 326 PlmnNetworkName[] pnnsArray = pnns.toArray(new PlmnNetworkName[0]); 327 328 // Set up OPL 329 String plmn1 = "345678"; 330 String plmn2 = "456789"; 331 String plmn3 = "567890"; 332 int lacTacStart = 0x0000; 333 int lacTacEnd = 0xFFFE; 334 int pnnIndex = 1; 335 List<OperatorPlmnInfo> opl = new ArrayList<OperatorPlmnInfo>(); 336 opl.add(new OperatorPlmnInfo(plmn1, lacTacStart, lacTacEnd, pnnIndex)); 337 opl.add(new OperatorPlmnInfo(plmn2, lacTacStart, lacTacEnd, pnnIndex + 1)); 338 opl.add(new OperatorPlmnInfo(plmn3, lacTacStart, lacTacEnd, pnnIndex + 2)); 339 OperatorPlmnInfo[] oplArray = opl.toArray(new OperatorPlmnInfo[0]); 340 341 // Test 342 assertNull(IccRecords.getNetworkNameForPlmnFromPnnOpl(pnnsArray, oplArray, null, 0)); 343 assertEquals(fullName1, IccRecords.getNetworkNameForPlmnFromPnnOpl(pnnsArray, oplArray, 344 plmn1, 0)); 345 assertEquals(fullName2, IccRecords.getNetworkNameForPlmnFromPnnOpl(pnnsArray, oplArray, 346 plmn2, 0)); 347 assertEquals(shortName2, IccRecords.getNetworkNameForPlmnFromPnnOpl(pnnsArray, oplArray, 348 plmn3, 0)); 349 } 350 } 351