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 android.telephony.euicc;
17 
18 import android.Manifest;
19 import android.annotation.IntDef;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.annotation.RequiresFeature;
23 import android.annotation.RequiresPermission;
24 import android.annotation.SdkConstant;
25 import android.annotation.SystemApi;
26 import android.app.Activity;
27 import android.app.PendingIntent;
28 import android.compat.annotation.ChangeId;
29 import android.compat.annotation.EnabledSince;
30 import android.content.Context;
31 import android.content.Intent;
32 import android.content.IntentSender;
33 import android.content.pm.PackageManager;
34 import android.os.Build;
35 import android.os.Bundle;
36 import android.os.RemoteException;
37 import android.telephony.SubscriptionInfo;
38 import android.telephony.SubscriptionManager;
39 import android.telephony.TelephonyFrameworkInitializer;
40 import android.telephony.TelephonyManager;
41 import android.telephony.UiccCardInfo;
42 import android.telephony.euicc.EuiccCardManager.ResetOption;
43 import android.util.Log;
44 
45 import com.android.internal.telephony.euicc.IEuiccController;
46 
47 import java.lang.annotation.Retention;
48 import java.lang.annotation.RetentionPolicy;
49 import java.util.Collections;
50 import java.util.List;
51 import java.util.Locale;
52 import java.util.stream.Collectors;
53 
54 /**
55  * EuiccManager is the application interface to eUICCs, or eSIMs/embedded SIMs.
56  *
57  * <p>You do not instantiate this class directly; instead, you retrieve an instance through
58  * {@link Context#getSystemService(String)} and {@link Context#EUICC_SERVICE}. This instance will be
59  * created using the default eUICC.
60  *
61  * <p>On a device with multiple eUICCs, you may want to create multiple EuiccManagers. To do this
62  * you can call {@link #createForCardId}.
63  *
64  * <p>See {@link #isEnabled} before attempting to use these APIs.
65  */
66 @RequiresFeature(PackageManager.FEATURE_TELEPHONY_EUICC)
67 public class EuiccManager {
68     private static final String TAG = "EuiccManager";
69 
70     /**
71      * Intent action to launch the embedded SIM (eUICC) management settings screen.
72      *
73      * <p>This screen shows a list of embedded profiles and offers the user the ability to switch
74      * between them, download new profiles, and delete unused profiles.
75      *
76      * <p>The activity will immediately finish with {@link android.app.Activity#RESULT_CANCELED} if
77      * {@link #isEnabled} is false.
78      *
79      * This is ued by non-LPA app to bring up LUI.
80      */
81     @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
82     public static final String ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS =
83             "android.telephony.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS";
84 
85 
86     /**
87      * Intent action to transfer an embedded subscriptions.
88      *
89      * <p> Action sent by apps (such as the Settings app) to the Telephony framework to transfer an
90      * embedded subscription.
91      *
92      * <p> Requires that the calling app has the
93      * {@code android.Manifest.permission#MODIFY_PHONE_STATE} permission.
94      *
95      * <p>The activity will immediately finish with {@link android.app.Activity#RESULT_CANCELED} if
96      * {@link #isEnabled} is false.
97      *
98      * @hide
99      */
100     @SystemApi
101     @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
102     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
103     public static final String ACTION_TRANSFER_EMBEDDED_SUBSCRIPTIONS =
104             "android.telephony.euicc.action.TRANSFER_EMBEDDED_SUBSCRIPTIONS";
105 
106     /**
107      * Intent action to convert the physical subscription to an embedded subscription.
108      *
109      * <p> Action sent by apps (such as the Settings app) to the Telephony framework to convert
110      * physical sim to embedded sim.
111      *
112      * <p> Requires that the calling app has the
113      * {@code android.Manifest.permission#MODIFY_PHONE_STATE} permission.
114      *
115      * <p>The activity will immediately finish with {@link android.app.Activity#RESULT_CANCELED} if
116      * {@link #isEnabled} is false.
117      *
118      * @hide
119      */
120     @SystemApi
121     @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
122     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
123     public static final String ACTION_CONVERT_TO_EMBEDDED_SUBSCRIPTION =
124             "android.telephony.euicc.action.CONVERT_TO_EMBEDDED_SUBSCRIPTION";
125 
126     /**
127      * Broadcast Action: The eUICC OTA status is changed.
128      * <p class="note">
129      * Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
130      *
131      * <p class="note">This is a protected intent that can only be sent
132      * by the system.
133      *
134      * @hide
135      */
136     @SystemApi
137     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
138     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
139     public static final String ACTION_OTA_STATUS_CHANGED =
140             "android.telephony.euicc.action.OTA_STATUS_CHANGED";
141 
142     /**
143      * Broadcast Action: The action sent to carrier app so it knows the carrier setup is not
144      * completed.
145      */
146     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
147     public static final String ACTION_NOTIFY_CARRIER_SETUP_INCOMPLETE =
148             "android.telephony.euicc.action.NOTIFY_CARRIER_SETUP_INCOMPLETE";
149 
150     /**
151      * Intent action to provision an embedded subscription.
152      *
153      * <p>May be called during device provisioning to launch a screen to perform embedded SIM
154      * provisioning, e.g. if no physical SIM is present and the user elects to configure their
155      * embedded SIM.
156      *
157      * <p>The activity will immediately finish with {@link android.app.Activity#RESULT_CANCELED} if
158      * {@link #isEnabled} is false.
159      *
160      * @hide
161      */
162     @SystemApi
163     @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
164     public static final String ACTION_PROVISION_EMBEDDED_SUBSCRIPTION =
165             "android.telephony.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION";
166 
167     /**
168      * Intent action to handle a resolvable error.
169      * @hide
170      */
171     public static final String ACTION_RESOLVE_ERROR =
172             "android.telephony.euicc.action.RESOLVE_ERROR";
173 
174     /**
175      * Intent action sent by system apps (such as the Settings app) to the Telephony framework to
176      * enable or disable a subscription. Must be accompanied with {@link #EXTRA_SUBSCRIPTION_ID} and
177      * {@link #EXTRA_ENABLE_SUBSCRIPTION}, and optionally {@link #EXTRA_FROM_SUBSCRIPTION_ID}.
178      *
179      * <p>Requires the caller to be a privileged process with the
180      * {@link android.permission#CALL_PRIVILEGED} permission for the intent to reach the Telephony
181      * stack.
182      *
183      * <p>Unlike {@link #switchToSubscription(int, PendingIntent)}, using this action allows the
184      * underlying eUICC service (i.e. the LPA app) to control the UI experience during this
185      * operation. The action is received by the Telephony framework, which in turn selects and
186      * launches an appropriate LPA activity to present UI to the user. For example, the activity may
187      * show a confirmation dialog, a progress dialog, or an error dialog when necessary.
188      *
189      * <p>The launched activity will immediately finish with
190      * {@link android.app.Activity#RESULT_CANCELED} if {@link #isEnabled} is false.
191      *
192      * @hide
193      */
194     @SystemApi
195     public static final String ACTION_TOGGLE_SUBSCRIPTION_PRIVILEGED =
196             "android.telephony.euicc.action.TOGGLE_SUBSCRIPTION_PRIVILEGED";
197 
198     /**
199      * Intent action sent by system apps (such as the Settings app) to the Telephony framework to
200      * delete a subscription. Must be accompanied with {@link #EXTRA_SUBSCRIPTION_ID}.
201      *
202      * <p>Requires the caller to be a privileged process with the
203      * {@link android.permission#CALL_PRIVILEGED} permission for the intent to reach the Telephony
204      * stack.
205      *
206      * <p>Unlike {@link #deleteSubscription(int, PendingIntent)}, using this action allows the
207      * underlying eUICC service (i.e. the LPA app) to control the UI experience during this
208      * operation. The action is received by the Telephony framework, which in turn selects and
209      * launches an appropriate LPA activity to present UI to the user. For example, the activity may
210      * show a confirmation dialog, a progress dialog, or an error dialog when necessary.
211      *
212      * <p>The launched activity will immediately finish with
213      * {@link android.app.Activity#RESULT_CANCELED} if {@link #isEnabled} is false.
214      *
215      * @hide
216      */
217     @SystemApi
218     public static final String ACTION_DELETE_SUBSCRIPTION_PRIVILEGED =
219             "android.telephony.euicc.action.DELETE_SUBSCRIPTION_PRIVILEGED";
220 
221     /**
222      * Intent action sent by system apps (such as the Settings app) to the Telephony framework to
223      * rename a subscription. Must be accompanied with {@link #EXTRA_SUBSCRIPTION_ID} and
224      * {@link #EXTRA_SUBSCRIPTION_NICKNAME}.
225      *
226      * <p>Requires the caller to be a privileged process with the
227      * {@link android.permission#CALL_PRIVILEGED} permission for the intent to reach the Telephony
228      * stack.
229      *
230      * <p>Unlike {@link #updateSubscriptionNickname(int, String, PendingIntent)}, using this action
231      * allows the the underlying eUICC service (i.e. the LPA app) to control the UI experience
232      * during this operation. The action is received by the Telephony framework, which in turn
233      * selects and launches an appropriate LPA activity to present UI to the user. For example, the
234      * activity may show a confirmation dialog, a progress dialog, or an error dialog when
235      * necessary.
236      *
237      * <p>The launched activity will immediately finish with
238      * {@link android.app.Activity#RESULT_CANCELED} if {@link #isEnabled} is false.
239      *
240      * @hide
241      */
242     @SystemApi
243     public static final String ACTION_RENAME_SUBSCRIPTION_PRIVILEGED =
244             "android.telephony.euicc.action.RENAME_SUBSCRIPTION_PRIVILEGED";
245 
246     /**
247      * Intent action sent by a carrier app to launch the eSIM activation flow provided by the LPA UI
248      * (LUI). The carrier app must send this intent with one of the following:
249      *
250      * <p>{@link #EXTRA_USE_QR_SCANNER} not set or set to false: The LPA should try to get an
251      * activation code from the carrier app by binding to the carrier app service implementing
252      * {@link android.service.euicc.EuiccService#ACTION_BIND_CARRIER_PROVISIONING_SERVICE}.
253      * <p>{@link #EXTRA_USE_QR_SCANNER} set to true: The LPA should launch a QR scanner for the user
254      * to scan an eSIM profile QR code.
255      *
256      * <p>Upon completion, the LPA should return one of the following results to the carrier app:
257      *
258      * <p>{@code Activity.RESULT_OK}: The LPA has succeeded in downloading the new eSIM profile.
259      * <p>{@code Activity.RESULT_CANCELED}: The carrier app should treat this as if the user pressed
260      * the back button.
261      * <p>Anything else: The carrier app should treat this as an error.
262      *
263      * <p>LPA needs to check if caller's package name is allowed to perform this action.
264      **/
265     @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
266     public static final String ACTION_START_EUICC_ACTIVATION =
267             "android.telephony.euicc.action.START_EUICC_ACTIVATION";
268 
269     /**
270      * Result code for an operation indicating that the operation succeeded.
271      */
272     public static final int EMBEDDED_SUBSCRIPTION_RESULT_OK = 0;
273 
274     /**
275      * Result code for an operation indicating that the user must take some action before the
276      * operation can continue.
277      *
278      * @see #startResolutionActivity
279      */
280     public static final int EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR = 1;
281 
282     /**
283      * Result code for an operation indicating that an unresolvable error occurred.
284      *
285      * {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} will be populated with a detailed error
286      * code for logging/debugging purposes only.
287      */
288     public static final int EMBEDDED_SUBSCRIPTION_RESULT_ERROR = 2;
289 
290     /**
291      * Key for an extra set on the {@link #ACTION_PROVISION_EMBEDDED_SUBSCRIPTION} intent for which
292      * kind of activation flow will be evolved. (see {@code EUICC_ACTIVATION_})
293      *
294      * @hide
295      */
296     @SystemApi
297     public static final String EXTRA_ACTIVATION_TYPE =
298             "android.telephony.euicc.extra.ACTIVATION_TYPE";
299 
300     /**
301      * Key for an extra set on {@link PendingIntent} result callbacks providing a detailed result
302      * code.
303      *
304      * <p>The value of this key is an integer and contains two portions. The first byte is
305      * OperationCode and the reaming three bytes is the ErrorCode.
306      *
307      * OperationCode is the first byte of the result code and is a categorization which defines what
308      * type of operation took place when an error occurred. e.g {@link #OPERATION_DOWNLOAD} means
309      * the error is related to download.Since the OperationCode only uses at most one byte, the
310      * maximum allowed quantity is 255(0xFF).
311      *
312      * ErrorCode is the remaining three bytes of the result code, and it denotes what happened.
313      * e.g a combination of {@link #OPERATION_DOWNLOAD} and {@link #ERROR_TIME_OUT} will suggest the
314      * download operation has timed out. The only exception here is
315      * {@link #OPERATION_SMDX_SUBJECT_REASON_CODE}, where instead of ErrorCode, SubjectCode[5.2.6.1
316      * from GSMA (SGP.22 v2.2) and ReasonCode[5.2.6.2] from GSMA (SGP.22 v2.2) are encoded. @see
317      * {@link #EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_SUBJECT_CODE} and
318      * {@link #EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_REASON_CODE}
319      *
320      * In the case where ErrorCode contains a value of 0, it means it's an unknown error. E.g Intent
321      * only contains {@link #OPERATION_DOWNLOAD} and ErrorCode is 0 implies this is an unknown
322      * Download error.
323      *
324      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_OPERATION_CODE
325      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_ERROR_CODE
326      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_SUBJECT_CODE
327      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_REASON_CODE
328      */
329     public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE =
330             "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DETAILED_CODE";
331 
332     /**
333      * Key for an extra set on {@link PendingIntent} result callbacks providing a
334      * OperationCode of {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE},
335      * value will be an int.
336      */
337     public static final String EXTRA_EMBEDDED_SUBSCRIPTION_OPERATION_CODE =
338             "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_OPERATION_CODE";
339 
340     /**
341      * Key for an extra set on {@link PendingIntent} result callbacks providing a
342      * ErrorCode of {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE},
343      * value will be an int.
344      */
345     public static final String EXTRA_EMBEDDED_SUBSCRIPTION_ERROR_CODE =
346             "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_ERROR_CODE";
347 
348     /**
349      * Key for an extra set on {@link PendingIntent} result callbacks providing a
350      * SubjectCode[5.2.6.1] from GSMA (SGP.22 v2.2) decoded from
351      * {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE}.
352      * The value of this extra will be a String.
353      */
354     public static final String EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_SUBJECT_CODE =
355             "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_SMDX_SUBJECT_CODE";
356 
357     /**
358      * Key for an extra set on {@link PendingIntent} result callbacks providing a
359      * ReasonCode[5.2.6.2] from GSMA (SGP.22 v2.2) decoded from
360      * {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE}.
361      * The value of this extra will be a String.
362      */
363     public static final String EXTRA_EMBEDDED_SUBSCRIPTION_SMDX_REASON_CODE =
364             "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_SMDX_REASON_CODE";
365 
366     /**
367      * Key for an extra set on {@code #getDownloadableSubscriptionMetadata} PendingIntent result
368      * callbacks providing the downloadable subscription metadata.
369      */
370     public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION =
371             "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION";
372 
373     /**
374      * Key for an extra set on {@link #getDefaultDownloadableSubscriptionList} PendingIntent result
375      * callbacks providing the list of available downloadable subscriptions.
376      * @hide
377      */
378     @SystemApi
379     public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS =
380             "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS";
381 
382     /**
383      * Key for an extra set on {@link PendingIntent} result callbacks providing the resolution
384      * pending intent for {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR}s.
385      * @hide
386      */
387     public static final String EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT =
388             "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT";
389 
390     /**
391      * Key for an extra set on the {@link #EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT} intent
392      * containing the EuiccService action to launch for resolution.
393      * @hide
394      */
395     public static final String EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_ACTION =
396             "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_RESOLUTION_ACTION";
397 
398     /**
399      * Key for an extra set on the {@link #EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT} intent
400      * providing the callback to execute after resolution is completed.
401      * @hide
402      */
403     public static final String EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT =
404             "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT";
405 
406     /**
407      * Key for an extra set on the {@link #ACTION_PROVISION_EMBEDDED_SUBSCRIPTION} intent for
408      * whether eSIM provisioning flow is forced to be started or not. If this extra hasn't been
409      * set, eSIM provisioning flow may be skipped and the corresponding carrier's app will be
410      * notified. Otherwise, eSIM provisioning flow will be started when
411      * {@link #ACTION_PROVISION_EMBEDDED_SUBSCRIPTION} has been received.
412      * @hide
413      */
414     @SystemApi
415     public static final String EXTRA_FORCE_PROVISION =
416             "android.telephony.euicc.extra.FORCE_PROVISION";
417 
418     /**
419      * Key for an extra set on privileged actions {@link #ACTION_TOGGLE_SUBSCRIPTION_PRIVILEGED},
420      * {@link #ACTION_DELETE_SUBSCRIPTION_PRIVILEGED}, and
421      * {@link #ACTION_RENAME_SUBSCRIPTION_PRIVILEGED} providing the ID of the targeted subscription.
422      *
423      * <p>Expected type of the extra data: int
424      *
425      * @hide
426      */
427     @SystemApi
428     public static final String EXTRA_SUBSCRIPTION_ID =
429             "android.telephony.euicc.extra.SUBSCRIPTION_ID";
430 
431     /**
432      * Key for an extra set on {@link #ACTION_TOGGLE_SUBSCRIPTION_PRIVILEGED} providing a boolean
433      * value of whether to enable or disable the targeted subscription.
434      *
435      * <p>Expected type of the extra data: boolean
436      *
437      * @hide
438      */
439     @SystemApi
440     public static final String EXTRA_ENABLE_SUBSCRIPTION =
441             "android.telephony.euicc.extra.ENABLE_SUBSCRIPTION";
442 
443     /**
444      * Key for an extra set on {@link #ACTION_RENAME_SUBSCRIPTION_PRIVILEGED} providing a new
445      * nickname for the targeted subscription.
446      *
447      * <p>Expected type of the extra data: String
448      *
449      * @hide
450      */
451     @SystemApi
452     public static final String EXTRA_SUBSCRIPTION_NICKNAME =
453             "android.telephony.euicc.extra.SUBSCRIPTION_NICKNAME";
454 
455     /**
456      * Key for an extra set on {@link #ACTION_TOGGLE_SUBSCRIPTION_PRIVILEGED} providing the ID of
457      * the subscription we're toggling from. This extra is optional and is only used for UI
458      * purposes by the underlying eUICC service (i.e. the LPA app), such as displaying a dialog
459      * titled "Switch X with Y". If set, the provided subscription will be used as the "from"
460      * subscription in UI (the "X" in the dialog example). Otherwise, the currently active
461      * subscription that will be disabled is the "from" subscription.
462      *
463      * <p>Expected type of the extra data: int
464      *
465      * @hide
466      */
467     @SystemApi
468     public static final String EXTRA_FROM_SUBSCRIPTION_ID =
469             "android.telephony.euicc.extra.FROM_SUBSCRIPTION_ID";
470 
471     /**
472      * Key for an extra set on privileged actions {@link #ACTION_TOGGLE_SUBSCRIPTION_PRIVILEGED}
473      * providing the physical slot ID of the target slot.
474      *
475      * <p>Expected type of the extra data: int
476      *
477      * @hide
478      */
479     @SystemApi
480     public static final String EXTRA_PHYSICAL_SLOT_ID =
481             "android.telephony.euicc.extra.PHYSICAL_SLOT_ID";
482 
483 
484     /**
485      * Key for an extra set on actions {@link #ACTION_START_EUICC_ACTIVATION} providing a boolean
486      * value of whether to start eSIM activation with QR scanner.
487      *
488      * <p>Expected type of the extra data: boolean
489      **/
490     public static final String EXTRA_USE_QR_SCANNER =
491             "android.telephony.euicc.extra.USE_QR_SCANNER";
492 
493     /**
494      * Optional meta-data attribute for a carrier app providing an icon to use to represent the
495      * carrier. If not provided, the app's launcher icon will be used as a fallback.
496      */
497     public static final String META_DATA_CARRIER_ICON = "android.telephony.euicc.carriericon";
498 
499     /**
500      * Euicc activation type which will be included in {@link #EXTRA_ACTIVATION_TYPE} and used to
501      * decide which kind of activation flow should be lauched.
502      *
503      * @hide
504      */
505     @Retention(RetentionPolicy.SOURCE)
506     @IntDef(prefix = {"EUICC_ACTIVATION_"}, value = {
507             EUICC_ACTIVATION_TYPE_DEFAULT,
508             EUICC_ACTIVATION_TYPE_BACKUP,
509             EUICC_ACTIVATION_TYPE_TRANSFER,
510             EUICC_ACTIVATION_TYPE_ACCOUNT_REQUIRED,
511     })
512     public @interface EuiccActivationType{}
513 
514 
515     /**
516      * The default euicc activation type which includes checking server side and downloading the
517      * profile based on carrier's download configuration.
518      *
519      * @hide
520      */
521     @SystemApi
522     public static final int EUICC_ACTIVATION_TYPE_DEFAULT = 1;
523 
524     /**
525      * The euicc activation type used when the default download process failed. LPA will start the
526      * backup flow and try to download the profile for the carrier.
527      *
528      * @hide
529      */
530     @SystemApi
531     public static final int EUICC_ACTIVATION_TYPE_BACKUP = 2;
532 
533     /**
534      * The activation flow of eSIM seamless transfer will be used. LPA will start normal eSIM
535      * activation flow and if it's failed, the name of the carrier selected will be recorded. After
536      * the future device pairing, LPA will contact this carrier to transfer it from the other device
537      * to this device.
538      *
539      * @hide
540      */
541     @SystemApi
542     public static final int EUICC_ACTIVATION_TYPE_TRANSFER = 3;
543 
544     /**
545      * The activation flow of eSIM requiring user account will be started. This can only be used
546      * when there is user account signed in. Otherwise, the flow will be failed.
547      *
548      * @hide
549      */
550     @SystemApi
551     public static final int EUICC_ACTIVATION_TYPE_ACCOUNT_REQUIRED = 4;
552 
553     /**
554      * Euicc OTA update status which can be got by {@link #getOtaStatus}
555      * @hide
556      */
557     @SystemApi
558     @Retention(RetentionPolicy.SOURCE)
559     @IntDef(prefix = {"EUICC_OTA_"}, value = {
560             EUICC_OTA_IN_PROGRESS,
561             EUICC_OTA_FAILED,
562             EUICC_OTA_SUCCEEDED,
563             EUICC_OTA_NOT_NEEDED,
564             EUICC_OTA_STATUS_UNAVAILABLE
565 
566     })
567     public @interface OtaStatus{}
568 
569     /**
570      * An OTA is in progress. During this time, the eUICC is not available and the user may lose
571      * network access.
572      * @hide
573      */
574     @SystemApi
575     public static final int EUICC_OTA_IN_PROGRESS = 1;
576 
577     /**
578      * The OTA update failed.
579      * @hide
580      */
581     @SystemApi
582     public static final int EUICC_OTA_FAILED = 2;
583 
584     /**
585      * The OTA update finished successfully.
586      * @hide
587      */
588     @SystemApi
589     public static final int EUICC_OTA_SUCCEEDED = 3;
590 
591     /**
592      * The OTA update not needed since current eUICC OS is latest.
593      * @hide
594      */
595     @SystemApi
596     public static final int EUICC_OTA_NOT_NEEDED = 4;
597 
598     /**
599      * The OTA status is unavailable since eUICC service is unavailable.
600      * @hide
601      */
602     @SystemApi
603     public static final int EUICC_OTA_STATUS_UNAVAILABLE = 5;
604 
605     /**
606      * List of OperationCode corresponding to {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE}'s
607      * value, an integer. @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details
608      *
609      * @hide
610      */
611     @Retention(RetentionPolicy.SOURCE)
612     @IntDef(prefix = {"OPERATION_"}, value = {
613             OPERATION_SYSTEM,
614             OPERATION_SIM_SLOT,
615             OPERATION_EUICC_CARD,
616             OPERATION_SWITCH,
617             OPERATION_DOWNLOAD,
618             OPERATION_METADATA,
619             OPERATION_EUICC_GSMA,
620             OPERATION_APDU,
621             OPERATION_SMDX,
622             OPERATION_HTTP,
623             OPERATION_SMDX_SUBJECT_REASON_CODE,
624     })
625     public @interface OperationCode {
626     }
627 
628     /**
629      * Internal system error.
630      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details
631      */
632     public static final int OPERATION_SYSTEM = 1;
633 
634     /**
635      * SIM slot error. Failed to switch slot, failed to access the physical slot etc.
636      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details
637      */
638     public static final int OPERATION_SIM_SLOT = 2;
639 
640     /**
641      * eUICC card error.
642      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details
643      */
644     public static final int OPERATION_EUICC_CARD = 3;
645 
646     /**
647      * Generic switching profile error
648      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details
649      */
650     public static final int OPERATION_SWITCH = 4;
651 
652     /**
653      * Download profile error.
654      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details
655      */
656     public static final int OPERATION_DOWNLOAD = 5;
657 
658     /**
659      * Subscription's metadata error
660      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details
661      */
662     public static final int OPERATION_METADATA = 6;
663 
664     /**
665      * eUICC returned an error defined in GSMA (SGP.22 v2.2) while running one of the ES10x
666      * functions.
667      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details
668      */
669     public static final int OPERATION_EUICC_GSMA = 7;
670 
671     /**
672      * The exception of failing to execute an APDU command. It can be caused by an error
673      * happening on opening the basic or logical channel, or the response of the APDU command is
674      * not success (0x9000).
675      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details
676      */
677     public static final int OPERATION_APDU = 8;
678 
679     /**
680      * SMDX(SMDP/SMDS) error
681      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details
682      */
683     public static final int OPERATION_SMDX = 9;
684 
685     /**
686      * SubjectCode[5.2.6.1] and ReasonCode[5.2.6.2] error from GSMA (SGP.22 v2.2)
687      * When {@link #OPERATION_SMDX_SUBJECT_REASON_CODE} is used as the
688      * {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE}, the remaining three bytes of the integer
689      * result from {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} will be used to stored the
690      * SubjectCode and ReasonCode from the GSMA spec and NOT ErrorCode.
691      *
692      * The encoding will follow the format of:
693      * 1. The first byte of the result will be 255(0xFF).
694      * 2. Remaining three bytes(24 bits) will be split into six sections, 4 bits in each section.
695      * 3. A SubjectCode/ReasonCode will take 12 bits each.
696      * 4. The maximum number can be represented per section is 15, as that is the maximum number
697      * allowed to be stored into 4 bits
698      * 5. Maximum supported nested category from GSMA is three layers. E.g 8.11.1.2 is not
699      * supported.
700      *
701      * E.g given SubjectCode(8.11.1) and ReasonCode(5.1)
702      *
703      * Base10:  0       10      8       11      1       0       5       1
704      * Base2:   0000    1010    1000    1011    0001    0000    0101    0001
705      * Base16:  0       A       8       B       1       0       5       1
706      *
707      * Thus the integer stored in {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} is
708      * 0xA8B1051(176885841)
709      *
710      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details
711      */
712     public static final int OPERATION_SMDX_SUBJECT_REASON_CODE = 10;
713 
714     /**
715      * HTTP error
716      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details
717      */
718     public static final int OPERATION_HTTP = 11;
719 
720     /**
721      * List of ErrorCode corresponding to {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE}
722      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details
723      * @hide
724      */
725     @Retention(RetentionPolicy.SOURCE)
726     @IntDef(prefix = {"ERROR_"}, value = {
727             ERROR_CARRIER_LOCKED,
728             ERROR_INVALID_ACTIVATION_CODE,
729             ERROR_INVALID_CONFIRMATION_CODE,
730             ERROR_INCOMPATIBLE_CARRIER,
731             ERROR_EUICC_INSUFFICIENT_MEMORY,
732             ERROR_TIME_OUT,
733             ERROR_EUICC_MISSING,
734             ERROR_UNSUPPORTED_VERSION,
735             ERROR_SIM_MISSING,
736             ERROR_INSTALL_PROFILE,
737             ERROR_DISALLOWED_BY_PPR,
738             ERROR_ADDRESS_MISSING,
739             ERROR_CERTIFICATE_ERROR,
740             ERROR_NO_PROFILES_AVAILABLE,
741             ERROR_CONNECTION_ERROR,
742             ERROR_INVALID_RESPONSE,
743             ERROR_OPERATION_BUSY,
744     })
745     public @interface ErrorCode{}
746 
747     /**
748      * Operation such as downloading/switching to another profile failed due to device being
749      * carrier locked.
750      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details
751      */
752     public static final int ERROR_CARRIER_LOCKED = 10000;
753 
754     /**
755      * The activation code(SGP.22 v2.2 section[4.1]) is invalid.
756      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details
757      */
758     public static final int ERROR_INVALID_ACTIVATION_CODE = 10001;
759 
760     /**
761      * The confirmation code(SGP.22 v2.2 section[4.7]) is invalid.
762      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details
763      */
764     public static final int ERROR_INVALID_CONFIRMATION_CODE = 10002;
765 
766     /**
767      * The profile's carrier is incompatible with the LPA.
768      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details
769      */
770     public static final int ERROR_INCOMPATIBLE_CARRIER = 10003;
771 
772     /**
773      * There is no more space available on the eUICC for new profiles.
774      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details
775      */
776     public static final int ERROR_EUICC_INSUFFICIENT_MEMORY = 10004;
777 
778     /**
779      * Timed out while waiting for an operation to complete. i.e restart, disable,
780      * switch reset etc.
781      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details
782      */
783     public static final int ERROR_TIME_OUT = 10005;
784 
785     /**
786      * eUICC is missing or defective on the device.
787      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details
788      */
789     public static final int ERROR_EUICC_MISSING = 10006;
790 
791     /**
792      * The eUICC card(hardware) version is incompatible with the software
793      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details
794      */
795     public static final int ERROR_UNSUPPORTED_VERSION = 10007;
796 
797     /**
798      * No SIM card is available in the device.
799      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details
800      */
801     public static final int ERROR_SIM_MISSING = 10008;
802 
803     /**
804      * Failure to load the profile onto the eUICC card. e.g
805      * 1. iccid of the profile already exists on the eUICC.
806      * 2. GSMA(.22 v2.2) Profile Install Result - installFailedDueToDataMismatch
807      * 3. operation was interrupted
808      * 4. SIMalliance error in PEStatus(SGP.22 v2.2 section 2.5.6.1)
809      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details
810      */
811     public static final int ERROR_INSTALL_PROFILE = 10009;
812 
813     /**
814      * Failed to load profile onto eUICC due to Profile Policy Rules.
815      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details
816      */
817     public static final int ERROR_DISALLOWED_BY_PPR = 10010;
818 
819 
820     /**
821      * Address is missing e.g SMDS/SMDP address is missing.
822      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details
823      */
824     public static final int ERROR_ADDRESS_MISSING = 10011;
825 
826     /**
827      * Certificate needed for authentication is not valid or missing. E.g  SMDP/SMDS authentication
828      * failed.
829      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details
830      */
831     public static final int ERROR_CERTIFICATE_ERROR = 10012;
832 
833 
834     /**
835      * No profiles available.
836      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details
837      */
838     public static final int ERROR_NO_PROFILES_AVAILABLE = 10013;
839 
840     /**
841      * Failure to create a connection.
842      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details
843      */
844     public static final int ERROR_CONNECTION_ERROR = 10014;
845 
846     /**
847      * Response format is invalid. e.g SMDP/SMDS response contains invalid json, header or/and ASN1.
848      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details
849      */
850     public static final int ERROR_INVALID_RESPONSE = 10015;
851 
852     /**
853      * The operation is currently busy, try again later.
854      * @see #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE for details
855      */
856     public static final int ERROR_OPERATION_BUSY = 10016;
857 
858     /**
859      * Failure due to target port is not supported.
860      * @see #switchToSubscription(int, int, PendingIntent)
861      */
862     public static final int ERROR_INVALID_PORT = 10017;
863 
864     /**
865      * Apps targeting on Android T and beyond will get exception whenever switchToSubscription
866      * without portIndex is called for disable subscription.
867      * @hide
868      */
869     @ChangeId
870     @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
871     public static final long SWITCH_WITHOUT_PORT_INDEX_EXCEPTION_ON_DISABLE = 218393363L;
872 
873     /**
874      * With support for MEP(multiple enabled profile) in Android T, a SIM card can enable multiple
875      * profile on different port. If apps are not target SDK T yet and keep calling the
876      * switchToSubscription or download API without specifying the port index, we should
877      * keep the existing behaviour by always use port index 0 even the device itself has MEP eUICC,
878      * this is for carrier app's backward compatibility.
879      * @hide
880      */
881     @ChangeId
882     @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
883     public static final long SHOULD_RESOLVE_PORT_INDEX_FOR_APPS = 224562872L;
884 
885     /**
886      * Starting with Android U, a port is available if it is active without an enabled profile
887      * on it or calling app can activate a new profile on the selected port without any user
888      * interaction.
889      * @hide
890      */
891     @ChangeId
892     @EnabledSince(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
893     public static final long INACTIVE_PORT_AVAILABILITY_CHECK = 240273417L;
894 
895     private final Context mContext;
896     private int mCardId;
897 
898     /** @hide */
EuiccManager(Context context)899     public EuiccManager(Context context) {
900         mContext = context;
901         TelephonyManager tm = (TelephonyManager)
902                 context.getSystemService(Context.TELEPHONY_SERVICE);
903         mCardId = tm.getCardIdForDefaultEuicc();
904     }
905 
906     /** @hide */
EuiccManager(Context context, int cardId)907     private EuiccManager(Context context, int cardId) {
908         mContext = context;
909         mCardId = cardId;
910     }
911 
912     /**
913      * Create a new EuiccManager object pinned to the given card ID.
914      *
915      * @return an EuiccManager that uses the given card ID for all calls.
916      */
917     @NonNull
createForCardId(int cardId)918     public EuiccManager createForCardId(int cardId) {
919         return new EuiccManager(mContext, cardId);
920     }
921 
922     /**
923      * Whether embedded subscriptions are currently enabled.
924      *
925      * <p>Even on devices with the {@link PackageManager#FEATURE_TELEPHONY_EUICC} feature, embedded
926      * subscriptions may be turned off, e.g. because of a carrier restriction from an inserted
927      * physical SIM. Therefore, this runtime check should be used before accessing embedded
928      * subscription APIs.
929      *
930      * @return true if embedded subscriptions are currently enabled.
931      */
isEnabled()932     public boolean isEnabled() {
933         // In the future, this may reach out to IEuiccController (if non-null) to check any dynamic
934         // restrictions.
935         return getIEuiccController() != null && refreshCardIdIfUninitialized();
936     }
937 
938     /**
939      * Returns the EID identifying the eUICC hardware.
940      *
941      * <p>Requires that the calling app has carrier privileges on the active subscription on the
942      * current eUICC. A calling app with carrier privileges for one eUICC may not necessarily have
943      * access to the EID of another eUICC.
944      *
945      * @return the EID. May be null if the eUICC is not ready.
946      */
947     @Nullable
getEid()948     public String getEid() {
949         if (!isEnabled()) {
950             return null;
951         }
952         try {
953             return getIEuiccController().getEid(mCardId, mContext.getOpPackageName());
954         } catch (RemoteException e) {
955             throw e.rethrowFromSystemServer();
956         }
957     }
958 
959     /**
960      * Returns the current status of eUICC OTA.
961      *
962      * <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
963      *
964      * @return the status of eUICC OTA. If the eUICC is not ready,
965      *         {@link OtaStatus#EUICC_OTA_STATUS_UNAVAILABLE} will be returned.
966      *
967      * @hide
968      */
969     @SystemApi
970     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
getOtaStatus()971     public int getOtaStatus() {
972         if (!isEnabled()) {
973             return EUICC_OTA_STATUS_UNAVAILABLE;
974         }
975         try {
976             return getIEuiccController().getOtaStatus(mCardId);
977         } catch (RemoteException e) {
978             throw e.rethrowFromSystemServer();
979         }
980     }
981 
982     /**
983      * Attempt to download the given {@link DownloadableSubscription}.
984      *
985      * <p>Requires the {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission,
986      * or the calling app must be authorized to manage both the currently-active subscription on the
987      * current eUICC and the subscription to be downloaded according to the subscription metadata.
988      * Without the former, an {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR} will be
989      * returned in the callback intent to prompt the user to accept the download.
990      *
991      * <p>On a multi-active SIM device, requires the
992      * {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission, or a calling app
993      * only if the targeted eUICC does not currently have an active subscription or the calling app
994      * is authorized to manage the active subscription on the target eUICC, and the calling app is
995      * authorized to manage any active subscription on any SIM. Without it, an
996      * {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR} will be returned in the callback
997      * intent to prompt the user to accept the download. The caller should also be authorized to
998      * manage the subscription to be downloaded.
999      *
1000      * <p>If device support {@link PackageManager#FEATURE_TELEPHONY_EUICC_MEP} and
1001      * switchAfterDownload is {@code true}, the subscription will be enabled on an esim port based
1002      * on the following selection rules:
1003      * <ul>
1004      *    <li>In SS(Single SIM) mode, if the embedded slot already has an active port, then download
1005      *    and enable the subscription on this port.
1006      *    <li>In SS mode, if the embedded slot is not active, then try to download and enable the
1007      *    subscription on the default port 0 of eUICC.
1008      *    <li>In DSDS mode, find first available port to download and enable the subscription.
1009      *    (see {@link #isSimPortAvailable(int)})
1010      *</ul>
1011      * If there is no available port, an {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR}
1012      * will be returned in the callback intent to prompt the user to disable an already-active
1013      * subscription.
1014      *
1015      * @param subscription the subscription to download.
1016      * @param switchAfterDownload if true, the profile will be activated upon successful download.
1017      * @param callbackIntent a PendingIntent to launch when the operation completes.
1018      */
1019     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
downloadSubscription(DownloadableSubscription subscription, boolean switchAfterDownload, PendingIntent callbackIntent)1020     public void downloadSubscription(DownloadableSubscription subscription,
1021             boolean switchAfterDownload, PendingIntent callbackIntent) {
1022         if (!isEnabled()) {
1023             sendUnavailableError(callbackIntent);
1024             return;
1025         }
1026         try {
1027             getIEuiccController().downloadSubscription(mCardId, subscription, switchAfterDownload,
1028                     mContext.getOpPackageName(), null /* resolvedBundle */, callbackIntent);
1029         } catch (RemoteException e) {
1030             throw e.rethrowFromSystemServer();
1031         }
1032     }
1033 
1034     /**
1035      * Start an activity to resolve a user-resolvable error.
1036      *
1037      * <p>If an operation returns {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR}, this
1038      * method may be called to prompt the user to resolve the issue.
1039      *
1040      * <p>This method may only be called once for a particular error.
1041      *
1042      * @param activity the calling activity (which should be in the foreground).
1043      * @param requestCode an application-specific request code which will be provided to
1044      *     {@link Activity#onActivityResult} upon completion. Note that the operation may still be
1045      *     in progress when the resolution activity completes; it is not fully finished until the
1046      *     callback intent is triggered.
1047      * @param resultIntent the Intent provided to the initial callback intent which failed with
1048      *     {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR}.
1049      * @param callbackIntent a PendingIntent to launch when the operation completes. This is
1050      *     trigered upon completion of the original operation that required user resolution.
1051      * @throws android.content.IntentSender.SendIntentException if called more than once.
1052      */
startResolutionActivity(Activity activity, int requestCode, Intent resultIntent, PendingIntent callbackIntent)1053     public void startResolutionActivity(Activity activity, int requestCode, Intent resultIntent,
1054             PendingIntent callbackIntent) throws IntentSender.SendIntentException {
1055         PendingIntent resolutionIntent =
1056                 resultIntent.getParcelableExtra(EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT, android.app.PendingIntent.class);
1057         if (resolutionIntent == null) {
1058             throw new IllegalArgumentException("Invalid result intent");
1059         }
1060         Intent fillInIntent = new Intent();
1061         fillInIntent.putExtra(EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT,
1062                 callbackIntent);
1063         activity.startIntentSenderForResult(resolutionIntent.getIntentSender(), requestCode,
1064                 fillInIntent, 0 /* flagsMask */, 0 /* flagsValues */, 0 /* extraFlags */);
1065     }
1066 
1067     /**
1068      * Continue an operation after the user resolves an error.
1069      *
1070      * <p>To be called by the LUI upon completion of a resolvable error flow.
1071      *
1072      * <p>Requires that the calling app has the
1073      * {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
1074      *
1075      * @param resolutionIntent The original intent used to start the LUI.
1076      * @param resolutionExtras Resolution-specific extras depending on the result of the resolution.
1077      *     For example, this may indicate whether the user has consented or may include the input
1078      *     they provided.
1079      * @hide
1080      */
1081     @SystemApi
1082     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
continueOperation(Intent resolutionIntent, Bundle resolutionExtras)1083     public void continueOperation(Intent resolutionIntent, Bundle resolutionExtras) {
1084         if (!isEnabled()) {
1085             PendingIntent callbackIntent =
1086                     resolutionIntent.getParcelableExtra(
1087                             EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT, android.app.PendingIntent.class);
1088             if (callbackIntent != null) {
1089                 sendUnavailableError(callbackIntent);
1090             }
1091             return;
1092         }
1093         try {
1094             getIEuiccController().continueOperation(mCardId, resolutionIntent, resolutionExtras);
1095         } catch (RemoteException e) {
1096             throw e.rethrowFromSystemServer();
1097         }
1098     }
1099 
1100     /**
1101      * Fills in the metadata for a DownloadableSubscription.
1102      *
1103      * <p>May be used in cases that a DownloadableSubscription was constructed to download a
1104      * profile, but the metadata for the profile is unknown (e.g. we only know the activation code).
1105      * The callback will be triggered with an Intent with
1106      * {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION} set to the
1107      * downloadable subscription metadata upon success.
1108      *
1109      * <p>Requires that the calling app has the
1110      * {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. This is for
1111      * internal system use only.
1112      *
1113      * @param subscription the subscription which needs metadata filled in
1114      * @param callbackIntent a PendingIntent to launch when the operation completes.
1115      * @hide
1116      */
1117     @SystemApi
1118     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
getDownloadableSubscriptionMetadata( DownloadableSubscription subscription, PendingIntent callbackIntent)1119     public void getDownloadableSubscriptionMetadata(
1120             DownloadableSubscription subscription, PendingIntent callbackIntent) {
1121         if (!isEnabled()) {
1122             sendUnavailableError(callbackIntent);
1123             return;
1124         }
1125         try {
1126             getIEuiccController().getDownloadableSubscriptionMetadata(mCardId, subscription,
1127                     mContext.getOpPackageName(), callbackIntent);
1128         } catch (RemoteException e) {
1129             throw e.rethrowFromSystemServer();
1130         }
1131     }
1132 
1133     /**
1134      * Gets metadata for subscription which are available for download on this device.
1135      *
1136      * <p>Subscriptions returned here may be passed to {@link #downloadSubscription}. They may have
1137      * been pre-assigned to this particular device, for example. The callback will be triggered with
1138      * an Intent with {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS} set to the
1139      * list of available subscriptions upon success.
1140      *
1141      * <p>Requires that the calling app has the
1142      * {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. This is for
1143      * internal system use only.
1144      *
1145      * @param callbackIntent a PendingIntent to launch when the operation completes.
1146      * @hide
1147      */
1148     @SystemApi
1149     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
getDefaultDownloadableSubscriptionList(PendingIntent callbackIntent)1150     public void getDefaultDownloadableSubscriptionList(PendingIntent callbackIntent) {
1151         if (!isEnabled()) {
1152             sendUnavailableError(callbackIntent);
1153             return;
1154         }
1155         try {
1156             getIEuiccController().getDefaultDownloadableSubscriptionList(mCardId,
1157                     mContext.getOpPackageName(), callbackIntent);
1158         } catch (RemoteException e) {
1159             throw e.rethrowFromSystemServer();
1160         }
1161     }
1162 
1163     /**
1164      * Returns information about the eUICC chip/device.
1165      *
1166      * @return the {@link EuiccInfo}. May be null if the eUICC is not ready.
1167      */
1168     @Nullable
getEuiccInfo()1169     public EuiccInfo getEuiccInfo() {
1170         if (!isEnabled()) {
1171             return null;
1172         }
1173         try {
1174             return getIEuiccController().getEuiccInfo(mCardId);
1175         } catch (RemoteException e) {
1176             throw e.rethrowFromSystemServer();
1177         }
1178     }
1179 
1180     /**
1181      * Deletes the given subscription.
1182      *
1183      * <p>If this subscription is currently active, the device will first switch away from it onto
1184      * an "empty" subscription.
1185      *
1186      * <p>Requires that the calling app has carrier privileges according to the metadata of the
1187      * profile to be deleted, or the
1188      * {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
1189      *
1190      * @param subscriptionId the ID of the subscription to delete.
1191      * @param callbackIntent a PendingIntent to launch when the operation completes.
1192      */
1193     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
deleteSubscription(int subscriptionId, PendingIntent callbackIntent)1194     public void deleteSubscription(int subscriptionId, PendingIntent callbackIntent) {
1195         if (!isEnabled()) {
1196             sendUnavailableError(callbackIntent);
1197             return;
1198         }
1199         try {
1200             getIEuiccController().deleteSubscription(mCardId,
1201                     subscriptionId, mContext.getOpPackageName(), callbackIntent);
1202         } catch (RemoteException e) {
1203             throw e.rethrowFromSystemServer();
1204         }
1205     }
1206 
1207     /**
1208      * Switch to (enable) the given subscription.
1209      *
1210      * <p>Requires the {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission,
1211      * or the calling app must be authorized to manage both the currently-active subscription and
1212      * the subscription to be enabled according to the subscription metadata. Without the former,
1213      * an {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR} will be returned in the callback
1214      * intent to prompt the user to accept the download.
1215      *
1216      * <p>On a multi-active SIM device, requires the
1217      * {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission, or a calling app
1218      *  only if the targeted eUICC does not currently have an active subscription or the calling app
1219      * is authorized to manage the active subscription on the target eUICC, and the calling app is
1220      * authorized to manage any active subscription on any SIM. Without it, an
1221      * {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR} will be returned in the callback
1222      * intent to prompt the user to accept the download. The caller should also be authorized to
1223      * manage the subscription to be enabled.
1224      *
1225      * <p> From Android T, devices might support {@link PackageManager#FEATURE_TELEPHONY_EUICC_MEP},
1226      * the subscription can be installed on different port from the eUICC. Calling apps with
1227      * carrier privilege (see {@link TelephonyManager#hasCarrierPrivileges}) over the currently
1228      * active subscriptions can use {@link #switchToSubscription(int, int, PendingIntent)} to
1229      * specify which port to enable the subscription. Otherwise, use this API to enable the
1230      * subscription on the eUICC and the platform will internally resolve a port based on following
1231      * rules:
1232      * <ul>
1233      *    <li>always use the default port 0 is eUICC does not support MEP or the apps are
1234      *    not targeting on Android T.
1235      *    <li>In SS(Single SIM) mode, if the embedded slot already has an active port, then enable
1236      *    the subscription on this port.
1237      *    <li>In SS mode, if the embedded slot is not active, then try to enable the subscription on
1238      *    the default port 0 of eUICC.
1239      *    <li>In DSDS mode, find first available port to enable the subscription.
1240      *    (see {@link #isSimPortAvailable(int)})
1241      *</ul>
1242      * If there is no available port, an {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR}
1243      * will be returned in the callback intent to prompt the user to disable an already-active
1244      * subscription.
1245      *
1246      * @param subscriptionId the ID of the subscription to enable. May be
1247      *     {@link android.telephony.SubscriptionManager#INVALID_SUBSCRIPTION_ID} to deactivate the
1248      *     current profile without activating another profile to replace it. Calling apps targeting
1249      *     on android T must use {@link #switchToSubscription(int, int, PendingIntent)} API for
1250      *     disable profile, port index can be found from {@link SubscriptionInfo#getPortIndex()}.
1251      *     If it's a disable operation, requires the
1252      *     {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission, or the
1253      *     calling app must be authorized to manage the active subscription on the target eUICC.
1254      * @param callbackIntent a PendingIntent to launch when the operation completes.
1255      */
1256     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
switchToSubscription(int subscriptionId, PendingIntent callbackIntent)1257     public void switchToSubscription(int subscriptionId, PendingIntent callbackIntent) {
1258         if (!isEnabled()) {
1259             sendUnavailableError(callbackIntent);
1260             return;
1261         }
1262         try {
1263             if (subscriptionId == SubscriptionManager.INVALID_SUBSCRIPTION_ID
1264                      && getIEuiccController().isCompatChangeEnabled(mContext.getOpPackageName(),
1265                      SWITCH_WITHOUT_PORT_INDEX_EXCEPTION_ON_DISABLE)) {
1266                 // Apps targeting on Android T and beyond will get exception whenever
1267                 // switchToSubscription without portIndex is called with INVALID_SUBSCRIPTION_ID.
1268                 Log.e(TAG, "switchToSubscription without portIndex is not allowed for"
1269                         + " disable operation");
1270                 throw new IllegalArgumentException("Must use switchToSubscription with portIndex"
1271                         + " API for disable operation");
1272             }
1273             getIEuiccController().switchToSubscription(mCardId,
1274                     subscriptionId, mContext.getOpPackageName(), callbackIntent);
1275         } catch (RemoteException e) {
1276             throw e.rethrowFromSystemServer();
1277         }
1278     }
1279 
1280     /**
1281      * Switch to (enable) the given subscription.
1282      *
1283      * <p> Requires the {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission,
1284      * or the caller must be having both the carrier privileges
1285      * (see {@link TelephonyManager#hasCarrierPrivileges}) over any currently active subscriptions
1286      * and the subscription to be enabled according to the subscription metadata.
1287      * Without the former permissions, an SecurityException is thrown.
1288      *
1289      * <p> If the caller is passing invalid port index,
1290      * an {@link #EMBEDDED_SUBSCRIPTION_RESULT_ERROR} with detailed error code
1291      * {@link #ERROR_INVALID_PORT} will be returned. The port index is invalid if one of the
1292      * following requirements is met:
1293      * <ul>
1294      *     <li>index is beyond the range of {@link UiccCardInfo#getPorts()}.
1295      *     <li>In SS(Single SIM) mode, the embedded slot already has an active port with different
1296      *     port index.
1297      *     <li>In DSDS mode, if the psim slot is active and the embedded slot already has an active
1298      *     empty port with different port index.
1299      * </ul>
1300      *
1301      * <p> Depending on the target port and permission check,
1302      * an {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR} might be returned to the callback
1303      * intent to prompt the user to authorize before the switch.
1304      *
1305      * @param subscriptionId the ID of the subscription to enable. May be
1306      *     {@link android.telephony.SubscriptionManager#INVALID_SUBSCRIPTION_ID} to deactivate the
1307      *     current profile without activating another profile to replace it. If it's a disable
1308      *     operation, requires the {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS}
1309      *     permission, or the calling app must be authorized to manage the active subscription on
1310      *     the target eUICC. From Android T, multiple enabled profiles is supported. Calling apps
1311      *     targeting on android T must use {@link #switchToSubscription(int, int, PendingIntent)}
1312      *     API for disable profile, port index can be found from
1313      *     {@link SubscriptionInfo#getPortIndex()}.
1314      * @param portIndex the index of the port to target for the enabled subscription
1315      * @param callbackIntent a PendingIntent to launch when the operation completes.
1316      */
1317     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
switchToSubscription(int subscriptionId, int portIndex, @NonNull PendingIntent callbackIntent)1318     public void switchToSubscription(int subscriptionId, int portIndex,
1319             @NonNull PendingIntent callbackIntent) {
1320         if (!isEnabled()) {
1321             sendUnavailableError(callbackIntent);
1322             return;
1323         }
1324         try {
1325             boolean canWriteEmbeddedSubscriptions = mContext.checkCallingOrSelfPermission(
1326                     Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
1327                     == PackageManager.PERMISSION_GRANTED;
1328             // If the caller is not privileged caller and does not have the carrier privilege over
1329             // any active subscription, do not continue.
1330             if (!canWriteEmbeddedSubscriptions && !getIEuiccController()
1331                     .hasCarrierPrivilegesForPackageOnAnyPhone(mContext.getOpPackageName())) {
1332                 Log.e(TAG, "Not permitted to use switchToSubscription with portIndex");
1333                 throw new SecurityException(
1334                         "Must have carrier privileges to use switchToSubscription with portIndex");
1335             }
1336             getIEuiccController().switchToSubscriptionWithPort(mCardId,
1337                     subscriptionId, portIndex, mContext.getOpPackageName(), callbackIntent);
1338         } catch (RemoteException e) {
1339             throw e.rethrowFromSystemServer();
1340         }
1341     }
1342 
1343     /**
1344      * Update the nickname for the given subscription.
1345      *
1346      * <p>Requires that the calling app has carrier privileges according to the metadata of the
1347      * profile to be updated, or the
1348      * {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
1349      *
1350      * @param subscriptionId the ID of the subscription to update.
1351      * @param nickname the new nickname to apply.
1352      * @param callbackIntent a PendingIntent to launch when the operation completes.
1353      */
1354     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
updateSubscriptionNickname( int subscriptionId, @Nullable String nickname, @NonNull PendingIntent callbackIntent)1355     public void updateSubscriptionNickname(
1356             int subscriptionId, @Nullable String nickname, @NonNull PendingIntent callbackIntent) {
1357         if (!isEnabled()) {
1358             sendUnavailableError(callbackIntent);
1359             return;
1360         }
1361         try {
1362             getIEuiccController().updateSubscriptionNickname(mCardId,
1363                     subscriptionId, nickname, mContext.getOpPackageName(), callbackIntent);
1364         } catch (RemoteException e) {
1365             throw e.rethrowFromSystemServer();
1366         }
1367     }
1368 
1369     /**
1370      * Erase all operational subscriptions and reset the eUICC.
1371      *
1372      * <p>Requires that the calling app has the
1373      * {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
1374      *
1375      * @param callbackIntent a PendingIntent to launch when the operation completes.
1376      *
1377      * @deprecated From R, callers should specify a flag for specific set of subscriptions to erase
1378      * and use {@link #eraseSubscriptions(int, PendingIntent)} instead
1379      *
1380      * @hide
1381      */
1382     @SystemApi
1383     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
1384     @Deprecated
eraseSubscriptions(@onNull PendingIntent callbackIntent)1385     public void eraseSubscriptions(@NonNull PendingIntent callbackIntent) {
1386         if (!isEnabled()) {
1387             sendUnavailableError(callbackIntent);
1388             return;
1389         }
1390         try {
1391             getIEuiccController().eraseSubscriptions(mCardId, callbackIntent);
1392         } catch (RemoteException e) {
1393             throw e.rethrowFromSystemServer();
1394         }
1395     }
1396 
1397     /**
1398      * Erase all specific subscriptions and reset the eUICC.
1399      *
1400      * <p>Requires that the calling app has the
1401      * {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
1402      *
1403      * @param options flag indicating specific set of subscriptions to erase
1404      * @param callbackIntent a PendingIntent to launch when the operation completes.
1405      *
1406      * @hide
1407      */
1408     @SystemApi
1409     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
eraseSubscriptions( @esetOption int options, @NonNull PendingIntent callbackIntent)1410     public void eraseSubscriptions(
1411             @ResetOption int options, @NonNull PendingIntent callbackIntent) {
1412         if (!isEnabled()) {
1413             sendUnavailableError(callbackIntent);
1414             return;
1415         }
1416         try {
1417             getIEuiccController().eraseSubscriptionsWithOptions(mCardId, options, callbackIntent);
1418         } catch (RemoteException e) {
1419             throw e.rethrowFromSystemServer();
1420         }
1421     }
1422 
1423     /**
1424      * Ensure that subscriptions will be retained on the next factory reset.
1425      *
1426      * <p>By default, all subscriptions on the eUICC are erased the first time a device boots (ever
1427      * and after factory resets). This ensures that the data is wiped after a factory reset is
1428      * performed via fastboot or recovery mode, as these modes do not support the necessary radio
1429      * communication needed to wipe the eSIM.
1430      *
1431      * <p>However, this method may be called right before a factory reset issued via settings when
1432      * the user elects to retain subscriptions. Doing so will mark them for retention so that they
1433      * are not cleared after the ensuing reset.
1434      *
1435      * <p>Requires that the calling app has the {@link android.Manifest.permission#MASTER_CLEAR}
1436      * permission. This is for internal system use only.
1437      *
1438      * @param callbackIntent a PendingIntent to launch when the operation completes.
1439      * @hide
1440      */
retainSubscriptionsForFactoryReset(PendingIntent callbackIntent)1441     public void retainSubscriptionsForFactoryReset(PendingIntent callbackIntent) {
1442         if (!isEnabled()) {
1443             sendUnavailableError(callbackIntent);
1444             return;
1445         }
1446         try {
1447             getIEuiccController().retainSubscriptionsForFactoryReset(mCardId, callbackIntent);
1448         } catch (RemoteException e) {
1449             throw e.rethrowFromSystemServer();
1450         }
1451     }
1452 
1453     /**
1454      * Sets the supported countries for eUICC.
1455      *
1456      * <p>Requires that the calling app has the
1457      * {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
1458      *
1459      * <p>The supported country list will be replaced by {@code supportedCountries}. For how we
1460      * determine whether a country is supported please check {@link #isSupportedCountry}.
1461      *
1462      * @param supportedCountries is a list of strings contains country ISO codes in uppercase.
1463      * @hide
1464      */
1465     @SystemApi
1466     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
setSupportedCountries(@onNull List<String> supportedCountries)1467     public void setSupportedCountries(@NonNull List<String> supportedCountries) {
1468         if (!isEnabled()) {
1469             return;
1470         }
1471         try {
1472             getIEuiccController().setSupportedCountries(
1473                     true /* isSupported */,
1474                     supportedCountries.stream()
1475                         .map(String::toUpperCase).collect(Collectors.toList()));
1476         } catch (RemoteException e) {
1477             throw e.rethrowFromSystemServer();
1478         }
1479     }
1480 
1481     /**
1482      * Sets the unsupported countries for eUICC.
1483      *
1484      * <p>Requires that the calling app has the
1485      * {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
1486      *
1487      * <p>The unsupported country list will be replaced by {@code unsupportedCountries}. For how we
1488      * determine whether a country is supported please check {@link #isSupportedCountry}.
1489      *
1490      * @param unsupportedCountries is a list of strings contains country ISO codes in uppercase.
1491      * @hide
1492      */
1493     @SystemApi
1494     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
setUnsupportedCountries(@onNull List<String> unsupportedCountries)1495     public void setUnsupportedCountries(@NonNull List<String> unsupportedCountries) {
1496         if (!isEnabled()) {
1497             return;
1498         }
1499         try {
1500             getIEuiccController().setSupportedCountries(
1501                     false /* isSupported */,
1502                     unsupportedCountries.stream()
1503                         .map(String::toUpperCase).collect(Collectors.toList()));
1504         } catch (RemoteException e) {
1505             throw e.rethrowFromSystemServer();
1506         }
1507     }
1508 
1509     /**
1510      * Gets the supported countries for eUICC.
1511      *
1512      * <p>Requires that the calling app has the
1513      * {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
1514      *
1515      * @return list of strings contains country ISO codes in uppercase.
1516      * @hide
1517      */
1518     @SystemApi
1519     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
1520     @NonNull
getSupportedCountries()1521     public List<String> getSupportedCountries() {
1522         if (!isEnabled()) {
1523             return Collections.emptyList();
1524         }
1525         try {
1526             return getIEuiccController().getSupportedCountries(true /* isSupported */);
1527         } catch (RemoteException e) {
1528             throw e.rethrowFromSystemServer();
1529         }
1530     }
1531 
1532     /**
1533      * Gets the unsupported countries for eUICC.
1534      *
1535      * <p>Requires that the calling app has the
1536      * {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
1537      *
1538      * @return list of strings contains country ISO codes in uppercase.
1539      * @hide
1540      */
1541     @SystemApi
1542     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
1543     @NonNull
getUnsupportedCountries()1544     public List<String> getUnsupportedCountries() {
1545         if (!isEnabled()) {
1546             return Collections.emptyList();
1547         }
1548         try {
1549             return getIEuiccController().getSupportedCountries(false /* isSupported */);
1550         } catch (RemoteException e) {
1551             throw e.rethrowFromSystemServer();
1552         }
1553     }
1554 
1555     /**
1556      * Returns whether the given country supports eUICC.
1557      *
1558      * <p>Supported country list has a higher prority than unsupported country list. If the
1559      * supported country list is not empty, {@code countryIso} will be considered as supported when
1560      * it exists in the supported country list. Otherwise {@code countryIso} is not supported. If
1561      * the supported country list is empty, {@code countryIso} will be considered as supported if it
1562      * does not exist in the unsupported country list. Otherwise {@code countryIso} is not
1563      * supported. If both supported and unsupported country lists are empty, then all countries are
1564      * consider be supported. For how to set supported and unsupported country list, please check
1565      * {@link #setSupportedCountries} and {@link #setUnsupportedCountries}.
1566      *
1567      * @param countryIso should be the ISO-3166 country code is provided in uppercase 2 character
1568      * format.
1569      * @return whether the given country supports eUICC or not.
1570      * @hide
1571      */
1572     @SystemApi
1573     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
isSupportedCountry(@onNull String countryIso)1574     public boolean isSupportedCountry(@NonNull String countryIso) {
1575         if (!isEnabled()) {
1576             return false;
1577         }
1578         try {
1579             return getIEuiccController().isSupportedCountry(countryIso.toUpperCase(Locale.ROOT));
1580         } catch (RemoteException e) {
1581             throw e.rethrowFromSystemServer();
1582         }
1583     }
1584 
1585     /**
1586      * Refreshes the cardId if its uninitialized, and returns whether we should continue the
1587      * operation.
1588      * <p>
1589      * Note that after a successful refresh, the mCardId may be TelephonyManager.UNSUPPORTED_CARD_ID
1590      * on older HALs. For backwards compatability, we continue to the LPA and let it decide which
1591      * card to use.
1592      */
refreshCardIdIfUninitialized()1593     private boolean refreshCardIdIfUninitialized() {
1594         // Refresh mCardId if its UNINITIALIZED_CARD_ID
1595         if (mCardId == TelephonyManager.UNINITIALIZED_CARD_ID) {
1596             TelephonyManager tm = (TelephonyManager)
1597                     mContext.getSystemService(Context.TELEPHONY_SERVICE);
1598             mCardId = tm.getCardIdForDefaultEuicc();
1599         }
1600         if (mCardId == TelephonyManager.UNINITIALIZED_CARD_ID) {
1601             return false;
1602         }
1603         return true;
1604     }
1605 
sendUnavailableError(PendingIntent callbackIntent)1606     private static void sendUnavailableError(PendingIntent callbackIntent) {
1607         try {
1608             callbackIntent.send(EMBEDDED_SUBSCRIPTION_RESULT_ERROR);
1609         } catch (PendingIntent.CanceledException e) {
1610             // Caller canceled the callback; do nothing.
1611         }
1612     }
1613 
getIEuiccController()1614     private static IEuiccController getIEuiccController() {
1615         return IEuiccController.Stub.asInterface(
1616                 TelephonyFrameworkInitializer
1617                         .getTelephonyServiceManager()
1618                         .getEuiccControllerService()
1619                         .get());
1620     }
1621 
1622     /**
1623      * Returns whether the passing portIndex is available.
1624      * A port is available if it is active without enabled profile on it or
1625      * calling app has carrier privilege over the profile installed on the selected port.
1626      *
1627      * <p> From Android U, a port is available if it is active without an enabled profile on it or
1628      * calling app can activate a new profile on the selected port without any user interaction.
1629      *
1630      * Always returns false if the cardId is a physical card.
1631      *
1632      * @param portIndex is an enumeration of the ports available on the UICC.
1633      * @return {@code true} if port is available
1634      */
isSimPortAvailable(int portIndex)1635     public boolean isSimPortAvailable(int portIndex) {
1636         try {
1637             return getIEuiccController().isSimPortAvailable(mCardId, portIndex,
1638                     mContext.getOpPackageName());
1639         } catch (RemoteException e) {
1640             throw e.rethrowFromSystemServer();
1641         }
1642     }
1643 }
1644