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