1 /*
2  * Copyright (C) 2018 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 
17 package com.android.internal.telephony.uicc.euicc;
18 
19 import static org.junit.Assert.assertArrayEquals;
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertFalse;
22 import static org.junit.Assert.assertTrue;
23 import static org.junit.Assert.fail;
24 import static org.mockito.ArgumentMatchers.any;
25 import static org.mockito.ArgumentMatchers.anyInt;
26 import static org.mockito.ArgumentMatchers.eq;
27 import static org.mockito.Mockito.never;
28 import static org.mockito.Mockito.times;
29 import static org.mockito.Mockito.verify;
30 import static org.mockito.Mockito.when;
31 
32 import android.content.res.Resources;
33 import android.os.Handler;
34 import android.os.Looper;
35 import android.os.Message;
36 import android.service.carrier.CarrierIdentifier;
37 import android.service.euicc.EuiccProfileInfo;
38 import android.telephony.UiccAccessRule;
39 import android.telephony.euicc.EuiccCardManager;
40 import android.telephony.euicc.EuiccNotification;
41 import android.telephony.euicc.EuiccRulesAuthTable;
42 import android.testing.AndroidTestingRunner;
43 import android.testing.TestableLooper;
44 import android.util.ExceptionUtils;
45 import android.util.Log;
46 
47 import com.android.internal.telephony.CommandsInterface;
48 import com.android.internal.telephony.TelephonyTest;
49 import com.android.internal.telephony.uicc.IccCardApplicationStatus;
50 import com.android.internal.telephony.uicc.IccCardStatus;
51 import com.android.internal.telephony.uicc.IccUtils;
52 import com.android.internal.telephony.uicc.asn1.Asn1Node;
53 import com.android.internal.telephony.uicc.asn1.InvalidAsn1DataException;
54 import com.android.internal.telephony.uicc.asn1.TagNotFoundException;
55 import com.android.internal.telephony.uicc.euicc.apdu.ApduException;
56 import com.android.internal.telephony.uicc.euicc.apdu.LogicalChannelMocker;
57 import com.android.internal.telephony.uicc.euicc.async.AsyncResultCallback;
58 
59 import org.junit.After;
60 import org.junit.Before;
61 import org.junit.Test;
62 import org.junit.runner.RunWith;
63 import org.mockito.Mock;
64 
65 import java.util.Arrays;
66 import java.util.concurrent.CountDownLatch;
67 
68 @RunWith(AndroidTestingRunner.class)
69 @TestableLooper.RunWithLooper
70 public class EuiccCardTest extends TelephonyTest {
71 
72     private static class ResultCaptor<T> extends AsyncResultCallback<T> {
73         public T result;
74         public Throwable exception;
75 
76         private CountDownLatch mLatch;
77 
ResultCaptor()78         private ResultCaptor() {
79             mLatch = new CountDownLatch(1);
80         }
81 
82         @Override
onResult(T r)83         public void onResult(T r) {
84             result = r;
85             mLatch.countDown();
86         }
87 
88         @Override
onException(Throwable e)89         public void onException(Throwable e) {
90             exception = e;
91             mLatch.countDown();
92         }
93     }
94 
95     @Mock
96     private CommandsInterface mMockCi;
97     @Mock
98     private IccCardStatus mMockIccCardStatus;
99 
100     private Handler mHandler;
101 
102     private EuiccCard mEuiccCard;
103 
104     @Mock
105     private Resources mMockResources;
106 
107     @Before
setUp()108     public void setUp() throws Exception {
109         super.setUp(getClass().getSimpleName());
110 
111         mMockIccCardStatus.mApplications = new IccCardApplicationStatus[]{};
112         mMockIccCardStatus.mCdmaSubscriptionAppIndex =
113                 mMockIccCardStatus.mImsSubscriptionAppIndex =
114                         mMockIccCardStatus.mGsmUmtsSubscriptionAppIndex = -1;
115         mMockIccCardStatus.mCardState = IccCardStatus.CardState.CARDSTATE_PRESENT;
116 
117         mEuiccCard =
118             new EuiccCard(mContext, mMockCi, mMockIccCardStatus,
119                 0 /* phoneId */, new Object()) {
120                 @Override
121                 protected byte[] getDeviceId() {
122                     return IccUtils.bcdToBytes("987654321012345");
123                 }
124 
125                 @Override
126                 protected void loadEidAndNotifyRegistrants() {}
127 
128                 @Override
129                 protected Resources getResources() {
130                     return mMockResources;
131                 }
132 
133             };
134         mHandler = new Handler(Looper.myLooper());
135         processAllMessages();
136     }
137 
138     @After
tearDown()139     public void tearDown() throws Exception {
140         super.tearDown();
141     }
142 
assertUnexpectedException(Throwable e)143     private void assertUnexpectedException(Throwable e) {
144         if (e != null) {
145             fail("Unexpected exception: " + ExceptionUtils.getCompleteMessage(e) + "\n-----\n"
146                     + Log.getStackTraceString(e.getCause()) + "-----");
147         }
148     }
149 
150     @Test
testPassEidInConstructor()151     public void testPassEidInConstructor() {
152         mMockIccCardStatus.eid = "1A2B3C4D";
153         mEuiccCard = new EuiccCard(mContextFixture.getTestDouble(), mMockCi,
154                 mMockIccCardStatus, 0 /* phoneId */, new Object());
155 
156         final int eventEidReady = 0;
157         Handler handler = new Handler(Looper.myLooper()) {
158             @Override
159             public void handleMessage(Message msg) {
160                 if (msg.what == eventEidReady) {
161                     assertEquals("1A2B3C4D", mEuiccCard.getEid());
162                 }
163             }
164         };
165         // This will instantly return, since EID is already set
166         mEuiccCard.registerForEidReady(handler, eventEidReady, null /* obj */);
167         processAllMessages();
168     }
169 
170     @Test
testLoadEidAndNotifyRegistrants()171     public void testLoadEidAndNotifyRegistrants() {
172         int channel = mockLogicalChannelResponses("BF3E065A041A2B3C4D9000");
173         mHandler.post(() -> {
174             mEuiccCard = new EuiccCard(mContextFixture.getTestDouble(), mMockCi,
175                     mMockIccCardStatus, 0 /* phoneId */, new Object());
176         });
177         processAllMessages();
178 
179         final int eventEidReady = 0;
180         Handler handler = new Handler(Looper.myLooper()) {
181             @Override
182             public void handleMessage(Message msg) {
183                 if (msg.what == eventEidReady) {
184                     assertEquals("1A2B3C4D", mEuiccCard.getEid());
185                 }
186             }
187         };
188 
189         mEuiccCard.registerForEidReady(handler, eventEidReady, null /* obj */);
190         processAllMessages();
191         verifyStoreData(channel, "BF3E035C015A");
192     }
193 
194     @Test
testGetAllProfiles()195     public void testGetAllProfiles() {
196         int channel = mockLogicalChannelResponses(
197                 "BF2D14A012E3105A0A896700000000004523019F7001019000");
198 
199         ResultCaptor<EuiccProfileInfo[]> resultCaptor = new ResultCaptor<>();
200         mEuiccCard.getAllProfiles(resultCaptor, mHandler);
201         processAllMessages();
202 
203         assertUnexpectedException(resultCaptor.exception);
204         EuiccProfileInfo[] profiles = resultCaptor.result;
205         assertEquals(1, profiles.length);
206         assertEquals("98760000000000543210", profiles[0].getIccid());
207         assertEquals(EuiccProfileInfo.PROFILE_STATE_ENABLED, profiles[0].getState());
208         verifyStoreData(channel, "BF2D0D5C0B5A909192B79F709599BF76");
209     }
210 
211     @Test
testFSuffix()212     public void testFSuffix() {
213         // iccID is 987600000000005432FF.
214         int channel = mockLogicalChannelResponses(
215                 "BF2D14A012E3105A0A896700000000004523FF9F7001019000");
216 
217         ResultCaptor<EuiccProfileInfo[]> resultCaptor = new ResultCaptor<>();
218         mEuiccCard.getAllProfiles(resultCaptor, mHandler);
219         processAllMessages();
220 
221         EuiccProfileInfo[] profiles = resultCaptor.result;
222         assertEquals(1, profiles.length);
223         assertEquals("987600000000005432", profiles[0].getIccid());
224         assertEquals(EuiccProfileInfo.PROFILE_STATE_ENABLED, profiles[0].getState());
225         verifyStoreData(channel, "BF2D0D5C0B5A909192B79F709599BF76");
226     }
227 
228     @Test
testGetProfile()229     public void testGetProfile() {
230         int channel = mockLogicalChannelResponses("BF2D8184A08181E37F"
231                 + "5A0A89670000000000452301" // ICCID
232                 + "90046E69636B" // Nickname
233                 + "9103746D6F" // Service provider name
234                 + "92027031" // Profile name
235                 + "B70F800312F34581030102038203040506" // Operator id
236                 + "9F700101" // Profile state
237                 + "950101" // Profile class
238                 + "990206C0" // Policy rules
239                 + "BF7645E243E135C114ABCD92CBB156B280FA4E1429A6ECEEB6E5C1BFE4"
240                 + "CA1D636F6D2E676F6F676C652E616E64726F69642E617070732E6D79617070"
241                 + "E30ADB080000000000000001" // Carrier privilege rules
242                 + "9000");
243 
244         ResultCaptor<EuiccProfileInfo> resultCaptor = new ResultCaptor<>();
245         mEuiccCard.getProfile("98760000000000543210", resultCaptor, mHandler);
246         processAllMessages();
247 
248         EuiccProfileInfo profile = resultCaptor.result;
249         assertEquals("98760000000000543210", profile.getIccid());
250         assertEquals("nick", profile.getNickname());
251         assertEquals("tmo", profile.getServiceProviderName());
252         assertEquals("p1", profile.getProfileName());
253         assertEquals("213", profile.getCarrierIdentifier().getMcc());
254         assertEquals("54", profile.getCarrierIdentifier().getMnc());
255         assertEquals("010203", profile.getCarrierIdentifier().getGid1());
256         assertEquals("040506", profile.getCarrierIdentifier().getGid2());
257         assertEquals(EuiccProfileInfo.PROFILE_STATE_ENABLED, profile.getState());
258         assertEquals(EuiccProfileInfo.PROFILE_CLASS_PROVISIONING, profile.getProfileClass());
259         assertEquals(
260                 EuiccProfileInfo.POLICY_RULE_DO_NOT_DELETE
261                         | EuiccProfileInfo.POLICY_RULE_DO_NOT_DISABLE,
262                 profile.getPolicyRules());
263         assertArrayEquals(
264                 new UiccAccessRule[] {
265                         new UiccAccessRule(
266                                 IccUtils.hexStringToBytes(
267                                         "ABCD92CBB156B280FA4E1429A6ECEEB6E5C1BFE4"),
268                                 "com.google.android.apps.myapp", 1)
269                 },
270                 profile.getUiccAccessRules().toArray());
271         verifyStoreData(channel, "BF2D1BA00C5A0A896700000000004523015C0B5A909192B79F709599BF76");
272     }
273 
274     @Test
testDisableProfile()275     public void testDisableProfile() {
276         int channel = mockLogicalChannelResponses("BF32038001009000");
277 
278         ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
279         mEuiccCard.disableProfile("98760000000000543210", true, resultCaptor, mHandler);
280         processAllMessages();
281 
282         assertUnexpectedException(resultCaptor.exception);
283         verifyStoreData(channel, "BF3211A00C5A0A896700000000004523018101FF");
284     }
285 
286     @Test
testDisableProfile_SimRefresh()287     public void testDisableProfile_SimRefresh() {
288         int channel = mockLogicalChannelResponses("6106", "6f00");
289 
290         ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
291         mEuiccCard.disableProfile("98760000000000543210", true, resultCaptor, mHandler);
292         processAllMessages();
293 
294         assertUnexpectedException(resultCaptor.exception);
295         verifyStoreData(channel, "BF3211A00C5A0A896700000000004523018101FF");
296     }
297 
298     @Test
testDisableProfile_Error()299     public void testDisableProfile_Error() {
300         int channel = mockLogicalChannelResponses("BF32038001039000");
301 
302         ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
303         mEuiccCard.disableProfile("98760000000000543210", true, resultCaptor, mHandler);
304         processAllMessages();
305 
306         assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
307         verifyStoreData(channel, "BF3211A00C5A0A896700000000004523018101FF");
308     }
309 
310     @Test
testSwitchToProfile()311     public void testSwitchToProfile() {
312         int channel = mockLogicalChannelResponses("BF31038001009000");
313 
314         ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
315         mEuiccCard.switchToProfile("98760000000000543210", true, resultCaptor, mHandler);
316         processAllMessages();
317 
318         assertUnexpectedException(resultCaptor.exception);
319         verifyStoreData(channel, "BF3111A00C5A0A896700000000004523018101FF");
320     }
321 
322     @Test
testSwitchToProfile_SimRefresh()323     public void testSwitchToProfile_SimRefresh() {
324         int channel = mockLogicalChannelResponses("6106", "6f00");
325 
326         ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
327         mEuiccCard.switchToProfile("98760000000000543210", true, resultCaptor, mHandler);
328         processAllMessages();
329 
330         assertUnexpectedException(resultCaptor.exception);
331         verifyStoreData(channel, "BF3111A00C5A0A896700000000004523018101FF");
332     }
333 
334     @Test
testSwitchToProfile_Error()335     public void testSwitchToProfile_Error() {
336         int channel = mockLogicalChannelResponses("BF31038001039000");
337 
338         ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
339         mEuiccCard.switchToProfile("98760000000000543210", true, resultCaptor, mHandler);
340         processAllMessages();
341 
342         assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
343         verifyStoreData(channel, "BF3111A00C5A0A896700000000004523018101FF");
344     }
345 
346     @Test
testGetEid()347     public void testGetEid() {
348         int channel = mockLogicalChannelResponses("BF3E065A041A2B3C4D9000");
349 
350         ResultCaptor<String> resultCaptor = new ResultCaptor<>();
351         mEuiccCard.getEid(resultCaptor, mHandler);
352         processAllMessages();
353 
354         assertEquals("1A2B3C4D", resultCaptor.result);
355         verifyStoreData(channel, "BF3E035C015A");
356     }
357 
358     @Test
testSetNickname()359     public void testSetNickname() {
360         int channel = mockLogicalChannelResponses("BF29038001009000");
361 
362         ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
363         mEuiccCard.setNickname("98760000000000543210", "new nickname", resultCaptor, mHandler);
364         processAllMessages();
365 
366         assertUnexpectedException(resultCaptor.exception);
367         verifyStoreData(channel, "BF291A5A0A89670000000000452301900C6E6577206E69636B6E616D65");
368     }
369 
370     @Test
testDeleteProfile()371     public void testDeleteProfile() {
372         int channel = mockLogicalChannelResponses("BF33038001009000");
373 
374         ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
375         mEuiccCard.deleteProfile("98760000000000543210", resultCaptor, mHandler);
376         processAllMessages();
377 
378         assertUnexpectedException(resultCaptor.exception);
379         verifyStoreData(channel, "BF330C5A0A89670000000000452301");
380     }
381 
382     @Test
testDeleteProfile_Error()383     public void testDeleteProfile_Error() {
384         int channel = mockLogicalChannelResponses("BF33038001039000");
385 
386         ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
387         mEuiccCard.deleteProfile("98760000000000543210", resultCaptor, mHandler);
388         processAllMessages();
389 
390         assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
391         verifyStoreData(channel, "BF330C5A0A89670000000000452301");
392     }
393 
394     @Test
testGetDefaultSmdpAddress()395     public void testGetDefaultSmdpAddress() {
396         int channel = mockLogicalChannelResponses(
397                 "BF3C148008534D44502E434F4D8108736D64732E636F6D9000");
398 
399         ResultCaptor<String> resultCaptor = new ResultCaptor<>();
400         mEuiccCard.getDefaultSmdpAddress(resultCaptor, mHandler);
401         processAllMessages();
402 
403         assertEquals("SMDP.COM", resultCaptor.result);
404         verifyStoreData(channel, "BF3C00");
405     }
406 
407     @Test
testGetSmdsAddress()408     public void testGetSmdsAddress() {
409         int channel = mockLogicalChannelResponses(
410                 "BF3C148008534D44502E434F4D8108736D64732E636F6D9000");
411 
412         ResultCaptor<String> resultCaptor = new ResultCaptor<>();
413         mEuiccCard.getSmdsAddress(resultCaptor, mHandler);
414         processAllMessages();
415 
416         assertEquals("smds.com", resultCaptor.result);
417         verifyStoreData(channel, "BF3C00");
418     }
419 
420     @Test
testSetDefaultSmdpAddress()421     public void testSetDefaultSmdpAddress() {
422         int channel = mockLogicalChannelResponses("BF3F038001009000");
423 
424         ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
425         mEuiccCard.setDefaultSmdpAddress("smdp.gsma.com", resultCaptor, mHandler);
426         processAllMessages();
427 
428         assertUnexpectedException(resultCaptor.exception);
429         verifyStoreData(channel, "BF3F0F800D736D64702E67736D612E636F6D");
430     }
431 
432     @Test
testGetRulesAuthTable()433     public void testGetRulesAuthTable() {
434         int channel = mockLogicalChannelResponses("BF434B"
435                 + "A0233021" // Rule #1
436                 + "800206C0" // Policy rules: DO_NOT_DELETE | DO_NOT_DISABLE
437                 + "A118" // Operator IDs
438                 + "B70A800312F3458103010203" // ID #1: 213, 54, [1,2,3], null
439                 + "B70A800312F3458203040506" // ID #2: 213, 54, null, [4,5,6]
440                 + "820108" // Flag (no user consent)
441                 + "A0243022" // Rule #2
442                 + "80020780" // Policy rules: DO_NOT_DISABLE
443                 + "A118" // Operator IDs
444                 + "B70A800312E3458103010203" // ID #1: 213, 54E, [1,2,3], null
445                 + "B70A8003EEEE458203040506" // ID #2: EEE, 54E, null, [4,5,6]
446                 + "82020780" // Flag (user consent)
447                 + "9000");
448 
449         ResultCaptor<EuiccRulesAuthTable> resultCaptor = new ResultCaptor<>();
450         mEuiccCard.getRulesAuthTable(resultCaptor, mHandler);
451         processAllMessages();
452 
453         EuiccRulesAuthTable rat = resultCaptor.result;
454         assertEquals(-1,
455                 rat.findIndex(EuiccProfileInfo.POLICY_RULE_DO_NOT_DELETE,
456                         new CarrierIdentifier(new byte[] {0x12, (byte) 0xF3, 0x45}, null, null)));
457         assertEquals(1,
458                 rat.findIndex(EuiccProfileInfo.POLICY_RULE_DO_NOT_DISABLE,
459                         new CarrierIdentifier(new byte[] {0x23, 0x67, 0x45}, null, "040506")));
460         assertFalse(rat.hasPolicyRuleFlag(0,
461                 EuiccRulesAuthTable.POLICY_RULE_FLAG_CONSENT_REQUIRED));
462         assertTrue(rat.hasPolicyRuleFlag(1,
463                 EuiccRulesAuthTable.POLICY_RULE_FLAG_CONSENT_REQUIRED));
464         verifyStoreData(channel, "BF4300");
465     }
466 
467     @Test
testResetMemory()468     public void testResetMemory() {
469         int channel = mockLogicalChannelResponses("BF34038001009000");
470 
471         ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
472         mEuiccCard.resetMemory(EuiccCardManager.RESET_OPTION_DELETE_FIELD_LOADED_TEST_PROFILES,
473                 resultCaptor, mHandler);
474         processAllMessages();
475 
476         assertUnexpectedException(resultCaptor.exception);
477         verifyStoreData(channel, "BF340482020640");
478     }
479 
480     @Test
testResetMemory_SimRefresh()481     public void testResetMemory_SimRefresh() {
482         int channel = mockLogicalChannelResponses("6106", "6f00");
483 
484         ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
485         mEuiccCard.resetMemory(EuiccCardManager.RESET_OPTION_DELETE_FIELD_LOADED_TEST_PROFILES,
486                 resultCaptor, mHandler);
487         processAllMessages();
488 
489         assertUnexpectedException(resultCaptor.exception);
490         verifyStoreData(channel, "BF340482020640");
491     }
492 
493     @Test
testGetEuiccChallenge()494     public void testGetEuiccChallenge() {
495         int channel = mockLogicalChannelResponses("BF2E0580030102039000");
496 
497         ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
498         mEuiccCard.getEuiccChallenge(resultCaptor, mHandler);
499         processAllMessages();
500 
501         assertArrayEquals(new byte[] {1, 2, 3}, resultCaptor.result);
502         verifyStoreData(channel, "BF2E00");
503     }
504 
505     @Test
testGetEuiccInfo1()506     public void testGetEuiccInfo1() {
507         int channel = mockLogicalChannelResponses("BF20030102039000");
508 
509         ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
510         mEuiccCard.getEuiccInfo1(resultCaptor, mHandler);
511         processAllMessages();
512 
513         assertEquals("BF2003010203", IccUtils.bytesToHexString(resultCaptor.result));
514         verifyStoreData(channel, "BF2000");
515     }
516 
517     @Test
testGetEuiccInfo2()518     public void testGetEuiccInfo2() {
519         int channel = mockLogicalChannelResponses("BF22030102039000");
520 
521         ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
522         mEuiccCard.getEuiccInfo2(resultCaptor, mHandler);
523         processAllMessages();
524 
525         assertEquals("BF2203010203", IccUtils.bytesToHexString(resultCaptor.result));
526         verifyStoreData(channel, "BF2200");
527     }
528 
529     @Test
testAuthenticateServer()530     public void testAuthenticateServer() {
531         when(mMockResources.getStringArray(
532                 com.android.internal.R.array.config_telephonyEuiccDeviceCapabilities))
533                 .thenReturn(new String[] {});
534 
535         int channel = mockLogicalChannelResponses("BF3802A0009000");
536 
537         ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
538         mEuiccCard.authenticateServer("A1B2C3-X4Y5Z6", // Matching id
539                 Asn1Node.newBuilder(0xA0).build().toBytes(),
540                 Asn1Node.newBuilder(0xA1).build().toBytes(),
541                 Asn1Node.newBuilder(0xA2).build().toBytes(),
542                 Asn1Node.newBuilder(0xA3).build().toBytes(), resultCaptor, mHandler);
543         processAllMessages();
544 
545         assertUnexpectedException(resultCaptor.exception);
546         assertEquals("BF3802A000", IccUtils.bytesToHexString(resultCaptor.result));
547         verifyStoreData(channel,
548                 "BF382D" + "A000" + "A100" + "A200" + "A300" + "A023"
549                         + "800D4131423243332D583459355A36" // Matching id
550                         + "A112800489674523" // TAC
551                         + "A100" // Device capabilities
552                         + "82088967452301214305"); // IMEI
553     }
554 
555     @Test
testAuthenticateServer_Error()556     public void testAuthenticateServer_Error() {
557         when(mMockResources.getStringArray(
558                 com.android.internal.R.array.config_telephonyEuiccDeviceCapabilities))
559                 .thenReturn(new String[] {});
560 
561         int channel = mockLogicalChannelResponses("BF3805A1030201039000");
562 
563         ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
564         mEuiccCard.authenticateServer("A1B2C3-X4Y5Z6", // Matching id
565                 Asn1Node.newBuilder(0xA0).build().toBytes(),
566                 Asn1Node.newBuilder(0xA1).build().toBytes(),
567                 Asn1Node.newBuilder(0xA2).build().toBytes(),
568                 Asn1Node.newBuilder(0xA3).build().toBytes(), resultCaptor, mHandler);
569         processAllMessages();
570 
571         assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
572         verifyStoreData(channel,
573                 "BF382D" + "A000" + "A100" + "A200" + "A300" + "A023"
574                         + "800D4131423243332D583459355A36" // Matching id
575                         + "A112800489674523" // TAC
576                         + "A100" // Device capabilities
577                         + "82088967452301214305"); // IMEI
578     }
579 
580     @Test
testAuthenticateService_devCap()581     public void testAuthenticateService_devCap() {
582         when(mMockResources.getStringArray(
583                 com.android.internal.R.array.config_telephonyEuiccDeviceCapabilities))
584                 .thenReturn(new String[] {
585                         "gsm,11",
586                         "utran,11",
587                         "cdma1x,1",
588                         "hrpd,3",
589                         "ehrpd,12",
590                         "eutran,11"});
591 
592         int channel = mockLogicalChannelResponses("BF3802A0009000");
593 
594         ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
595         mEuiccCard.authenticateServer("A1B2C3-X4Y5Z6", // Matching id
596                 Asn1Node.newBuilder(0xA0).build().toBytes(),
597                 Asn1Node.newBuilder(0xA1).build().toBytes(),
598                 Asn1Node.newBuilder(0xA2).build().toBytes(),
599                 Asn1Node.newBuilder(0xA3).build().toBytes(), resultCaptor, mHandler);
600         processAllMessages();
601 
602         assertUnexpectedException(resultCaptor.exception);
603         assertEquals("BF3802A000", IccUtils.bytesToHexString(resultCaptor.result));
604         verifyStoreData(channel,
605                 "BF384B" + "A000" + "A100" + "A200" + "A300" + "A041"
606                         + "800D4131423243332D583459355A36" // Matching id
607                         + "A130800489674523" // TAC
608                         // Device capabilities
609                         + "A11E80030B000081030B00008203010000830303000084030C000085030B0000"
610                         + "82088967452301214305"); // IMEI
611     }
612 
613     @Test
testPrepareDownload()614     public void testPrepareDownload() {
615         int channel = mockLogicalChannelResponses("BF2102A0009000");
616 
617         ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
618         mEuiccCard.prepareDownload(
619                 IccUtils.hexStringToBytes("4131423243332D583459355A36"), // hashCc
620                 Asn1Node.newBuilder(0xA0).build().toBytes(),
621                 Asn1Node.newBuilder(0xA1).build().toBytes(),
622                 Asn1Node.newBuilder(0xA2).build().toBytes(), resultCaptor, mHandler);
623         processAllMessages();
624 
625         assertEquals("BF2102A000", IccUtils.bytesToHexString(resultCaptor.result));
626         verifyStoreData(channel,
627                 "BF2115" + "A000" + "A100"
628                         + "040D4131423243332D583459355A36" // hashCc
629                         + "A200");
630     }
631 
632     @Test
testPrepareDownload_Error()633     public void testPrepareDownload_Error() {
634         int channel = mockLogicalChannelResponses("BF2105A1030201039000");
635 
636         ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
637         mEuiccCard.prepareDownload(
638                 IccUtils.hexStringToBytes("4131423243332D583459355A36"), // hashCc
639                 Asn1Node.newBuilder(0xA0).build().toBytes(),
640                 Asn1Node.newBuilder(0xA1).build().toBytes(),
641                 Asn1Node.newBuilder(0xA2).build().toBytes(), resultCaptor, mHandler);
642         processAllMessages();
643 
644         assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
645         verifyStoreData(channel,
646                 "BF2115" + "A000" + "A100"
647                         + "040D4131423243332D583459355A36" // hashCc
648                         + "A200");
649     }
650 
651     @Test
testLoadBoundProfilePackage()652     public void testLoadBoundProfilePackage() {
653         int channel = mockLogicalChannelResponses(
654                 // For boundProfilePackage head + initialiseSecureChannelRequest
655                 // (ES8+.InitialiseSecureChannel)
656                 "9000",
657                 // For firstSequenceOf87 (ES8+.ConfigureISDP)
658                 "9000",
659                 // For head of sequenceOf88 (ES8+.StoreMetadata)
660                 "9000",
661                 // For body (element 1) of sequenceOf88 (ES8+.StoreMetadata)
662                 "9000",
663                 "9000",
664                 // For head of sequenceOf86 (ES8+.LoadProfileElements)
665                 "9000",
666                 // For body (element 1) of sequenceOf86 (ES8+.LoadProfileElements)
667                 "9000",
668                 // Profile installation result (element 2 of sequenceOf86)
669                 "BF37009000");
670 
671         ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
672         mEuiccCard.loadBoundProfilePackage(
673                 Asn1Node.newBuilder(0xBF36)
674                         .addChild(Asn1Node.newBuilder(0xBF23))
675                         .addChild(Asn1Node.newBuilder(0xA0)
676                                 .addChildAsBytes(0x87, new byte[] {1, 2, 3}))
677                         .addChild(Asn1Node.newBuilder(0xA1)
678                                 .addChildAsBytes(0x88, new byte[] {4, 5, 6}))
679                         .addChild(Asn1Node.newBuilder(0xA2))
680                         .addChild(Asn1Node.newBuilder(0xA3)
681                                 .addChildAsBytes(0x86, new byte[] {7, 8, 9})
682                                 .addChildAsBytes(0x86, new byte[] {0xA, 0xB, 0xC}))
683                         .build().toBytes(),
684                 resultCaptor, mHandler);
685         processAllMessages();
686 
687         assertEquals("BF3700", IccUtils.bytesToHexString(resultCaptor.result));
688         verifyStoreData(channel, "BF361FBF2300"); // ES8+.InitialiseSecureChannel
689         verifyStoreData(channel, "A0058703010203"); // ES8+.ConfigureISDP
690         verifyStoreData(channel, "A105"); // ES8+.StoreMetadata
691         verifyStoreData(channel, "8803040506"); // ES8+.StoreMetadata
692         verifyStoreData(channel, "A200");
693         verifyStoreData(channel, "A30A"); // ES8+.LoadProfileElements
694         verifyStoreData(channel, "8603070809"); // ES8+.LoadProfileElements
695         verifyStoreData(channel, "86030A0B0C"); // ES8+.LoadProfileElements
696     }
697 
698     @Test
testLoadBoundProfilePackage_ErrorAtEnd()699     public void testLoadBoundProfilePackage_ErrorAtEnd() {
700         int channel = mockLogicalChannelResponses(
701                 // For boundProfilePackage head + initialiseSecureChannelRequest
702                 // (ES8+.InitialiseSecureChannel)
703                 "9000",
704                 // For firstSequenceOf87 (ES8+.ConfigureISDP)
705                 "9000",
706                 // For head of sequenceOf88 (ES8+.StoreMetadata)
707                 "9000",
708                 // For body (element 1) of sequenceOf88 (ES8+.StoreMetadata)
709                 "9000",
710                 "9000",
711                 // For head of sequenceOf86 (ES8+.LoadProfileElements)
712                 "9000",
713                 // For body (element 1) of sequenceOf86 (ES8+.LoadProfileElements)
714                 "9000",
715                 // Profile installation result (element 2 of sequenceOf86)
716                 "BF370ABF2707A205A1038101039000");
717 
718         ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
719         mEuiccCard.loadBoundProfilePackage(
720                 Asn1Node.newBuilder(0xBF36)
721                         .addChild(Asn1Node.newBuilder(0xBF23))
722                         .addChild(Asn1Node.newBuilder(0xA0)
723                                 .addChildAsBytes(0x87, new byte[] {1, 2, 3}))
724                         .addChild(Asn1Node.newBuilder(0xA1)
725                                 .addChildAsBytes(0x88, new byte[] {4, 5, 6}))
726                         .addChild(Asn1Node.newBuilder(0xA2))
727                         .addChild(Asn1Node.newBuilder(0xA3)
728                                 .addChildAsBytes(0x86, new byte[] {7, 8, 9})
729                                 .addChildAsBytes(0x86, new byte[] {0xA, 0xB, 0xC}))
730                         .build().toBytes(),
731                 resultCaptor, mHandler);
732         processAllMessages();
733 
734         assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
735         verifyStoreData(channel, "BF361FBF2300"); // ES8+.InitialiseSecureChannel
736         verifyStoreData(channel, "A0058703010203"); // ES8+.ConfigureISDP
737         verifyStoreData(channel, "A105"); // ES8+.StoreMetadata
738         verifyStoreData(channel, "8803040506"); // ES8+.StoreMetadata
739         verifyStoreData(channel, "A200");
740         verifyStoreData(channel, "A30A"); // ES8+.LoadProfileElements
741         verifyStoreData(channel, "8603070809"); // ES8+.LoadProfileElements
742         verifyStoreData(channel, "86030A0B0C"); // ES8+.LoadProfileElements
743     }
744 
745     @Test
testLoadBoundProfilePackage_ErrorInMiddle()746     public void testLoadBoundProfilePackage_ErrorInMiddle() {
747         int channel = mockLogicalChannelResponses(
748                 // For boundProfilePackage head + initialiseSecureChannelRequest
749                 // (ES8+.InitialiseSecureChannel)
750                 "9000",
751                 // For firstSequenceOf87 (ES8+.ConfigureISDP)
752                 "9000",
753                 // For head of sequenceOf88 (ES8+.StoreMetadata)
754                 "9000",
755                 // For body (element 1) of sequenceOf88 (ES8+.StoreMetadata)
756                 "BF370ABF2707A205A1038101039000",
757                 "9000",
758                 // For head of sequenceOf86 (ES8+.LoadProfileElements)
759                 "9000",
760                 // For body (element 1) of sequenceOf86 (ES8+.LoadProfileElements)
761                 "9000",
762                 // Profile installation result (element 2 of sequenceOf86)
763                 "9000");
764 
765         ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
766         mEuiccCard.loadBoundProfilePackage(
767                 Asn1Node.newBuilder(0xBF36)
768                         .addChild(Asn1Node.newBuilder(0xBF23))
769                         .addChild(Asn1Node.newBuilder(0xA0)
770                                 .addChildAsBytes(0x87, new byte[] {1, 2, 3}))
771                         .addChild(Asn1Node.newBuilder(0xA1)
772                                 .addChildAsBytes(0x88, new byte[] {4, 5, 6}))
773                         .addChild(Asn1Node.newBuilder(0xA2))
774                         .addChild(Asn1Node.newBuilder(0xA3)
775                                 .addChildAsBytes(0x86, new byte[] {7, 8, 9})
776                                 .addChildAsBytes(0x86, new byte[] {0xA, 0xB, 0xC}))
777                         .build().toBytes(),
778                 resultCaptor, mHandler);
779         processAllMessages();
780 
781         assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
782         verifyStoreData(channel, "BF361FBF2300"); // ES8+.InitialiseSecureChannel
783         verifyStoreData(channel, "A0058703010203"); // ES8+.ConfigureISDP
784         verifyStoreData(channel, "A105"); // ES8+.StoreMetadata
785         verifyStoreData(channel, "8803040506"); // ES8+.StoreMetadata
786     }
787 
788     @Test
testLoadBoundProfilePackage_ErrorStatus()789     public void testLoadBoundProfilePackage_ErrorStatus() {
790         int channel = mockLogicalChannelResponses(
791                 // For boundProfilePackage head + initialiseSecureChannelRequest
792                 // (ES8+.InitialiseSecureChannel)
793                 "9000",
794                 // For firstSequenceOf87 (ES8+.ConfigureISDP)
795                 "9000",
796                 // For head of sequenceOf88 (ES8+.StoreMetadata)
797                 "9000",
798                 // For body (element 1) of sequenceOf88 (ES8+.StoreMetadata)
799                 "6985",
800                 "9000",
801                 // For head of sequenceOf86 (ES8+.LoadProfileElements)
802                 "9000",
803                 // For body (element 1) of sequenceOf86 (ES8+.LoadProfileElements)
804                 "9000",
805                 // Profile installation result (element 2 of sequenceOf86)
806                 "9000");
807 
808         ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
809         mEuiccCard.loadBoundProfilePackage(
810                 Asn1Node.newBuilder(0xBF36)
811                         .addChild(Asn1Node.newBuilder(0xBF23))
812                         .addChild(Asn1Node.newBuilder(0xA0)
813                                 .addChildAsBytes(0x87, new byte[] {1, 2, 3}))
814                         .addChild(Asn1Node.newBuilder(0xA1)
815                                 .addChildAsBytes(0x88, new byte[] {4, 5, 6}))
816                         .addChild(Asn1Node.newBuilder(0xA2))
817                         .addChild(Asn1Node.newBuilder(0xA3)
818                                 .addChildAsBytes(0x86, new byte[] {7, 8, 9})
819                                 .addChildAsBytes(0x86, new byte[] {0xA, 0xB, 0xC}))
820                         .build().toBytes(),
821                 resultCaptor, mHandler);
822         processAllMessages();
823 
824         EuiccCardException e = (EuiccCardException) resultCaptor.exception;
825         assertEquals(0x6985, ((ApduException) e.getCause()).getApduStatus());
826         verifyStoreData(channel, "BF361FBF2300"); // ES8+.InitialiseSecureChannel
827         verifyStoreData(channel, "A0058703010203"); // ES8+.ConfigureISDP
828         verifyStoreData(channel, "A105"); // ES8+.StoreMetadata
829         verifyStoreData(channel, "8803040506"); // ES8+.StoreMetadata
830     }
831 
832     @Test
testLoadBoundProfilePackage_NoProfileElements()833     public void testLoadBoundProfilePackage_NoProfileElements() {
834         int channel = mockLogicalChannelResponses_sgp22v210();
835 
836         ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
837         mEuiccCard.loadBoundProfilePackage(
838                 Asn1Node.newBuilder(0xBF36)
839                         .addChild(Asn1Node.newBuilder(0xBF23))
840                         .addChild(Asn1Node.newBuilder(0xA0)
841                                 .addChildAsBytes(0x87, new byte[] {1, 2, 3}))
842                         .addChild(Asn1Node.newBuilder(0xA1)
843                                 .addChildAsBytes(0x88, new byte[] {4, 5, 6}))
844                         .addChild(Asn1Node.newBuilder(0xA2))
845                         // No children
846                         .addChild(Asn1Node.newBuilder(0xA3))
847                         .build().toBytes(),
848                 resultCaptor, mHandler);
849         processAllMessages();
850 
851         EuiccCardException e = (EuiccCardException) resultCaptor.exception;
852         assertEquals("No profile elements in BPP", e.getCause().getMessage());
853         verify(mMockCi, never())
854                 .iccTransmitApduLogicalChannel(
855                         eq(channel), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), any(),
856                         any());
857     }
858 
859     @Test
testLoadBoundProfilePackage_UnrecognizedTag()860     public void testLoadBoundProfilePackage_UnrecognizedTag() {
861         int channel = mockLogicalChannelResponses_sgp22v210();
862 
863         ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
864         mEuiccCard.loadBoundProfilePackage(
865                 Asn1Node.newBuilder(0xBF36)
866                         .addChild(Asn1Node.newBuilder(0xBF23))
867                         .addChild(Asn1Node.newBuilder(0xA0)
868                                 .addChildAsBytes(0x87, new byte[] {1, 2, 3}))
869                         .addChild(Asn1Node.newBuilder(0xA1)
870                                 .addChildAsBytes(0x88, new byte[] {4, 5, 6}))
871                         .addChild(Asn1Node.newBuilder(0xA2))
872                         .addChild(Asn1Node.newBuilder(0xA3)
873                                 .addChildAsBytes(0x86, new byte[] {7, 8, 9})
874                                 .addChildAsBytes(0x86, new byte[] {0xA, 0xB, 0xC}))
875                         // Unrecognized tag
876                         .addChild(Asn1Node.newBuilder(0xA4))
877                         .build().toBytes(),
878                 resultCaptor, mHandler);
879         processAllMessages();
880 
881         EuiccCardException e = (EuiccCardException) resultCaptor.exception;
882         assertEquals(
883                 "Actual BPP length (33) does not match segmented length (31), this must be due to a"
884                         + " malformed BPP",
885                 e.getCause().getMessage());
886         verify(mMockCi, never())
887                 .iccTransmitApduLogicalChannel(
888                         eq(channel), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), any(),
889                         any());
890     }
891 
892     @Test
testCancelSession()893     public void testCancelSession() {
894         int channel = mockLogicalChannelResponses("BF41009000");
895 
896         ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
897         mEuiccCard.cancelSession(IccUtils.hexStringToBytes("A1B2C3"),
898                 EuiccCardManager.CANCEL_REASON_POSTPONED, resultCaptor, mHandler);
899         processAllMessages();
900 
901         assertEquals("BF4100", IccUtils.bytesToHexString(resultCaptor.result));
902         verifyStoreData(channel, "BF41088003A1B2C3810101");
903     }
904 
905     @Test
testCancelSession_Error()906     public void testCancelSession_Error() {
907         int channel = mockLogicalChannelResponses("BF41038101039000");
908 
909         ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
910         mEuiccCard.cancelSession(IccUtils.hexStringToBytes("A1B2C3"),
911                 EuiccCardManager.CANCEL_REASON_POSTPONED, resultCaptor, mHandler);
912         processAllMessages();
913 
914         assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
915         verifyStoreData(channel, "BF41088003A1B2C3810101");
916     }
917 
918     @Test
testListNotifications()919     public void testListNotifications() {
920         int channel = mockLogicalChannelResponses("BF282BA029"
921                 + "BF2F118001010C08736D64702E636F6D81020410" // Notification #1
922                 + "BF2F128001020C09736D6470322E636F6D81020420" // Notification #2
923                 + "9000");
924 
925         ResultCaptor<EuiccNotification[]> resultCaptor = new ResultCaptor<>();
926         mEuiccCard.listNotifications(
927                 EuiccNotification.EVENT_DELETE | EuiccNotification.EVENT_DISABLE,
928                 resultCaptor, mHandler);
929         processAllMessages();
930 
931         assertArrayEquals(
932                 new EuiccNotification[] {
933                         new EuiccNotification(1, "smdp.com", EuiccNotification.EVENT_DELETE, null),
934                         new EuiccNotification(2, "smdp2.com", EuiccNotification.EVENT_DISABLE, null)
935                 },
936                 resultCaptor.result);
937         verifyStoreData(channel, "BF280481020430");
938     }
939 
940     @Test
testListNotifications_Error()941     public void testListNotifications_Error() {
942         int channel = mockLogicalChannelResponses("BF28038101039000");
943 
944         ResultCaptor<EuiccNotification[]> resultCaptor = new ResultCaptor<>();
945         mEuiccCard.listNotifications(
946                 EuiccNotification.EVENT_DELETE | EuiccNotification.EVENT_DISABLE,
947                 resultCaptor, mHandler);
948         processAllMessages();
949 
950         assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
951         verifyStoreData(channel, "BF280481020430");
952     }
953 
954     @Test
testRetrieveNotificationList()955     public void testRetrieveNotificationList() {
956         int channel = mockLogicalChannelResponses("BF2B2FA02D"
957                 // Notification #1
958                 + "3014BF2F118001010C08736D64702E636F6D81020410"
959                 // Notification #2
960                 + "3015BF2F128001020C09736D6470322E636F6D81020420"
961                 + "9000");
962 
963         ResultCaptor<EuiccNotification[]> resultCaptor = new ResultCaptor<>();
964         mEuiccCard.retrieveNotificationList(
965                 EuiccNotification.EVENT_DELETE | EuiccNotification.EVENT_DISABLE,
966                 resultCaptor, mHandler);
967         processAllMessages();
968 
969         assertArrayEquals(
970                 new EuiccNotification[] {
971                         new EuiccNotification(1, "smdp.com", EuiccNotification.EVENT_DELETE,
972                                 IccUtils.hexStringToBytes(
973                                         "3014BF2F118001010C08736D64702E636F6D81020410")),
974                         new EuiccNotification(2, "smdp2.com", EuiccNotification.EVENT_DISABLE,
975                                 IccUtils.hexStringToBytes(
976                                         "3015BF2F128001020C09736D6470322E636F6D81020420"))
977                 },
978                 resultCaptor.result);
979         verifyStoreData(channel, "BF2B06A00481020430");
980     }
981 
982     @Test
testRetrieveNotificationList_Empty()983     public void testRetrieveNotificationList_Empty() {
984         int channel = mockLogicalChannelResponses("BF2B038101019000");
985 
986         ResultCaptor<EuiccNotification[]> resultCaptor = new ResultCaptor<>();
987         mEuiccCard.retrieveNotificationList(
988                 EuiccNotification.EVENT_DELETE | EuiccNotification.EVENT_DISABLE,
989                 resultCaptor, mHandler);
990         processAllMessages();
991 
992         assertArrayEquals(new EuiccNotification[0], resultCaptor.result);
993         verifyStoreData(channel, "BF2B06A00481020430");
994     }
995 
996     @Test
testRetrieveNotificationList_Error()997     public void testRetrieveNotificationList_Error() {
998         int channel = mockLogicalChannelResponses("BF2B038101039000");
999 
1000         ResultCaptor<EuiccNotification[]> resultCaptor = new ResultCaptor<>();
1001         mEuiccCard.retrieveNotificationList(
1002                 EuiccNotification.EVENT_DELETE | EuiccNotification.EVENT_DISABLE,
1003                 resultCaptor, mHandler);
1004         processAllMessages();
1005 
1006         assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
1007         verifyStoreData(channel, "BF2B06A00481020430");
1008     }
1009 
1010     @Test
testRetrieveNotification()1011     public void testRetrieveNotification() {
1012         int channel = mockLogicalChannelResponses("BF2B18A016"
1013                 + "3014BF2F118001010C08736D64702E636F6D81020410" // Notification
1014                 + "9000");
1015 
1016         ResultCaptor<EuiccNotification> resultCaptor = new ResultCaptor<>();
1017         mEuiccCard.retrieveNotification(5, resultCaptor, mHandler);
1018         processAllMessages();
1019 
1020         assertEquals(
1021                 new EuiccNotification(1, "smdp.com", EuiccNotification.EVENT_DELETE,
1022                         IccUtils.hexStringToBytes("3014BF2F118001010C08736D64702E636F6D81020410")),
1023                 resultCaptor.result);
1024         verifyStoreData(channel, "BF2B05A003800105");
1025     }
1026 
1027     @Test
testRetrieveNotification_Error()1028     public void testRetrieveNotification_Error() {
1029         int channel = mockLogicalChannelResponses("BF2B038101019000");
1030 
1031         ResultCaptor<EuiccNotification> resultCaptor = new ResultCaptor<>();
1032         mEuiccCard.retrieveNotification(5, resultCaptor, mHandler);
1033         processAllMessages();
1034 
1035         assertEquals(1, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
1036         verifyStoreData(channel, "BF2B05A003800105");
1037     }
1038 
1039     @Test
testRemoveNotificationFromList()1040     public void testRemoveNotificationFromList() {
1041         int channel = mockLogicalChannelResponses("BF30038001009000");
1042 
1043         ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
1044         mEuiccCard.removeNotificationFromList(5, resultCaptor, mHandler);
1045         processAllMessages();
1046 
1047         assertUnexpectedException(resultCaptor.exception);
1048         verifyStoreData(channel, "BF3003800105");
1049     }
1050 
1051     @Test
testAddDeviceCapability()1052     public void testAddDeviceCapability() throws InvalidAsn1DataException, TagNotFoundException {
1053         Asn1Node.Builder devCapsBuilder = Asn1Node.newBuilder(Tags.TAG_CTX_COMP_1);
1054 
1055         String devCapItem = "gsm,11";
1056         mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem);
1057         Asn1Node node = devCapsBuilder.build();
1058 
1059         assertTrue(node.hasChild(Tags.TAG_CTX_0));
1060         Asn1Node child = node.getChild(Tags.TAG_CTX_0);
1061         assertTrue(Arrays.equals(new byte[] {11, 0 , 0}, child.asBytes()));
1062 
1063         devCapItem = "utran,11";
1064         mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem);
1065         node = devCapsBuilder.build();
1066 
1067         assertTrue(node.hasChild(Tags.TAG_CTX_1));
1068         child = node.getChild(Tags.TAG_CTX_1);
1069         assertTrue(Arrays.equals(new byte[] {11, 0 , 0}, child.asBytes()));
1070 
1071         devCapItem = "cdma1x,1";
1072         mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem);
1073         node = devCapsBuilder.build();
1074 
1075         assertTrue(node.hasChild(Tags.TAG_CTX_2));
1076         child = node.getChild(Tags.TAG_CTX_2);
1077         assertTrue(Arrays.equals(new byte[] {1, 0 , 0}, child.asBytes()));
1078 
1079         devCapItem = "hrpd,1";
1080         mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem);
1081         node = devCapsBuilder.build();
1082 
1083         assertTrue(node.hasChild(Tags.TAG_CTX_3));
1084         child = node.getChild(Tags.TAG_CTX_3);
1085         assertTrue(Arrays.equals(new byte[] {1, 0 , 0}, child.asBytes()));
1086 
1087         devCapItem = "ehrpd,12";
1088         mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem);
1089         node = devCapsBuilder.build();
1090 
1091         assertTrue(node.hasChild(Tags.TAG_CTX_4));
1092         child = node.getChild(Tags.TAG_CTX_4);
1093         assertTrue(Arrays.equals(new byte[] {12, 0 , 0}, child.asBytes()));
1094 
1095         devCapItem = "eutran,11";
1096         mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem);
1097         node = devCapsBuilder.build();
1098 
1099         assertTrue(node.hasChild(Tags.TAG_CTX_5));
1100         child = node.getChild(Tags.TAG_CTX_5);
1101         assertTrue(Arrays.equals(new byte[] {11, 0 , 0}, child.asBytes()));
1102 
1103         devCapItem = "nfc,0";
1104         mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem);
1105         node = devCapsBuilder.build();
1106 
1107         assertTrue(node.hasChild(Tags.TAG_CTX_6));
1108         child = node.getChild(Tags.TAG_CTX_6);
1109         assertTrue(Arrays.equals(new byte[] {0, 0 , 0}, child.asBytes()));
1110 
1111         devCapItem = "crl,0";
1112         mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem);
1113         node = devCapsBuilder.build();
1114 
1115         assertTrue(node.hasChild(Tags.TAG_CTX_7));
1116         child = node.getChild(Tags.TAG_CTX_7);
1117         assertTrue(Arrays.equals(new byte[] {0, 0 , 0}, child.asBytes()));
1118 
1119         // Array length should not be 3.
1120         Asn1Node.Builder devCapsBuilder2 = Asn1Node.newBuilder(Tags.TAG_CTX_COMP_1);
1121         devCapItem = "gsm,1,1";
1122         mEuiccCard.addDeviceCapability(devCapsBuilder2, devCapItem);
1123         node = devCapsBuilder2.build();
1124 
1125         assertFalse(node.hasChild(Tags.TAG_CTX_0));
1126     }
1127 
1128     @Test
testGetDeviceId()1129     public void testGetDeviceId() {
1130         // Unclear v2.0 definition
1131         assertArrayEquals(
1132                 new byte[] {0x21, 0x43, 0x65, (byte) 0x87, 0x09, 0x21, 0x43, 0x05},
1133                 EuiccCard.getDeviceId("123456789012345", new EuiccSpecVersion(2, 0, 0)));
1134         // Clarified v2.1+ definition
1135         assertArrayEquals(
1136                 new byte[] {0x21, 0x43, 0x65, (byte) 0x87, 0x09, 0x21, 0x43, 0x5F},
1137                 EuiccCard.getDeviceId("123456789012345", new EuiccSpecVersion(2, 1, 0)));
1138         // Same definition on v2.2
1139         assertArrayEquals(
1140                 new byte[] {0x21, 0x43, 0x65, (byte) 0x87, 0x09, 0x21, 0x43, 0x5F},
1141                 EuiccCard.getDeviceId("123456789012345", new EuiccSpecVersion(2, 2, 0)));
1142     }
1143 
verifyStoreData(int channel, String command)1144     private void verifyStoreData(int channel, String command) {
1145         verify(mMockCi, times(1))
1146                 .iccTransmitApduLogicalChannel(eq(channel), eq(0x80 | channel), eq(0xE2), eq(0x91),
1147                         eq(0), eq(command.length() / 2), eq(command), any());
1148     }
1149 
mockLogicalChannelResponses(Object... responses)1150     private int mockLogicalChannelResponses(Object... responses) {
1151         int channel = LogicalChannelMocker.mockOpenLogicalChannelResponse(mMockCi,
1152                 "E00582030200009000");
1153         LogicalChannelMocker.mockSendToLogicalChannel(mMockCi, channel, responses);
1154         LogicalChannelMocker.mockCloseLogicalChannel(mMockCi, channel);
1155         return channel;
1156     }
1157 
mockLogicalChannelResponses_sgp22v210(Object... responses)1158     private int mockLogicalChannelResponses_sgp22v210(Object... responses) {
1159         int channel = LogicalChannelMocker.mockOpenLogicalChannelResponse(mMockCi,
1160                 "E00582030201009000");
1161         LogicalChannelMocker.mockSendToLogicalChannel(mMockCi, channel, responses);
1162         LogicalChannelMocker.mockCloseLogicalChannel(mMockCi, channel);
1163         return channel;
1164     }
1165 }
1166