Home | History | Annotate | Download | only in euicc
      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.Nullable;
     21 import android.annotation.RequiresPermission;
     22 import android.annotation.SdkConstant;
     23 import android.annotation.SystemApi;
     24 import android.app.Activity;
     25 import android.app.PendingIntent;
     26 import android.content.Context;
     27 import android.content.Intent;
     28 import android.content.IntentSender;
     29 import android.content.pm.PackageManager;
     30 import android.os.Bundle;
     31 import android.os.RemoteException;
     32 import android.os.ServiceManager;
     33 
     34 import com.android.internal.telephony.euicc.IEuiccController;
     35 
     36 import java.lang.annotation.Retention;
     37 import java.lang.annotation.RetentionPolicy;
     38 
     39 /**
     40  * EuiccManager is the application interface to eUICCs, or eSIMs/embedded SIMs.
     41  *
     42  * <p>You do not instantiate this class directly; instead, you retrieve an instance through
     43  * {@link Context#getSystemService(String)} and {@link Context#EUICC_SERVICE}.
     44  *
     45  * <p>See {@link #isEnabled} before attempting to use these APIs.
     46  */
     47 public class EuiccManager {
     48 
     49     /**
     50      * Intent action to launch the embedded SIM (eUICC) management settings screen.
     51      *
     52      * <p>This screen shows a list of embedded profiles and offers the user the ability to switch
     53      * between them, download new profiles, and delete unused profiles.
     54      *
     55      * <p>The activity will immediately finish with {@link android.app.Activity#RESULT_CANCELED} if
     56      * {@link #isEnabled} is false.
     57      *
     58      * This is ued by non-LPA app to bring up LUI.
     59      */
     60     @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
     61     public static final String ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS =
     62             "android.telephony.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS";
     63 
     64 
     65     /**
     66      * Broadcast Action: The eUICC OTA status is changed.
     67      * <p class="note">
     68      * Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
     69      *
     70      * <p class="note">This is a protected intent that can only be sent
     71      * by the system.
     72      *
     73      * @hide
     74      */
     75     @SystemApi
     76     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
     77     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
     78     public static final String ACTION_OTA_STATUS_CHANGED =
     79             "android.telephony.euicc.action.OTA_STATUS_CHANGED";
     80 
     81     /**
     82      * Broadcast Action: The action sent to carrier app so it knows the carrier setup is not
     83      * completed.
     84      */
     85     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
     86     public static final String ACTION_NOTIFY_CARRIER_SETUP_INCOMPLETE =
     87             "android.telephony.euicc.action.NOTIFY_CARRIER_SETUP_INCOMPLETE";
     88 
     89     /**
     90      * Intent action to provision an embedded subscription.
     91      *
     92      * <p>May be called during device provisioning to launch a screen to perform embedded SIM
     93      * provisioning, e.g. if no physical SIM is present and the user elects to configure their
     94      * embedded SIM.
     95      *
     96      * <p>The activity will immediately finish with {@link android.app.Activity#RESULT_CANCELED} if
     97      * {@link #isEnabled} is false.
     98      *
     99      * @hide
    100      */
    101     @SystemApi
    102     @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
    103     public static final String ACTION_PROVISION_EMBEDDED_SUBSCRIPTION =
    104             "android.telephony.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION";
    105 
    106     /**
    107      * Intent action to handle a resolvable error.
    108      * @hide
    109      */
    110     public static final String ACTION_RESOLVE_ERROR =
    111             "android.telephony.euicc.action.RESOLVE_ERROR";
    112 
    113     /**
    114      * Result code for an operation indicating that the operation succeeded.
    115      */
    116     public static final int EMBEDDED_SUBSCRIPTION_RESULT_OK = 0;
    117 
    118     /**
    119      * Result code for an operation indicating that the user must take some action before the
    120      * operation can continue.
    121      *
    122      * @see #startResolutionActivity
    123      */
    124     public static final int EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR = 1;
    125 
    126     /**
    127      * Result code for an operation indicating that an unresolvable error occurred.
    128      *
    129      * {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} will be populated with a detailed error
    130      * code for logging/debugging purposes only.
    131      */
    132     public static final int EMBEDDED_SUBSCRIPTION_RESULT_ERROR = 2;
    133 
    134     /**
    135      * Key for an extra set on {@link PendingIntent} result callbacks providing a detailed result
    136      * code.
    137      *
    138      * <p>This code is an implementation detail of the embedded subscription manager and is only
    139      * intended for logging or debugging purposes.
    140      */
    141     public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE =
    142             "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DETAILED_CODE";
    143 
    144     /**
    145      * Key for an extra set on {@code #getDownloadableSubscriptionMetadata} PendingIntent result
    146      * callbacks providing the downloadable subscription metadata.
    147      */
    148     public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION =
    149             "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION";
    150 
    151     /**
    152      * Key for an extra set on {@link #getDefaultDownloadableSubscriptionList} PendingIntent result
    153      * callbacks providing the list of available downloadable subscriptions.
    154      * @hide
    155      */
    156     @SystemApi
    157     public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS =
    158             "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS";
    159 
    160     /**
    161      * Key for an extra set on {@link PendingIntent} result callbacks providing the resolution
    162      * pending intent for {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR}s.
    163      * @hide
    164      */
    165     public static final String EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT =
    166             "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT";
    167 
    168     /**
    169      * Key for an extra set on the {@link #EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT} intent
    170      * containing the EuiccService action to launch for resolution.
    171      * @hide
    172      */
    173     public static final String EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_ACTION =
    174             "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_RESOLUTION_ACTION";
    175 
    176     /**
    177      * Key for an extra set on the {@link #EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT} intent
    178      * providing the callback to execute after resolution is completed.
    179      * @hide
    180      */
    181     public static final String EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT =
    182             "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT";
    183 
    184     /**
    185      * Key for an extra set on the {@link #ACTION_PROVISION_EMBEDDED_SUBSCRIPTION} intent for
    186      * whether the user choses to use eUICC to set up network in SUW.
    187      * @hide
    188      */
    189     public static final String EXTRA_FORCE_PROVISION =
    190             "android.telephony.euicc.extra.FORCE_PROVISION";
    191 
    192     /**
    193      * Optional meta-data attribute for a carrier app providing an icon to use to represent the
    194      * carrier. If not provided, the app's launcher icon will be used as a fallback.
    195      */
    196     public static final String META_DATA_CARRIER_ICON = "android.telephony.euicc.carriericon";
    197 
    198     /**
    199      * Euicc OTA update status which can be got by {@link #getOtaStatus}
    200      * @hide
    201      */
    202     @SystemApi
    203     @Retention(RetentionPolicy.SOURCE)
    204     @IntDef(prefix = {"EUICC_OTA_"}, value = {
    205             EUICC_OTA_IN_PROGRESS,
    206             EUICC_OTA_FAILED,
    207             EUICC_OTA_SUCCEEDED,
    208             EUICC_OTA_NOT_NEEDED,
    209             EUICC_OTA_STATUS_UNAVAILABLE
    210 
    211     })
    212     public @interface OtaStatus{}
    213 
    214     /**
    215      * An OTA is in progress. During this time, the eUICC is not available and the user may lose
    216      * network access.
    217      * @hide
    218      */
    219     @SystemApi
    220     public static final int EUICC_OTA_IN_PROGRESS = 1;
    221 
    222     /**
    223      * The OTA update failed.
    224      * @hide
    225      */
    226     @SystemApi
    227     public static final int EUICC_OTA_FAILED = 2;
    228 
    229     /**
    230      * The OTA update finished successfully.
    231      * @hide
    232      */
    233     @SystemApi
    234     public static final int EUICC_OTA_SUCCEEDED = 3;
    235 
    236     /**
    237      * The OTA update not needed since current eUICC OS is latest.
    238      * @hide
    239      */
    240     @SystemApi
    241     public static final int EUICC_OTA_NOT_NEEDED = 4;
    242 
    243     /**
    244      * The OTA status is unavailable since eUICC service is unavailable.
    245      * @hide
    246      */
    247     @SystemApi
    248     public static final int EUICC_OTA_STATUS_UNAVAILABLE = 5;
    249 
    250     private final Context mContext;
    251 
    252     /** @hide */
    253     public EuiccManager(Context context) {
    254         mContext = context;
    255     }
    256 
    257     /**
    258      * Whether embedded subscriptions are currently enabled.
    259      *
    260      * <p>Even on devices with the {@link PackageManager#FEATURE_TELEPHONY_EUICC} feature, embedded
    261      * subscriptions may be turned off, e.g. because of a carrier restriction from an inserted
    262      * physical SIM. Therefore, this runtime check should be used before accessing embedded
    263      * subscription APIs.
    264      *
    265      * @return true if embedded subscriptions are currently enabled.
    266      */
    267     public boolean isEnabled() {
    268         // In the future, this may reach out to IEuiccController (if non-null) to check any dynamic
    269         // restrictions.
    270         return getIEuiccController() != null;
    271     }
    272 
    273     /**
    274      * Returns the EID identifying the eUICC hardware.
    275      *
    276      * <p>Requires that the calling app has carrier privileges on the active subscription on the
    277      * eUICC.
    278      *
    279      * @return the EID. May be null if {@link #isEnabled()} is false or the eUICC is not ready.
    280      */
    281     @Nullable
    282     public String getEid() {
    283         if (!isEnabled()) {
    284             return null;
    285         }
    286         try {
    287             return getIEuiccController().getEid();
    288         } catch (RemoteException e) {
    289             throw e.rethrowFromSystemServer();
    290         }
    291     }
    292 
    293     /**
    294      * Returns the current status of eUICC OTA.
    295      *
    296      * <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
    297      *
    298      * @return the status of eUICC OTA. If {@link #isEnabled()} is false or the eUICC is not ready,
    299      *     {@link OtaStatus#EUICC_OTA_STATUS_UNAVAILABLE} will be returned.
    300      *
    301      * @hide
    302      */
    303     @SystemApi
    304     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
    305     public int getOtaStatus() {
    306         if (!isEnabled()) {
    307             return EUICC_OTA_STATUS_UNAVAILABLE;
    308         }
    309         try {
    310             return getIEuiccController().getOtaStatus();
    311         } catch (RemoteException e) {
    312             throw e.rethrowFromSystemServer();
    313         }
    314     }
    315 
    316     /**
    317      * Attempt to download the given {@link DownloadableSubscription}.
    318      *
    319      * <p>Requires the {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission,
    320      * or the calling app must be authorized to manage both the currently-active subscription and
    321      * the subscription to be downloaded according to the subscription metadata. Without the former,
    322      * an {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR} will be returned in the callback
    323      * intent to prompt the user to accept the download.
    324      *
    325      * @param subscription the subscription to download.
    326      * @param switchAfterDownload if true, the profile will be activated upon successful download.
    327      * @param callbackIntent a PendingIntent to launch when the operation completes.
    328      */
    329     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
    330     public void downloadSubscription(DownloadableSubscription subscription,
    331             boolean switchAfterDownload, PendingIntent callbackIntent) {
    332         if (!isEnabled()) {
    333             sendUnavailableError(callbackIntent);
    334             return;
    335         }
    336         try {
    337             getIEuiccController().downloadSubscription(subscription, switchAfterDownload,
    338                     mContext.getOpPackageName(), callbackIntent);
    339         } catch (RemoteException e) {
    340             throw e.rethrowFromSystemServer();
    341         }
    342     }
    343 
    344     /**
    345      * Start an activity to resolve a user-resolvable error.
    346      *
    347      * <p>If an operation returns {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR}, this
    348      * method may be called to prompt the user to resolve the issue.
    349      *
    350      * <p>This method may only be called once for a particular error.
    351      *
    352      * @param activity the calling activity (which should be in the foreground).
    353      * @param requestCode an application-specific request code which will be provided to
    354      *     {@link Activity#onActivityResult} upon completion. Note that the operation may still be
    355      *     in progress when the resolution activity completes; it is not fully finished until the
    356      *     callback intent is triggered.
    357      * @param resultIntent the Intent provided to the initial callback intent which failed with
    358      *     {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR}.
    359      * @param callbackIntent a PendingIntent to launch when the operation completes. This is
    360      *     trigered upon completion of the original operation that required user resolution.
    361      * @throws android.content.IntentSender.SendIntentException if called more than once.
    362      */
    363     public void startResolutionActivity(Activity activity, int requestCode, Intent resultIntent,
    364             PendingIntent callbackIntent) throws IntentSender.SendIntentException {
    365         PendingIntent resolutionIntent =
    366                 resultIntent.getParcelableExtra(EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT);
    367         if (resolutionIntent == null) {
    368             throw new IllegalArgumentException("Invalid result intent");
    369         }
    370         Intent fillInIntent = new Intent();
    371         fillInIntent.putExtra(EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT,
    372                 callbackIntent);
    373         activity.startIntentSenderForResult(resolutionIntent.getIntentSender(), requestCode,
    374                 fillInIntent, 0 /* flagsMask */, 0 /* flagsValues */, 0 /* extraFlags */);
    375     }
    376 
    377     /**
    378      * Continue an operation after the user resolves an error.
    379      *
    380      * <p>To be called by the LUI upon completion of a resolvable error flow.
    381      *
    382      * <p>Requires that the calling app has the
    383      * {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
    384      *
    385      * @param resolutionIntent The original intent used to start the LUI.
    386      * @param resolutionExtras Resolution-specific extras depending on the result of the resolution.
    387      *     For example, this may indicate whether the user has consented or may include the input
    388      *     they provided.
    389      * @hide
    390      */
    391     @SystemApi
    392     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
    393     public void continueOperation(Intent resolutionIntent, Bundle resolutionExtras) {
    394         if (!isEnabled()) {
    395             PendingIntent callbackIntent =
    396                     resolutionIntent.getParcelableExtra(
    397                             EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT);
    398             if (callbackIntent != null) {
    399                 sendUnavailableError(callbackIntent);
    400             }
    401             return;
    402         }
    403         try {
    404             getIEuiccController().continueOperation(resolutionIntent, resolutionExtras);
    405         } catch (RemoteException e) {
    406             throw e.rethrowFromSystemServer();
    407         }
    408     }
    409 
    410     /**
    411      * Fills in the metadata for a DownloadableSubscription.
    412      *
    413      * <p>May be used in cases that a DownloadableSubscription was constructed to download a
    414      * profile, but the metadata for the profile is unknown (e.g. we only know the activation code).
    415      * The callback will be triggered with an Intent with
    416      * {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION} set to the
    417      * downloadable subscription metadata upon success.
    418      *
    419      * <p>Requires that the calling app has the
    420      * {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. This is for
    421      * internal system use only.
    422      *
    423      * @param subscription the subscription which needs metadata filled in
    424      * @param callbackIntent a PendingIntent to launch when the operation completes.
    425      * @hide
    426      */
    427     @SystemApi
    428     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
    429     public void getDownloadableSubscriptionMetadata(
    430             DownloadableSubscription subscription, PendingIntent callbackIntent) {
    431         if (!isEnabled()) {
    432             sendUnavailableError(callbackIntent);
    433             return;
    434         }
    435         try {
    436             getIEuiccController().getDownloadableSubscriptionMetadata(
    437                     subscription, mContext.getOpPackageName(), callbackIntent);
    438         } catch (RemoteException e) {
    439             throw e.rethrowFromSystemServer();
    440         }
    441     }
    442 
    443     /**
    444      * Gets metadata for subscription which are available for download on this device.
    445      *
    446      * <p>Subscriptions returned here may be passed to {@link #downloadSubscription}. They may have
    447      * been pre-assigned to this particular device, for example. The callback will be triggered with
    448      * an Intent with {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS} set to the
    449      * list of available subscriptions upon success.
    450      *
    451      * <p>Requires that the calling app has the
    452      * {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. This is for
    453      * internal system use only.
    454      *
    455      * @param callbackIntent a PendingIntent to launch when the operation completes.
    456      * @hide
    457      */
    458     @SystemApi
    459     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
    460     public void getDefaultDownloadableSubscriptionList(PendingIntent callbackIntent) {
    461         if (!isEnabled()) {
    462             sendUnavailableError(callbackIntent);
    463             return;
    464         }
    465         try {
    466             getIEuiccController().getDefaultDownloadableSubscriptionList(
    467                     mContext.getOpPackageName(), callbackIntent);
    468         } catch (RemoteException e) {
    469             throw e.rethrowFromSystemServer();
    470         }
    471     }
    472 
    473     /**
    474      * Returns information about the eUICC chip/device.
    475      *
    476      * @return the {@link EuiccInfo}. May be null if {@link #isEnabled()} is false or the eUICC is
    477      *     not ready.
    478      */
    479     @Nullable
    480     public EuiccInfo getEuiccInfo() {
    481         if (!isEnabled()) {
    482             return null;
    483         }
    484         try {
    485             return getIEuiccController().getEuiccInfo();
    486         } catch (RemoteException e) {
    487             throw e.rethrowFromSystemServer();
    488         }
    489     }
    490 
    491     /**
    492      * Deletes the given subscription.
    493      *
    494      * <p>If this subscription is currently active, the device will first switch away from it onto
    495      * an "empty" subscription.
    496      *
    497      * <p>Requires that the calling app has carrier privileges according to the metadata of the
    498      * profile to be deleted, or the
    499      * {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
    500      *
    501      * @param subscriptionId the ID of the subscription to delete.
    502      * @param callbackIntent a PendingIntent to launch when the operation completes.
    503      */
    504     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
    505     public void deleteSubscription(int subscriptionId, PendingIntent callbackIntent) {
    506         if (!isEnabled()) {
    507             sendUnavailableError(callbackIntent);
    508             return;
    509         }
    510         try {
    511             getIEuiccController().deleteSubscription(
    512                     subscriptionId, mContext.getOpPackageName(), callbackIntent);
    513         } catch (RemoteException e) {
    514             throw e.rethrowFromSystemServer();
    515         }
    516     }
    517 
    518     /**
    519      * Switch to (enable) the given subscription.
    520      *
    521      * <p>Requires the {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission,
    522      * or the calling app must be authorized to manage both the currently-active subscription and
    523      * the subscription to be enabled according to the subscription metadata. Without the former,
    524      * an {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR} will be returned in the callback
    525      * intent to prompt the user to accept the download.
    526      *
    527      * @param subscriptionId the ID of the subscription to enable. May be
    528      *     {@link android.telephony.SubscriptionManager#INVALID_SUBSCRIPTION_ID} to deactivate the
    529      *     current profile without activating another profile to replace it.
    530      * @param callbackIntent a PendingIntent to launch when the operation completes.
    531      */
    532     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
    533     public void switchToSubscription(int subscriptionId, PendingIntent callbackIntent) {
    534         if (!isEnabled()) {
    535             sendUnavailableError(callbackIntent);
    536             return;
    537         }
    538         try {
    539             getIEuiccController().switchToSubscription(
    540                     subscriptionId, mContext.getOpPackageName(), callbackIntent);
    541         } catch (RemoteException e) {
    542             throw e.rethrowFromSystemServer();
    543         }
    544     }
    545 
    546     /**
    547      * Update the nickname for the given subscription.
    548      *
    549      * <p>Requires that the calling app has the
    550      * {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. This is for
    551      * internal system use only.
    552      *
    553      * @param subscriptionId the ID of the subscription to update.
    554      * @param nickname the new nickname to apply.
    555      * @param callbackIntent a PendingIntent to launch when the operation completes.
    556      * @hide
    557      */
    558     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
    559     public void updateSubscriptionNickname(
    560             int subscriptionId, String nickname, PendingIntent callbackIntent) {
    561         if (!isEnabled()) {
    562             sendUnavailableError(callbackIntent);
    563             return;
    564         }
    565         try {
    566             getIEuiccController().updateSubscriptionNickname(
    567                     subscriptionId, nickname, callbackIntent);
    568         } catch (RemoteException e) {
    569             throw e.rethrowFromSystemServer();
    570         }
    571     }
    572 
    573     /**
    574      * Erase all subscriptions and reset the eUICC.
    575      *
    576      * <p>Requires that the calling app has the
    577      * {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
    578      *
    579      * @param callbackIntent a PendingIntent to launch when the operation completes.
    580      * @hide
    581      */
    582     @SystemApi
    583     @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
    584     public void eraseSubscriptions(PendingIntent callbackIntent) {
    585         if (!isEnabled()) {
    586             sendUnavailableError(callbackIntent);
    587             return;
    588         }
    589         try {
    590             getIEuiccController().eraseSubscriptions(callbackIntent);
    591         } catch (RemoteException e) {
    592             throw e.rethrowFromSystemServer();
    593         }
    594     }
    595 
    596     /**
    597      * Ensure that subscriptions will be retained on the next factory reset.
    598      *
    599      * <p>By default, all subscriptions on the eUICC are erased the first time a device boots (ever
    600      * and after factory resets). This ensures that the data is wiped after a factory reset is
    601      * performed via fastboot or recovery mode, as these modes do not support the necessary radio
    602      * communication needed to wipe the eSIM.
    603      *
    604      * <p>However, this method may be called right before a factory reset issued via settings when
    605      * the user elects to retain subscriptions. Doing so will mark them for retention so that they
    606      * are not cleared after the ensuing reset.
    607      *
    608      * <p>Requires that the calling app has the {@link android.Manifest.permission#MASTER_CLEAR}
    609      * permission. This is for internal system use only.
    610      *
    611      * @param callbackIntent a PendingIntent to launch when the operation completes.
    612      * @hide
    613      */
    614     public void retainSubscriptionsForFactoryReset(PendingIntent callbackIntent) {
    615         if (!isEnabled()) {
    616             sendUnavailableError(callbackIntent);
    617             return;
    618         }
    619         try {
    620             getIEuiccController().retainSubscriptionsForFactoryReset(callbackIntent);
    621         } catch (RemoteException e) {
    622             throw e.rethrowFromSystemServer();
    623         }
    624     }
    625 
    626     private static void sendUnavailableError(PendingIntent callbackIntent) {
    627         try {
    628             callbackIntent.send(EMBEDDED_SUBSCRIPTION_RESULT_ERROR);
    629         } catch (PendingIntent.CanceledException e) {
    630             // Caller canceled the callback; do nothing.
    631         }
    632     }
    633 
    634     private static IEuiccController getIEuiccController() {
    635         return IEuiccController.Stub.asInterface(ServiceManager.getService("econtroller"));
    636     }
    637 }
    638