1 /*
2  * Copyright (C) 2017 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 package com.android.internal.telephony.euicc;
17 
18 import static android.telephony.euicc.EuiccManager.EUICC_OTA_STATUS_UNAVAILABLE;
19 
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertFalse;
22 import static org.junit.Assert.assertNotNull;
23 import static org.junit.Assert.assertNull;
24 import static org.junit.Assert.assertTrue;
25 import static org.mockito.ArgumentMatchers.any;
26 import static org.mockito.ArgumentMatchers.anyBoolean;
27 import static org.mockito.ArgumentMatchers.anyInt;
28 import static org.mockito.ArgumentMatchers.anyString;
29 import static org.mockito.ArgumentMatchers.eq;
30 import static org.mockito.Mockito.doAnswer;
31 import static org.mockito.Mockito.doNothing;
32 import static org.mockito.Mockito.doReturn;
33 import static org.mockito.Mockito.doThrow;
34 import static org.mockito.Mockito.never;
35 import static org.mockito.Mockito.verify;
36 import static org.mockito.Mockito.when;
37 
38 import android.Manifest;
39 import android.annotation.Nullable;
40 import android.app.PendingIntent;
41 import android.content.Context;
42 import android.content.Intent;
43 import android.content.pm.PackageInfo;
44 import android.content.pm.PackageManager;
45 import android.content.pm.Signature;
46 import android.os.Parcelable;
47 import android.os.RemoteException;
48 import android.provider.Settings;
49 import android.service.euicc.EuiccService;
50 import android.service.euicc.GetDefaultDownloadableSubscriptionListResult;
51 import android.service.euicc.GetDownloadableSubscriptionMetadataResult;
52 import android.support.test.runner.AndroidJUnit4;
53 import android.telephony.SubscriptionInfo;
54 import android.telephony.SubscriptionManager;
55 import android.telephony.UiccAccessRule;
56 import android.telephony.euicc.DownloadableSubscription;
57 import android.telephony.euicc.EuiccInfo;
58 import android.telephony.euicc.EuiccManager;
59 
60 import com.android.internal.telephony.TelephonyTest;
61 import com.android.internal.telephony.euicc.EuiccConnector.GetOtaStatusCommandCallback;
62 import com.android.internal.telephony.euicc.EuiccConnector.OtaStatusChangedCallback;
63 
64 import org.junit.After;
65 import org.junit.Before;
66 import org.junit.Test;
67 import org.junit.runner.RunWith;
68 import org.mockito.Mock;
69 import org.mockito.Mockito;
70 import org.mockito.invocation.InvocationOnMock;
71 import org.mockito.stubbing.Answer;
72 import org.mockito.stubbing.Stubber;
73 
74 import java.security.MessageDigest;
75 import java.security.NoSuchAlgorithmException;
76 import java.util.Arrays;
77 import java.util.Collections;
78 
79 @RunWith(AndroidJUnit4.class)
80 public class EuiccControllerTest extends TelephonyTest {
81     private static final DownloadableSubscription SUBSCRIPTION =
82             DownloadableSubscription.forActivationCode("abcde");
83 
84     private static final String PACKAGE_NAME = "test.package";
85     private static final String CARRIER_NAME = "test name";
86     private static final byte[] SIGNATURE_BYTES = new byte[] {1, 2, 3, 4, 5};
87 
88     private static final UiccAccessRule ACCESS_RULE;
89     static {
90         try {
91             ACCESS_RULE = new UiccAccessRule(
92                     MessageDigest.getInstance("SHA-256").digest(SIGNATURE_BYTES),
93                     PACKAGE_NAME,
94                     0);
95         } catch (NoSuchAlgorithmException e) {
96             throw new RuntimeException("SHA-256 must exist");
97         }
98     }
99 
100     private static final DownloadableSubscription SUBSCRIPTION_WITH_METADATA =
101             DownloadableSubscription.forActivationCode("abcde");
102     static {
103         SUBSCRIPTION_WITH_METADATA.setCarrierName("test name");
104         SUBSCRIPTION_WITH_METADATA.setAccessRules(
Arrays.asList(new UiccAccessRule[] { ACCESS_RULE })105                 Arrays.asList(new UiccAccessRule[] { ACCESS_RULE }));
106     }
107 
108     private static final String OS_VERSION = "1.0";
109     private static final EuiccInfo EUICC_INFO = new EuiccInfo(OS_VERSION);
110 
111     private static final int SUBSCRIPTION_ID = 12345;
112     private static final String ICC_ID = "54321";
113 
114     @Mock private EuiccConnector mMockConnector;
115     private TestEuiccController mController;
116     private int mSavedEuiccProvisionedValue;
117 
118     private static class TestEuiccController extends EuiccController {
119         // Captured arguments to addResolutionIntent
120         private String mResolutionAction;
121         private EuiccOperation mOp;
122 
123         // Captured arguments to sendResult.
124         private PendingIntent mCallbackIntent;
125         private int mResultCode;
126         private Intent mExtrasIntent;
127 
128         // Whether refreshSubscriptionsAndSendResult was called.
129         private boolean mCalledRefreshSubscriptionsAndSendResult;
130 
131         // Number of OTA status changed.
132         private int mNumOtaStatusChanged;
133 
TestEuiccController(Context context, EuiccConnector connector)134         TestEuiccController(Context context, EuiccConnector connector) {
135             super(context, connector);
136             mNumOtaStatusChanged = 0;
137         }
138 
139         @Override
addResolutionIntent( Intent extrasIntent, String resolutionAction, String callingPackage, boolean retried, EuiccOperation op)140         public void addResolutionIntent(
141                 Intent extrasIntent, String resolutionAction, String callingPackage,
142                 boolean retried, EuiccOperation op) {
143             mResolutionAction = resolutionAction;
144             mOp = op;
145         }
146 
147         @Override
sendResult(PendingIntent callbackIntent, int resultCode, Intent extrasIntent)148         public void sendResult(PendingIntent callbackIntent, int resultCode, Intent extrasIntent) {
149             assertNull("sendResult called twice unexpectedly", mCallbackIntent);
150             mCallbackIntent = callbackIntent;
151             mResultCode = resultCode;
152             mExtrasIntent = extrasIntent;
153         }
154 
155         @Override
refreshSubscriptionsAndSendResult( PendingIntent callbackIntent, int resultCode, Intent extrasIntent)156         public void refreshSubscriptionsAndSendResult(
157                 PendingIntent callbackIntent, int resultCode, Intent extrasIntent) {
158             mCalledRefreshSubscriptionsAndSendResult = true;
159             sendResult(callbackIntent, resultCode, extrasIntent);
160         }
161 
162         @Override
sendOtaStatusChangedBroadcast()163         public void sendOtaStatusChangedBroadcast() {
164             ++mNumOtaStatusChanged;
165         }
166     }
167 
168     @Before
setUp()169     public void setUp() throws Exception {
170         super.setUp("EuiccControllerTest");
171         mController = new TestEuiccController(mContext, mMockConnector);
172 
173         PackageInfo pi = new PackageInfo();
174         pi.packageName = PACKAGE_NAME;
175         pi.signatures = new Signature[] { new Signature(SIGNATURE_BYTES) };
176         when(mPackageManager.getPackageInfo(eq(PACKAGE_NAME), anyInt())).thenReturn(pi);
177 
178         mSavedEuiccProvisionedValue = Settings.Global.getInt(mContext.getContentResolver(),
179                 Settings.Global.EUICC_PROVISIONED, 0);
180         Settings.Global.putInt(mContext.getContentResolver(),
181                 Settings.Global.EUICC_PROVISIONED, 0);
182     }
183 
184     @After
tearDown()185     public void tearDown() throws Exception {
186         super.tearDown();
187         Settings.Global.putInt(mContext.getContentResolver(),
188                 Settings.Global.EUICC_PROVISIONED, mSavedEuiccProvisionedValue);
189     }
190 
191     @Test(expected = SecurityException.class)
testGetEid_noPrivileges()192     public void testGetEid_noPrivileges() {
193         setGetEidPermissions(false /* hasPhoneStatePrivileged */, false /* hasCarrierPrivileges */);
194         callGetEid(true /* success */, "ABCDE" /* eid */);
195     }
196 
197     @Test
testGetEid_withPhoneStatePrivileged()198     public void testGetEid_withPhoneStatePrivileged() {
199         setGetEidPermissions(true /* hasPhoneStatePrivileged */, false /* hasCarrierPrivileges */);
200         assertEquals("ABCDE", callGetEid(true /* success */, "ABCDE" /* eid */));
201     }
202 
203     @Test
testGetEid_withCarrierPrivileges()204     public void testGetEid_withCarrierPrivileges() {
205         setGetEidPermissions(false /* hasPhoneStatePrivileged */, true /* hasCarrierPrivileges */);
206         assertEquals("ABCDE", callGetEid(true /* success */, "ABCDE" /* eid */));
207     }
208 
209     @Test
testGetEid_failure()210     public void testGetEid_failure() {
211         setGetEidPermissions(true /* hasPhoneStatePrivileged */, false /* hasCarrierPrivileges */);
212         assertNull(callGetEid(false /* success */, null /* eid */));
213     }
214 
215     @Test
testGetEid_nullReturnValue()216     public void testGetEid_nullReturnValue() {
217         setGetEidPermissions(true /* hasPhoneStatePrivileged */, false /* hasCarrierPrivileges */);
218         assertNull(callGetEid(true /* success */, null /* eid */));
219     }
220 
221     @Test(expected = SecurityException.class)
testGetOtaStatus_noPrivileges()222     public void testGetOtaStatus_noPrivileges() {
223         setHasWriteEmbeddedPermission(false /* hasPermission */);
224         callGetOtaStatus(true /* success */, 1 /* status */);
225     }
226 
227     @Test
testGetOtaStatus_withWriteEmbeddedPermission()228     public void testGetOtaStatus_withWriteEmbeddedPermission() {
229         setHasWriteEmbeddedPermission(true /* hasPermission */);
230         assertEquals(1, callGetOtaStatus(true /* success */, 1 /* status */));
231     }
232 
233     @Test
testGetOtaStatus_failure()234     public void testGetOtaStatus_failure() {
235         setHasWriteEmbeddedPermission(true /* hasPermission */);
236         assertEquals(
237                 EUICC_OTA_STATUS_UNAVAILABLE,
238                 callGetOtaStatus(false /* success */, 1 /* status */));
239     }
240 
241     @Test
testStartOtaUpdatingIfNecessary_serviceNotAvailable()242     public void testStartOtaUpdatingIfNecessary_serviceNotAvailable() {
243         setHasWriteEmbeddedPermission(true /* hasPermission */);
244         callStartOtaUpdatingIfNecessary(
245                 false /* serviceAvailable */, EuiccManager.EUICC_OTA_IN_PROGRESS);
246         assertEquals(mController.mNumOtaStatusChanged, 0);
247     }
248 
249     @Test
testStartOtaUpdatingIfNecessary_otaStatusChanged()250     public void testStartOtaUpdatingIfNecessary_otaStatusChanged() {
251         setHasWriteEmbeddedPermission(true /* hasPermission */);
252         callStartOtaUpdatingIfNecessary(
253                 true /* serviceAvailable */, EuiccManager.EUICC_OTA_IN_PROGRESS);
254         callStartOtaUpdatingIfNecessary(
255                 true /* serviceAvailable */, EuiccManager.EUICC_OTA_FAILED);
256         callStartOtaUpdatingIfNecessary(
257                 true /* serviceAvailable */, EuiccManager.EUICC_OTA_SUCCEEDED);
258         callStartOtaUpdatingIfNecessary(
259                 true /* serviceAvailable */, EuiccManager.EUICC_OTA_NOT_NEEDED);
260         callStartOtaUpdatingIfNecessary(
261                 true /* serviceAvailable */, EuiccManager.EUICC_OTA_STATUS_UNAVAILABLE);
262 
263         assertEquals(mController.mNumOtaStatusChanged, 5);
264     }
265 
266 
267     @Test
testGetEuiccInfo_success()268     public void testGetEuiccInfo_success() {
269         assertEquals(OS_VERSION, callGetEuiccInfo(true /* success */, EUICC_INFO).getOsVersion());
270     }
271 
272     @Test
testGetEuiccInfo_failure()273     public void testGetEuiccInfo_failure() {
274         assertNull(callGetEuiccInfo(false /* success */, null /* euiccInfo */));
275     }
276 
277     @Test
testGetEuiccInfo_nullReturnValue()278     public void testGetEuiccInfo_nullReturnValue() {
279         assertNull(callGetEuiccInfo(true /* success */, null /* euiccInfo */));
280     }
281 
282     @Test
testGetDownloadableSubscriptionMetadata_serviceUnavailable()283     public void testGetDownloadableSubscriptionMetadata_serviceUnavailable() throws Exception {
284         setHasWriteEmbeddedPermission(true);
285         callGetDownloadableSubscriptionMetadata(
286                 SUBSCRIPTION, false /* complete */, null /* result */);
287         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
288                 0 /* detailedCode */);
289         verify(mMockConnector).getDownloadableSubscriptionMetadata(any(), anyBoolean(), any());
290     }
291 
292     @Test
testGetDownloadableSubscriptionMetadata_error()293     public void testGetDownloadableSubscriptionMetadata_error() throws Exception {
294         setHasWriteEmbeddedPermission(true);
295         GetDownloadableSubscriptionMetadataResult result =
296                 new GetDownloadableSubscriptionMetadataResult(42, null /* subscription */);
297         callGetDownloadableSubscriptionMetadata(SUBSCRIPTION, true /* complete */, result);
298         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
299                 42 /* detailedCode */);
300     }
301 
302     @Test
testGetDownloadableSubscriptionMetadata_mustDeactivateSim()303     public void testGetDownloadableSubscriptionMetadata_mustDeactivateSim()
304             throws Exception {
305         setHasWriteEmbeddedPermission(true);
306         GetDownloadableSubscriptionMetadataResult result =
307                 new GetDownloadableSubscriptionMetadataResult(
308                         EuiccService.RESULT_MUST_DEACTIVATE_SIM, null /* subscription */);
309         callGetDownloadableSubscriptionMetadata(SUBSCRIPTION, true /* complete */, result);
310         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR,
311                 0 /* detailedCode */);
312         verifyResolutionIntent(EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM,
313                 EuiccOperation.ACTION_GET_METADATA_DEACTIVATE_SIM);
314     }
315 
316     @Test
testGetDownloadableSubscriptionMetadata_success()317     public void testGetDownloadableSubscriptionMetadata_success() throws Exception {
318         setHasWriteEmbeddedPermission(true);
319         GetDownloadableSubscriptionMetadataResult result =
320                 new GetDownloadableSubscriptionMetadataResult(
321                         EuiccService.RESULT_OK, SUBSCRIPTION_WITH_METADATA);
322         callGetDownloadableSubscriptionMetadata(SUBSCRIPTION, true /* complete */, result);
323         Intent intent = verifyIntentSent(
324                 EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK, 0 /* detailedCode */);
325         DownloadableSubscription receivedSubscription = intent.getParcelableExtra(
326                 EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION);
327         assertNotNull(receivedSubscription);
328         assertEquals(CARRIER_NAME, receivedSubscription.getCarrierName());
329     }
330 
331     @Test
testGetDefaultDownloadableSubscriptionList_serviceUnavailable()332     public void testGetDefaultDownloadableSubscriptionList_serviceUnavailable() throws Exception {
333         setHasWriteEmbeddedPermission(true);
334         callGetDefaultDownloadableSubscriptionList(false /* complete */, null /* result */);
335         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
336                 0 /* detailedCode */);
337     }
338 
339     @Test
testGetDefaultDownloadableSubscriptionList_error()340     public void testGetDefaultDownloadableSubscriptionList_error() throws Exception {
341         setHasWriteEmbeddedPermission(true);
342         GetDefaultDownloadableSubscriptionListResult result =
343                 new GetDefaultDownloadableSubscriptionListResult(42, null /* subscriptions */);
344         callGetDefaultDownloadableSubscriptionList(true /* complete */, result);
345         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
346                 42 /* detailedCode */);
347         verify(mMockConnector).getDefaultDownloadableSubscriptionList(anyBoolean(), any());
348     }
349 
350     @Test
testGetDefaultDownloadableSubscriptionList_mustDeactivateSim()351     public void testGetDefaultDownloadableSubscriptionList_mustDeactivateSim()
352             throws Exception {
353         setHasWriteEmbeddedPermission(true);
354         GetDefaultDownloadableSubscriptionListResult result =
355                 new GetDefaultDownloadableSubscriptionListResult(
356                         EuiccService.RESULT_MUST_DEACTIVATE_SIM, null /* subscriptions */);
357         callGetDefaultDownloadableSubscriptionList(true /* complete */, result);
358         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR,
359                 0 /* detailedCode */);
360         verifyResolutionIntent(EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM,
361                 EuiccOperation.ACTION_GET_DEFAULT_LIST_DEACTIVATE_SIM);
362     }
363 
364     @Test
testGetDefaultDownloadableSubscriptionList_success()365     public void testGetDefaultDownloadableSubscriptionList_success() throws Exception {
366         setHasWriteEmbeddedPermission(true);
367         GetDefaultDownloadableSubscriptionListResult result =
368                 new GetDefaultDownloadableSubscriptionListResult(
369                         EuiccService.RESULT_OK,
370                         new DownloadableSubscription[] { SUBSCRIPTION_WITH_METADATA });
371         callGetDefaultDownloadableSubscriptionList(true /* complete */, result);
372         Intent intent = verifyIntentSent(
373                 EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK, 0 /* detailedCode */);
374         Parcelable[] receivedSubscriptions = intent.getParcelableArrayExtra(
375                 EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS);
376         assertNotNull(receivedSubscriptions);
377         assertEquals(1, receivedSubscriptions.length);
378         assertEquals(CARRIER_NAME,
379                 ((DownloadableSubscription) receivedSubscriptions[0]).getCarrierName());
380     }
381 
382     @Test
testDownloadSubscription_serviceUnavailable()383     public void testDownloadSubscription_serviceUnavailable() throws Exception {
384         setHasWriteEmbeddedPermission(true);
385         callDownloadSubscription(
386                 SUBSCRIPTION, true /* switchAfterDownload */, false /* complete */,
387                 0 /* result */, "whatever" /* callingPackage */);
388         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
389                 0 /* detailedCode */);
390         verify(mMockConnector).downloadSubscription(any(), anyBoolean(), anyBoolean(), any());
391     }
392 
393     @Test
testDownloadSubscription_error()394     public void testDownloadSubscription_error() throws Exception {
395         setHasWriteEmbeddedPermission(true);
396         callDownloadSubscription(SUBSCRIPTION, false /* switchAfterDownload */, true /* complete */,
397                 42, "whatever" /* callingPackage */);
398         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
399                 42 /* detailedCode */);
400     }
401 
402     @Test
testDownloadSubscription_mustDeactivateSim()403     public void testDownloadSubscription_mustDeactivateSim() throws Exception {
404         setHasWriteEmbeddedPermission(true);
405         callDownloadSubscription(SUBSCRIPTION, false /* switchAfterDownload */, true /* complete */,
406                 EuiccService.RESULT_MUST_DEACTIVATE_SIM, "whatever" /* callingPackage */);
407         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR,
408                 0 /* detailedCode */);
409         verifyResolutionIntent(EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM,
410                 EuiccOperation.ACTION_DOWNLOAD_DEACTIVATE_SIM);
411     }
412 
413     @Test
testDownloadSubscription_needConfirmationCode()414     public void testDownloadSubscription_needConfirmationCode() throws Exception {
415         setHasWriteEmbeddedPermission(true);
416         callDownloadSubscription(SUBSCRIPTION, false /* switchAfterDownload */, true /* complete */,
417                 EuiccService.RESULT_NEED_CONFIRMATION_CODE, "whatever" /* callingPackage */);
418         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR,
419                 0 /* detailedCode */);
420         verifyResolutionIntent(EuiccService.ACTION_RESOLVE_CONFIRMATION_CODE,
421                 EuiccOperation.ACTION_DOWNLOAD_CONFIRMATION_CODE);
422     }
423 
424     @Test
testDownloadSubscription_success()425     public void testDownloadSubscription_success() throws Exception {
426         setHasWriteEmbeddedPermission(true);
427         callDownloadSubscription(SUBSCRIPTION, true /* switchAfterDownload */, true /* complete */,
428                 EuiccService.RESULT_OK, "whatever" /* callingPackage */);
429         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK, 0 /* detailedCode */);
430         // switchAfterDownload = true so no refresh should occur.
431         assertFalse(mController.mCalledRefreshSubscriptionsAndSendResult);
432     }
433 
434     @Test
testDownloadSubscription_noSwitch_success()435     public void testDownloadSubscription_noSwitch_success() throws Exception {
436         setHasWriteEmbeddedPermission(true);
437         callDownloadSubscription(SUBSCRIPTION, false /* switchAfterDownload */, true /* complete */,
438                 EuiccService.RESULT_OK, "whatever" /* callingPackage */);
439         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK, 0 /* detailedCode */);
440         assertTrue(mController.mCalledRefreshSubscriptionsAndSendResult);
441     }
442 
443     @Test
testDownloadSubscription_noPrivileges_getMetadata_serviceUnavailable()444     public void testDownloadSubscription_noPrivileges_getMetadata_serviceUnavailable()
445             throws Exception {
446         setHasWriteEmbeddedPermission(false);
447         prepareGetDownloadableSubscriptionMetadataCall(false /* complete */, null /* result */);
448         callDownloadSubscription(SUBSCRIPTION, true /* switchAfterDownload */, true /* complete */,
449                 12345, PACKAGE_NAME /* callingPackage */);
450         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
451                 0 /* detailedCode */);
452         verify(mMockConnector, never()).downloadSubscription(
453                 any(), anyBoolean(), anyBoolean(), any());
454     }
455 
456     @Test
testDownloadSubscription_noPrivileges_getMetadata_error()457     public void testDownloadSubscription_noPrivileges_getMetadata_error()
458             throws Exception {
459         setHasWriteEmbeddedPermission(false);
460         GetDownloadableSubscriptionMetadataResult result =
461                 new GetDownloadableSubscriptionMetadataResult(42, null /* subscription */);
462         prepareGetDownloadableSubscriptionMetadataCall(true /* complete */, result);
463         callDownloadSubscription(SUBSCRIPTION, true /* switchAfterDownload */, true /* complete */,
464                 12345, PACKAGE_NAME /* callingPackage */);
465         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
466                 42 /* detailedCode */);
467         verify(mMockConnector, never()).downloadSubscription(
468                 any(), anyBoolean(), anyBoolean(), any());
469     }
470 
471     @Test
testDownloadSubscription_noPrivileges_getMetadata_mustDeactivateSim()472     public void testDownloadSubscription_noPrivileges_getMetadata_mustDeactivateSim()
473             throws Exception {
474         setHasWriteEmbeddedPermission(false);
475         GetDownloadableSubscriptionMetadataResult result =
476                 new GetDownloadableSubscriptionMetadataResult(
477                         EuiccService.RESULT_MUST_DEACTIVATE_SIM, null /* subscription */);
478         prepareGetDownloadableSubscriptionMetadataCall(true /* complete */, result);
479         callDownloadSubscription(SUBSCRIPTION, true /* switchAfterDownload */, true /* complete */,
480                 12345, PACKAGE_NAME /* callingPackage */);
481         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR,
482                 0 /* detailedCode */);
483         // In this case we go with the potentially stronger NO_PRIVILEGES consent dialog to avoid
484         // double prompting.
485         verifyResolutionIntent(EuiccService.ACTION_RESOLVE_NO_PRIVILEGES,
486                 EuiccOperation.ACTION_DOWNLOAD_NO_PRIVILEGES);
487     }
488 
489     @Test
testDownloadSubscription_noPrivileges_hasCarrierPrivileges()490     public void testDownloadSubscription_noPrivileges_hasCarrierPrivileges() throws Exception {
491         setHasWriteEmbeddedPermission(false);
492         GetDownloadableSubscriptionMetadataResult result =
493                 new GetDownloadableSubscriptionMetadataResult(
494                         EuiccService.RESULT_OK, SUBSCRIPTION_WITH_METADATA);
495         prepareGetDownloadableSubscriptionMetadataCall(true /* complete */, result);
496         setHasCarrierPrivilegesOnActiveSubscription(true);
497         callDownloadSubscription(SUBSCRIPTION, true /* switchAfterDownload */, true /* complete */,
498                 EuiccService.RESULT_OK, PACKAGE_NAME /* callingPackage */);
499         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK, 0 /* detailedCode */);
500         // switchAfterDownload = true so no refresh should occur.
501         assertFalse(mController.mCalledRefreshSubscriptionsAndSendResult);
502     }
503 
504     @Test
testDownloadSubscription_noPrivileges_hasCarrierPrivileges_needsConsent()505     public void testDownloadSubscription_noPrivileges_hasCarrierPrivileges_needsConsent()
506             throws Exception {
507         setHasWriteEmbeddedPermission(false);
508         GetDownloadableSubscriptionMetadataResult result =
509                 new GetDownloadableSubscriptionMetadataResult(
510                         EuiccService.RESULT_OK, SUBSCRIPTION_WITH_METADATA);
511         prepareGetDownloadableSubscriptionMetadataCall(true /* complete */, result);
512         setHasCarrierPrivilegesOnActiveSubscription(false);
513         callDownloadSubscription(SUBSCRIPTION, true /* switchAfterDownload */, true /* complete */,
514                 12345, PACKAGE_NAME /* callingPackage */);
515         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR,
516                 0 /* detailedCode */);
517         verify(mMockConnector, never()).downloadSubscription(
518                 any(), anyBoolean(), anyBoolean(), any());
519         verifyResolutionIntent(EuiccService.ACTION_RESOLVE_NO_PRIVILEGES,
520                 EuiccOperation.ACTION_DOWNLOAD_NO_PRIVILEGES);
521     }
522 
523     @Test
testDownloadSubscription_noPrivileges_noCarrierPrivileges()524     public void testDownloadSubscription_noPrivileges_noCarrierPrivileges() throws Exception {
525         setHasWriteEmbeddedPermission(false);
526         GetDownloadableSubscriptionMetadataResult result =
527                 new GetDownloadableSubscriptionMetadataResult(
528                         EuiccService.RESULT_OK, SUBSCRIPTION_WITH_METADATA);
529         prepareGetDownloadableSubscriptionMetadataCall(true /* complete */, result);
530         PackageInfo pi = new PackageInfo();
531         pi.packageName = PACKAGE_NAME;
532         pi.signatures = new Signature[] { new Signature(new byte[] { 5, 4, 3, 2, 1 }) };
533         when(mPackageManager.getPackageInfo(eq(PACKAGE_NAME), anyInt())).thenReturn(pi);
534         callDownloadSubscription(SUBSCRIPTION, true /* switchAfterDownload */, true /* complete */,
535                 12345, PACKAGE_NAME /* callingPackage */);
536         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
537                 0 /* detailedCode */);
538         verify(mTelephonyManager, never()).checkCarrierPrivilegesForPackage(PACKAGE_NAME);
539         verify(mMockConnector, never()).downloadSubscription(
540                 any(), anyBoolean(), anyBoolean(), any());
541     }
542 
543     @Test
testDeleteSubscription_noSuchSubscription()544     public void testDeleteSubscription_noSuchSubscription() throws Exception {
545         setHasWriteEmbeddedPermission(true);
546         callDeleteSubscription(
547                 SUBSCRIPTION_ID, ICC_ID, false /* complete */,
548                 0 /* result */, "whatever" /* callingPackage */);
549         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
550                 0 /* detailedCode */);
551         verify(mMockConnector, never()).deleteSubscription(anyString(), any());
552     }
553 
554     @Test
testDeleteSubscription_serviceUnavailable()555     public void testDeleteSubscription_serviceUnavailable() throws Exception {
556         setHasWriteEmbeddedPermission(true);
557         prepareOperationSubscription(false /* hasPrivileges */);
558         callDeleteSubscription(
559                 SUBSCRIPTION_ID, ICC_ID, false /* complete */,
560                 0 /* result */, "whatever" /* callingPackage */);
561         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
562                 0 /* detailedCode */);
563     }
564 
565     @Test
testDeleteSubscription_error()566     public void testDeleteSubscription_error() throws Exception {
567         setHasWriteEmbeddedPermission(true);
568         prepareOperationSubscription(false /* hasPrivileges */);
569         callDeleteSubscription(
570                 SUBSCRIPTION_ID, ICC_ID, true /* complete */,
571                 42 /* result */, "whatever" /* callingPackage */);
572         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
573                 42 /* detailedCode */);
574     }
575 
576     @Test
testDeleteSubscription_success()577     public void testDeleteSubscription_success() throws Exception {
578         setHasWriteEmbeddedPermission(true);
579         prepareOperationSubscription(false /* hasPrivileges */);
580         callDeleteSubscription(
581                 SUBSCRIPTION_ID, ICC_ID, true /* complete */,
582                 EuiccService.RESULT_OK, "whatever" /* callingPackage */);
583         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK, 0 /* detailedCode */);
584         assertTrue(mController.mCalledRefreshSubscriptionsAndSendResult);
585     }
586 
587     @Test
testDeleteSubscription_noPrivileges()588     public void testDeleteSubscription_noPrivileges() throws Exception {
589         setHasWriteEmbeddedPermission(false);
590         prepareOperationSubscription(false /* hasPrivileges */);
591         callDeleteSubscription(
592                 SUBSCRIPTION_ID, ICC_ID, false /* complete */,
593                 0 /* result */, "whatever" /* callingPackage */);
594         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
595                 0 /* detailedCode */);
596         verify(mMockConnector, never()).deleteSubscription(anyString(), any());
597     }
598 
599     @Test
testDeleteSubscription_carrierPrivileges_success()600     public void testDeleteSubscription_carrierPrivileges_success() throws Exception {
601         setHasWriteEmbeddedPermission(false);
602         prepareOperationSubscription(true /* hasPrivileges */);
603         callDeleteSubscription(
604                 SUBSCRIPTION_ID, ICC_ID, true /* complete */, EuiccService.RESULT_OK, PACKAGE_NAME);
605         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK, 0 /* detailedCode */);
606         assertTrue(mController.mCalledRefreshSubscriptionsAndSendResult);
607     }
608 
609     @Test
testSwitchToSubscription_noSuchSubscription()610     public void testSwitchToSubscription_noSuchSubscription() throws Exception {
611         setHasWriteEmbeddedPermission(true);
612         callSwitchToSubscription(
613                 12345, ICC_ID, false /* complete */, 0 /* result */,
614                 "whatever" /* callingPackage */);
615         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
616                 0 /* detailedCode */);
617         verify(mMockConnector, never()).switchToSubscription(anyString(), anyBoolean(), any());
618     }
619 
620     @Test
testSwitchToSubscription_emptySubscription_noPrivileges()621     public void testSwitchToSubscription_emptySubscription_noPrivileges() throws Exception {
622         setHasWriteEmbeddedPermission(false);
623         callSwitchToSubscription(
624                 SubscriptionManager.INVALID_SUBSCRIPTION_ID, null /* iccid */, false /* complete */,
625                 0 /* result */, "whatever" /* callingPackage */);
626         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
627                 0 /* detailedCode */);
628         verify(mMockConnector, never()).switchToSubscription(anyString(), anyBoolean(), any());
629     }
630 
631     @Test
testSwitchToSubscription_serviceUnavailable()632     public void testSwitchToSubscription_serviceUnavailable() throws Exception {
633         setHasWriteEmbeddedPermission(true);
634         prepareOperationSubscription(false /* hasPrivileges */);
635         callSwitchToSubscription(
636                 SUBSCRIPTION_ID, ICC_ID, false /* complete */, 0 /* result */,
637                 "whatever" /* callingPackage */);
638         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
639                 0 /* detailedCode */);
640         verify(mMockConnector).switchToSubscription(anyString(), anyBoolean(), any());
641     }
642 
643     @Test
testSwitchToSubscription_error()644     public void testSwitchToSubscription_error() throws Exception {
645         setHasWriteEmbeddedPermission(true);
646         prepareOperationSubscription(false /* hasPrivileges */);
647         callSwitchToSubscription(
648                 SUBSCRIPTION_ID, ICC_ID, true /* complete */, 42 /* result */,
649                 "whatever" /* callingPackage */);
650         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
651                 42 /* detailedCode */);
652     }
653 
654     @Test
testSwitchToSubscription_success()655     public void testSwitchToSubscription_success() throws Exception {
656         setHasWriteEmbeddedPermission(true);
657         prepareOperationSubscription(false /* hasPrivileges */);
658         callSwitchToSubscription(
659                 SUBSCRIPTION_ID, ICC_ID, true /* complete */, EuiccService.RESULT_OK,
660                 "whatever" /* callingPackage */);
661         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK, 0 /* detailedCode */);
662     }
663 
664     @Test
testSwitchToSubscription_emptySubscription_success()665     public void testSwitchToSubscription_emptySubscription_success() throws Exception {
666         setHasWriteEmbeddedPermission(true);
667         callSwitchToSubscription(
668                 SubscriptionManager.INVALID_SUBSCRIPTION_ID, null /* iccid */, true /* complete */,
669                 EuiccService.RESULT_OK, "whatever" /* callingPackage */);
670         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK, 0 /* detailedCode */);
671     }
672 
673     @Test
testSwitchToSubscription_noPrivileges()674     public void testSwitchToSubscription_noPrivileges() throws Exception {
675         setHasWriteEmbeddedPermission(false);
676         prepareOperationSubscription(false /* hasPrivileges */);
677         callSwitchToSubscription(
678                 SUBSCRIPTION_ID, ICC_ID, false /* complete */, 0 /* result */,
679                 "whatever" /* callingPackage */);
680         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
681                 0 /* detailedCode */);
682         verify(mMockConnector, never()).switchToSubscription(anyString(), anyBoolean(), any());
683     }
684 
685     @Test
testSwitchToSubscription_hasCarrierPrivileges()686     public void testSwitchToSubscription_hasCarrierPrivileges() throws Exception {
687         setHasWriteEmbeddedPermission(false);
688         prepareOperationSubscription(true /* hasPrivileges */);
689         setHasCarrierPrivilegesOnActiveSubscription(true);
690         callSwitchToSubscription(
691                 SUBSCRIPTION_ID, ICC_ID, true /* complete */, EuiccService.RESULT_OK, PACKAGE_NAME);
692         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK, 0 /* detailedCode */);
693     }
694 
695     @Test
testSwitchToSubscription_hasCarrierPrivileges_needsConsent()696     public void testSwitchToSubscription_hasCarrierPrivileges_needsConsent() throws Exception {
697         setHasWriteEmbeddedPermission(false);
698         prepareOperationSubscription(true /* hasPrivileges */);
699         setHasCarrierPrivilegesOnActiveSubscription(false);
700         callSwitchToSubscription(
701                 SUBSCRIPTION_ID, ICC_ID, false /* complete */, 0 /* result */, PACKAGE_NAME);
702         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR,
703                 0 /* detailedCode */);
704         verify(mMockConnector, never()).switchToSubscription(anyString(), anyBoolean(), any());
705         verifyResolutionIntent(EuiccService.ACTION_RESOLVE_NO_PRIVILEGES,
706                 EuiccOperation.ACTION_SWITCH_NO_PRIVILEGES);
707     }
708 
709     @Test(expected = SecurityException.class)
testUpdateSubscriptionNickname_noPrivileges()710     public void testUpdateSubscriptionNickname_noPrivileges() throws Exception {
711         setHasWriteEmbeddedPermission(false);
712         callUpdateSubscriptionNickname(
713                 SUBSCRIPTION_ID, ICC_ID, "nickname", false /* complete */, 0 /* result */);
714     }
715 
716     @Test
testUpdateSubscriptionNickname_noSuchSubscription()717     public void testUpdateSubscriptionNickname_noSuchSubscription() throws Exception {
718         setHasWriteEmbeddedPermission(true);
719         callUpdateSubscriptionNickname(
720                 SUBSCRIPTION_ID, ICC_ID, "nickname", false /* complete */, 0 /* result */);
721         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
722                 0 /* detailedCode */);
723         verify(mMockConnector, never()).updateSubscriptionNickname(anyString(), anyString(), any());
724     }
725 
726     @Test
testUpdateSubscriptionNickname_serviceUnavailable()727     public void testUpdateSubscriptionNickname_serviceUnavailable() throws Exception {
728         setHasWriteEmbeddedPermission(true);
729         prepareOperationSubscription(false /* hasPrivileges */);
730         callUpdateSubscriptionNickname(
731                 SUBSCRIPTION_ID, ICC_ID, "nickname", false /* complete */, 0 /* result */);
732         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
733                 0 /* detailedCode */);
734         verify(mMockConnector).updateSubscriptionNickname(anyString(), anyString(), any());
735     }
736 
737     @Test
testUpdateSubscriptionNickname_error()738     public void testUpdateSubscriptionNickname_error() throws Exception {
739         setHasWriteEmbeddedPermission(true);
740         prepareOperationSubscription(false /* hasPrivileges */);
741         callUpdateSubscriptionNickname(
742                 SUBSCRIPTION_ID, ICC_ID, "nickname", true /* complete */, 42 /* result */);
743         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
744                 42 /* detailedCode */);
745     }
746 
747     @Test
testUpdateSubscriptionNickname_success()748     public void testUpdateSubscriptionNickname_success() throws Exception {
749         setHasWriteEmbeddedPermission(true);
750         prepareOperationSubscription(false /* hasPrivileges */);
751         callUpdateSubscriptionNickname(
752                 SUBSCRIPTION_ID, ICC_ID, "nickname", true /* complete */, EuiccService.RESULT_OK);
753         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK, 0 /* detailedCode */);
754     }
755 
756     @Test(expected = SecurityException.class)
testEraseSubscriptions_noPrivileges()757     public void testEraseSubscriptions_noPrivileges() throws Exception {
758         setHasWriteEmbeddedPermission(false);
759         callEraseSubscriptions(false /* complete */, 0 /* result */);
760     }
761 
762     @Test
testEraseSubscriptions_serviceUnavailable()763     public void testEraseSubscriptions_serviceUnavailable() throws Exception {
764         setHasWriteEmbeddedPermission(true);
765         callEraseSubscriptions(false /* complete */, 0 /* result */);
766         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
767                 0 /* detailedCode */);
768         verify(mMockConnector).eraseSubscriptions(any());
769     }
770 
771     @Test
testEraseSubscriptions_error()772     public void testEraseSubscriptions_error() throws Exception {
773         setHasWriteEmbeddedPermission(true);
774         callEraseSubscriptions(true /* complete */, 42 /* result */);
775         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
776                 42 /* detailedCode */);
777     }
778 
779     @Test
testEraseSubscriptions_success()780     public void testEraseSubscriptions_success() throws Exception {
781         setHasWriteEmbeddedPermission(true);
782         callEraseSubscriptions(true /* complete */, EuiccService.RESULT_OK);
783         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK, 0 /* detailedCode */);
784         assertTrue(mController.mCalledRefreshSubscriptionsAndSendResult);
785     }
786 
787     @Test(expected = SecurityException.class)
testRetainSubscriptionsForFactoryReset_noPrivileges()788     public void testRetainSubscriptionsForFactoryReset_noPrivileges() throws Exception {
789         setHasMasterClearPermission(false);
790         callRetainSubscriptionsForFactoryReset(false /* complete */, 0 /* result */);
791     }
792 
793     @Test
testRetainSubscriptionsForFactoryReset_serviceUnavailable()794     public void testRetainSubscriptionsForFactoryReset_serviceUnavailable() throws Exception {
795         setHasMasterClearPermission(true);
796         callRetainSubscriptionsForFactoryReset(false /* complete */, 0 /* result */);
797         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR, 0 /* detailedCode */);
798         verify(mMockConnector).retainSubscriptions(any());
799     }
800 
801     @Test
testRetainSubscriptionsForFactoryReset_error()802     public void testRetainSubscriptionsForFactoryReset_error() throws Exception {
803         setHasMasterClearPermission(true);
804         callRetainSubscriptionsForFactoryReset(true /* complete */, 42 /* result */);
805         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR, 42 /* detailedCode */);
806     }
807 
808     @Test
testRetainSubscriptionsForFactoryReset_success()809     public void testRetainSubscriptionsForFactoryReset_success() throws Exception {
810         setHasMasterClearPermission(true);
811         callRetainSubscriptionsForFactoryReset(true /* complete */, EuiccService.RESULT_OK);
812         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK, 0 /* detailedCode */);
813     }
814 
setGetEidPermissions( boolean hasPhoneStatePrivileged, boolean hasCarrierPrivileges)815     private void setGetEidPermissions(
816             boolean hasPhoneStatePrivileged, boolean hasCarrierPrivileges) {
817         doReturn(hasPhoneStatePrivileged
818                 ? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED)
819                 .when(mContext)
820                 .checkCallingPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
821         when(mTelephonyManager.hasCarrierPrivileges()).thenReturn(hasCarrierPrivileges);
822     }
823 
setHasWriteEmbeddedPermission(boolean hasPermission)824     private void setHasWriteEmbeddedPermission(boolean hasPermission) {
825         doReturn(hasPermission
826                 ? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED)
827                 .when(mContext)
828                 .checkCallingPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS);
829     }
830 
setHasMasterClearPermission(boolean hasPermission)831     private void setHasMasterClearPermission(boolean hasPermission) {
832         Stubber stubber = hasPermission ? doNothing() : doThrow(new SecurityException());
833         stubber.when(mContext).enforceCallingPermission(
834                 eq(Manifest.permission.MASTER_CLEAR), anyString());
835     }
836 
setHasCarrierPrivilegesOnActiveSubscription(boolean hasPrivileges)837     private void setHasCarrierPrivilegesOnActiveSubscription(boolean hasPrivileges)
838             throws Exception {
839         SubscriptionInfo subInfo = new SubscriptionInfo(
840                 0, "", 0, "", "", 0, 0, "", 0, null, 0, 0, "", true /* isEmbedded */,
841                 hasPrivileges ? new UiccAccessRule[] { ACCESS_RULE } : null);
842         when(mSubscriptionManager.canManageSubscription(subInfo, PACKAGE_NAME)).thenReturn(
843                 hasPrivileges);
844         when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(
845                 Collections.singletonList(subInfo));
846     }
847 
prepareOperationSubscription(boolean hasPrivileges)848     private void prepareOperationSubscription(boolean hasPrivileges) throws Exception {
849         SubscriptionInfo subInfo = new SubscriptionInfo(
850                 SUBSCRIPTION_ID, ICC_ID, 0, "", "", 0, 0, "", 0, null, 0, 0, "",
851                 true /* isEmbedded */, hasPrivileges ? new UiccAccessRule[] { ACCESS_RULE } : null);
852         when(mSubscriptionManager.canManageSubscription(subInfo, PACKAGE_NAME)).thenReturn(
853                 hasPrivileges);
854         when(mSubscriptionManager.getAvailableSubscriptionInfoList()).thenReturn(
855                 Collections.singletonList(subInfo));
856     }
857 
callGetEid(final boolean success, final @Nullable String eid)858     private String callGetEid(final boolean success, final @Nullable String eid) {
859         doAnswer(new Answer<Void>() {
860             @Override
861             public Void answer(InvocationOnMock invocation) throws Exception {
862                 EuiccConnector.GetEidCommandCallback cb = invocation.getArgument(0);
863                 if (success) {
864                     cb.onGetEidComplete(eid);
865                 } else {
866                     cb.onEuiccServiceUnavailable();
867                 }
868                 return null;
869             }
870         }).when(mMockConnector).getEid(Mockito.<EuiccConnector.GetEidCommandCallback>any());
871         return mController.getEid();
872     }
873 
callGetOtaStatus(final boolean success, final int status)874     private int callGetOtaStatus(final boolean success, final int status) {
875         doAnswer(new Answer<Void>() {
876             @Override
877             public Void answer(InvocationOnMock invocation) throws Exception {
878                 GetOtaStatusCommandCallback cb = invocation.getArgument(0);
879                 if (success) {
880                     cb.onGetOtaStatusComplete(status);
881                 } else {
882                     cb.onEuiccServiceUnavailable();
883                 }
884                 return null;
885             }
886         }).when(mMockConnector).getOtaStatus(Mockito.<GetOtaStatusCommandCallback>any());
887         return mController.getOtaStatus();
888     }
889 
callStartOtaUpdatingIfNecessary( final boolean serviceAvailable, int status)890     private void callStartOtaUpdatingIfNecessary(
891             final boolean serviceAvailable, int status) {
892         doAnswer(new Answer<Void>() {
893             @Override
894             public Void answer(InvocationOnMock invocation) throws Exception {
895                 OtaStatusChangedCallback cb = invocation.getArgument(0);
896                 if (!serviceAvailable) {
897                     cb.onEuiccServiceUnavailable();
898                 } else {
899                     cb.onOtaStatusChanged(status);
900                 }
901                 return null;
902             }
903         }).when(mMockConnector).startOtaIfNecessary(Mockito.<OtaStatusChangedCallback>any());
904 
905         mController.startOtaUpdatingIfNecessary();
906     }
907 
callGetEuiccInfo(final boolean success, final @Nullable EuiccInfo euiccInfo)908     private EuiccInfo callGetEuiccInfo(final boolean success, final @Nullable EuiccInfo euiccInfo) {
909         doAnswer(new Answer<Void>() {
910             @Override
911             public Void answer(InvocationOnMock invocation) throws Exception {
912                 EuiccConnector.GetEuiccInfoCommandCallback cb = invocation.getArgument(0);
913                 if (success) {
914                     cb.onGetEuiccInfoComplete(euiccInfo);
915                 } else {
916                     cb.onEuiccServiceUnavailable();
917                 }
918                 return null;
919             }
920         }).when(mMockConnector).getEuiccInfo(any());
921         return mController.getEuiccInfo();
922     }
923 
prepareGetDownloadableSubscriptionMetadataCall( final boolean complete, final GetDownloadableSubscriptionMetadataResult result)924     private void prepareGetDownloadableSubscriptionMetadataCall(
925             final boolean complete, final GetDownloadableSubscriptionMetadataResult result) {
926         doAnswer(new Answer<Void>() {
927             @Override
928             public Void answer(InvocationOnMock invocation) throws Exception {
929                 EuiccConnector.GetMetadataCommandCallback cb = invocation.getArgument(2);
930                 if (complete) {
931                     cb.onGetMetadataComplete(result);
932                 } else {
933                     cb.onEuiccServiceUnavailable();
934                 }
935                 return null;
936             }
937         }).when(mMockConnector).getDownloadableSubscriptionMetadata(any(), anyBoolean(), any());
938     }
939 
callGetDownloadableSubscriptionMetadata(DownloadableSubscription subscription, boolean complete, GetDownloadableSubscriptionMetadataResult result)940     private void callGetDownloadableSubscriptionMetadata(DownloadableSubscription subscription,
941             boolean complete, GetDownloadableSubscriptionMetadataResult result) {
942         prepareGetDownloadableSubscriptionMetadataCall(complete, result);
943         PendingIntent resultCallback = PendingIntent.getBroadcast(mContext, 0, new Intent(), 0);
944         mController.getDownloadableSubscriptionMetadata(subscription, PACKAGE_NAME, resultCallback);
945     }
946 
callGetDefaultDownloadableSubscriptionList( boolean complete, GetDefaultDownloadableSubscriptionListResult result)947     private void callGetDefaultDownloadableSubscriptionList(
948             boolean complete, GetDefaultDownloadableSubscriptionListResult result) {
949         doAnswer(new Answer<Void>() {
950             @Override
951             public Void answer(InvocationOnMock invocation) throws Exception {
952                 EuiccConnector.GetDefaultListCommandCallback cb = invocation.getArgument(1);
953                 if (complete) {
954                     cb.onGetDefaultListComplete(result);
955                 } else {
956                     cb.onEuiccServiceUnavailable();
957                 }
958                 return null;
959             }
960         }).when(mMockConnector).getDefaultDownloadableSubscriptionList(anyBoolean(), any());
961         PendingIntent resultCallback = PendingIntent.getBroadcast(mContext, 0, new Intent(), 0);
962         mController.getDefaultDownloadableSubscriptionList(PACKAGE_NAME, resultCallback);
963     }
964 
callDownloadSubscription(DownloadableSubscription subscription, boolean switchAfterDownload, final boolean complete, final int result, String callingPackage)965     private void callDownloadSubscription(DownloadableSubscription subscription,
966             boolean switchAfterDownload, final boolean complete, final int result,
967             String callingPackage) {
968         PendingIntent resultCallback = PendingIntent.getBroadcast(mContext, 0, new Intent(), 0);
969         doAnswer(new Answer<Void>() {
970             @Override
971             public Void answer(InvocationOnMock invocation) throws Exception {
972                 EuiccConnector.DownloadCommandCallback cb = invocation.getArgument(3);
973                 if (complete) {
974                     cb.onDownloadComplete(result);
975                 } else {
976                     cb.onEuiccServiceUnavailable();
977                 }
978                 return null;
979             }
980         }).when(mMockConnector).downloadSubscription(
981                 any(), eq(switchAfterDownload), anyBoolean(), any());
982         mController.downloadSubscription(subscription, switchAfterDownload, callingPackage,
983                 resultCallback);
984         // EUICC_PROVISIONED setting should match whether the download was successful.
985         assertEquals(complete && result == EuiccService.RESULT_OK ? 1 : 0,
986                 Settings.Global.getInt(mContext.getContentResolver(),
987                         Settings.Global.EUICC_PROVISIONED, 0));
988     }
989 
callDeleteSubscription(int subscriptionId, String iccid, final boolean complete, final int result, String callingPackage)990     private void callDeleteSubscription(int subscriptionId, String iccid, final boolean complete,
991             final int result, String callingPackage) {
992         PendingIntent resultCallback = PendingIntent.getBroadcast(mContext, 0, new Intent(), 0);
993         doAnswer(new Answer<Void>() {
994             @Override
995             public Void answer(InvocationOnMock invocation) throws Exception {
996                 EuiccConnector.DeleteCommandCallback cb = invocation.getArgument(1);
997                 if (complete) {
998                     cb.onDeleteComplete(result);
999                 } else {
1000                     cb.onEuiccServiceUnavailable();
1001                 }
1002                 return null;
1003             }
1004         }).when(mMockConnector).deleteSubscription(eq(iccid), any());
1005         mController.deleteSubscription(subscriptionId, callingPackage, resultCallback);
1006     }
1007 
callSwitchToSubscription(int subscriptionId, String iccid, final boolean complete, final int result, String callingPackage)1008     private void callSwitchToSubscription(int subscriptionId, String iccid, final boolean complete,
1009             final int result, String callingPackage) {
1010         PendingIntent resultCallback = PendingIntent.getBroadcast(mContext, 0, new Intent(), 0);
1011         doAnswer(new Answer<Void>() {
1012             @Override
1013             public Void answer(InvocationOnMock invocation) throws Exception {
1014                 EuiccConnector.SwitchCommandCallback cb = invocation.getArgument(2);
1015                 if (complete) {
1016                     cb.onSwitchComplete(result);
1017                 } else {
1018                     cb.onEuiccServiceUnavailable();
1019                 }
1020                 return null;
1021             }
1022         }).when(mMockConnector).switchToSubscription(eq(iccid), anyBoolean(), any());
1023         mController.switchToSubscription(subscriptionId, callingPackage, resultCallback);
1024     }
1025 
callUpdateSubscriptionNickname(int subscriptionId, String iccid, String nickname, final boolean complete, final int result)1026     private void callUpdateSubscriptionNickname(int subscriptionId, String iccid, String nickname,
1027             final boolean complete, final int result) {
1028         PendingIntent resultCallback = PendingIntent.getBroadcast(mContext, 0, new Intent(), 0);
1029         doAnswer(new Answer<Void>() {
1030             @Override
1031             public Void answer(InvocationOnMock invocation) throws Exception {
1032                 EuiccConnector.UpdateNicknameCommandCallback cb = invocation.getArgument(2);
1033                 if (complete) {
1034                     cb.onUpdateNicknameComplete(result);
1035                 } else {
1036                     cb.onEuiccServiceUnavailable();
1037                 }
1038                 return null;
1039             }
1040         }).when(mMockConnector).updateSubscriptionNickname(eq(iccid), eq(nickname), any());
1041         mController.updateSubscriptionNickname(subscriptionId, nickname, resultCallback);
1042     }
1043 
callEraseSubscriptions(final boolean complete, final int result)1044     private void callEraseSubscriptions(final boolean complete, final int result) {
1045         PendingIntent resultCallback = PendingIntent.getBroadcast(mContext, 0, new Intent(), 0);
1046         doAnswer(new Answer<Void>() {
1047             @Override
1048             public Void answer(InvocationOnMock invocation) throws Exception {
1049                 EuiccConnector.EraseCommandCallback cb = invocation.getArgument(0);
1050                 if (complete) {
1051                     cb.onEraseComplete(result);
1052                 } else {
1053                     cb.onEuiccServiceUnavailable();
1054                 }
1055                 return null;
1056             }
1057         }).when(mMockConnector).eraseSubscriptions(any());
1058         mController.eraseSubscriptions(resultCallback);
1059     }
1060 
callRetainSubscriptionsForFactoryReset(final boolean complete, final int result)1061     private void callRetainSubscriptionsForFactoryReset(final boolean complete, final int result) {
1062         PendingIntent resultCallback = PendingIntent.getBroadcast(mContext, 0, new Intent(), 0);
1063         doAnswer(new Answer<Void>() {
1064             @Override
1065             public Void answer(InvocationOnMock invocation) throws Exception {
1066                 EuiccConnector.RetainSubscriptionsCommandCallback cb = invocation.getArgument(0);
1067                 if (complete) {
1068                     cb.onRetainSubscriptionsComplete(result);
1069                 } else {
1070                     cb.onEuiccServiceUnavailable();
1071                 }
1072                 return null;
1073             }
1074         }).when(mMockConnector).retainSubscriptions(any());
1075         mController.retainSubscriptionsForFactoryReset(resultCallback);
1076     }
1077 
verifyResolutionIntent(String euiccUiAction, @EuiccOperation.Action int action)1078     private void verifyResolutionIntent(String euiccUiAction, @EuiccOperation.Action int action) {
1079         assertEquals(euiccUiAction, mController.mResolutionAction);
1080         assertNotNull(mController.mOp);
1081         assertEquals(action, mController.mOp.mAction);
1082     }
1083 
verifyIntentSent(int resultCode, int detailedCode)1084     private Intent verifyIntentSent(int resultCode, int detailedCode)
1085             throws RemoteException {
1086         assertNotNull(mController.mCallbackIntent);
1087         assertEquals(resultCode, mController.mResultCode);
1088         if (mController.mExtrasIntent == null) {
1089             assertEquals(0, detailedCode);
1090         } else {
1091             assertEquals(detailedCode,
1092                     mController.mExtrasIntent.getIntExtra(
1093                             EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, 0));
1094         }
1095         return mController.mExtrasIntent;
1096     }
1097 }
1098