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