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