Home | History | Annotate | Download | only in euicc
      1 /*
      2  * Copyright (C) 2018 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.annotation.IntDef;
     19 import android.annotation.Nullable;
     20 import android.annotation.SystemApi;
     21 import android.content.Context;
     22 import android.os.RemoteException;
     23 import android.os.ServiceManager;
     24 import android.service.euicc.EuiccProfileInfo;
     25 import android.util.Log;
     26 
     27 import com.android.internal.telephony.euicc.IAuthenticateServerCallback;
     28 import com.android.internal.telephony.euicc.ICancelSessionCallback;
     29 import com.android.internal.telephony.euicc.IDeleteProfileCallback;
     30 import com.android.internal.telephony.euicc.IDisableProfileCallback;
     31 import com.android.internal.telephony.euicc.IEuiccCardController;
     32 import com.android.internal.telephony.euicc.IGetAllProfilesCallback;
     33 import com.android.internal.telephony.euicc.IGetDefaultSmdpAddressCallback;
     34 import com.android.internal.telephony.euicc.IGetEuiccChallengeCallback;
     35 import com.android.internal.telephony.euicc.IGetEuiccInfo1Callback;
     36 import com.android.internal.telephony.euicc.IGetEuiccInfo2Callback;
     37 import com.android.internal.telephony.euicc.IGetProfileCallback;
     38 import com.android.internal.telephony.euicc.IGetRulesAuthTableCallback;
     39 import com.android.internal.telephony.euicc.IGetSmdsAddressCallback;
     40 import com.android.internal.telephony.euicc.IListNotificationsCallback;
     41 import com.android.internal.telephony.euicc.ILoadBoundProfilePackageCallback;
     42 import com.android.internal.telephony.euicc.IPrepareDownloadCallback;
     43 import com.android.internal.telephony.euicc.IRemoveNotificationFromListCallback;
     44 import com.android.internal.telephony.euicc.IResetMemoryCallback;
     45 import com.android.internal.telephony.euicc.IRetrieveNotificationCallback;
     46 import com.android.internal.telephony.euicc.IRetrieveNotificationListCallback;
     47 import com.android.internal.telephony.euicc.ISetDefaultSmdpAddressCallback;
     48 import com.android.internal.telephony.euicc.ISetNicknameCallback;
     49 import com.android.internal.telephony.euicc.ISwitchToProfileCallback;
     50 
     51 import java.lang.annotation.Retention;
     52 import java.lang.annotation.RetentionPolicy;
     53 import android.annotation.CallbackExecutor;
     54 import java.util.concurrent.Executor;
     55 
     56 /**
     57  * EuiccCardManager is the application interface to an eSIM card.
     58  * @hide
     59  */
     60 @SystemApi
     61 public class EuiccCardManager {
     62     private static final String TAG = "EuiccCardManager";
     63 
     64     /** Reason for canceling a profile download session */
     65     @Retention(RetentionPolicy.SOURCE)
     66     @IntDef(prefix = { "CANCEL_REASON_" }, value = {
     67             CANCEL_REASON_END_USER_REJECTED,
     68             CANCEL_REASON_POSTPONED,
     69             CANCEL_REASON_TIMEOUT,
     70             CANCEL_REASON_PPR_NOT_ALLOWED
     71     })
     72     /** @hide */
     73     public @interface CancelReason {}
     74 
     75     /**
     76      * The end user has rejected the download. The profile will be put into the error state and
     77      * cannot be downloaded again without the operator's change.
     78      */
     79     public static final int CANCEL_REASON_END_USER_REJECTED = 0;
     80 
     81     /** The download has been postponed and can be restarted later. */
     82     public static final int CANCEL_REASON_POSTPONED = 1;
     83 
     84     /** The download has been timed out and can be restarted later. */
     85     public static final int CANCEL_REASON_TIMEOUT = 2;
     86 
     87     /**
     88      * The profile to be downloaded cannot be installed due to its policy rule is not allowed by
     89      * the RAT (Rules Authorisation Table) on the eUICC or by other installed profiles. The
     90      * download can be restarted later.
     91      */
     92     public static final int CANCEL_REASON_PPR_NOT_ALLOWED = 3;
     93 
     94     /** Options for resetting eUICC memory */
     95     @Retention(RetentionPolicy.SOURCE)
     96     @IntDef(flag = true, prefix = { "RESET_OPTION_" }, value = {
     97             RESET_OPTION_DELETE_OPERATIONAL_PROFILES,
     98             RESET_OPTION_DELETE_FIELD_LOADED_TEST_PROFILES,
     99             RESET_OPTION_RESET_DEFAULT_SMDP_ADDRESS
    100     })
    101     /** @hide */
    102     public @interface ResetOption {}
    103 
    104     /** Deletes all operational profiles. */
    105     public static final int RESET_OPTION_DELETE_OPERATIONAL_PROFILES = 1;
    106 
    107     /** Deletes all field-loaded testing profiles. */
    108     public static final int RESET_OPTION_DELETE_FIELD_LOADED_TEST_PROFILES = 1 << 1;
    109 
    110     /** Resets the default SM-DP+ address. */
    111     public static final int RESET_OPTION_RESET_DEFAULT_SMDP_ADDRESS = 1 << 2;
    112 
    113     /** Result code of execution with no error. */
    114     public static final int RESULT_OK = 0;
    115 
    116     /** Result code of an unknown error. */
    117     public static final int RESULT_UNKNOWN_ERROR = -1;
    118 
    119     /** Result code when the eUICC card with the given card Id is not found. */
    120     public static final int RESULT_EUICC_NOT_FOUND = -2;
    121 
    122     /**
    123      * Callback to receive the result of an eUICC card API.
    124      *
    125      * @param <T> Type of the result.
    126      */
    127     public interface ResultCallback<T> {
    128         /**
    129          * This method will be called when an eUICC card API call is completed.
    130          *
    131          * @param resultCode This can be {@link #RESULT_OK} or other positive values returned by the
    132          *     eUICC.
    133          * @param result The result object. It can be null if the {@code resultCode} is not
    134          *     {@link #RESULT_OK}.
    135          */
    136         void onComplete(int resultCode, T result);
    137     }
    138 
    139     private final Context mContext;
    140 
    141     /** @hide */
    142     public EuiccCardManager(Context context) {
    143         mContext = context;
    144     }
    145 
    146     private IEuiccCardController getIEuiccCardController() {
    147         return IEuiccCardController.Stub.asInterface(
    148                 ServiceManager.getService("euicc_card_controller"));
    149     }
    150 
    151     /**
    152      * Requests all the profiles on eUicc.
    153      *
    154      * @param cardId The Id of the eUICC.
    155      * @param executor The executor through which the callback should be invode.
    156      * @param callback The callback to get the result code and all the profiles.
    157      */
    158     public void requestAllProfiles(String cardId, @CallbackExecutor Executor executor,
    159             ResultCallback<EuiccProfileInfo[]> callback) {
    160         try {
    161             getIEuiccCardController().getAllProfiles(mContext.getOpPackageName(), cardId,
    162                     new IGetAllProfilesCallback.Stub() {
    163                         @Override
    164                         public void onComplete(int resultCode, EuiccProfileInfo[] profiles) {
    165                             executor.execute(() -> callback.onComplete(resultCode, profiles));
    166                         }
    167                     });
    168         } catch (RemoteException e) {
    169             Log.e(TAG, "Error calling getAllProfiles", e);
    170             throw e.rethrowFromSystemServer();
    171         }
    172     }
    173 
    174     /**
    175      * Requests the profile of the given iccid.
    176      *
    177      * @param cardId The Id of the eUICC.
    178      * @param iccid The iccid of the profile.
    179      * @param executor The executor through which the callback should be invode.
    180      * @param callback The callback to get the result code and profile.
    181      */
    182     public void requestProfile(String cardId, String iccid, @CallbackExecutor Executor executor,
    183             ResultCallback<EuiccProfileInfo> callback) {
    184         try {
    185             getIEuiccCardController().getProfile(mContext.getOpPackageName(), cardId, iccid,
    186                     new IGetProfileCallback.Stub() {
    187                         @Override
    188                         public void onComplete(int resultCode, EuiccProfileInfo profile) {
    189                             executor.execute(() -> callback.onComplete(resultCode, profile));
    190                         }
    191                     });
    192         } catch (RemoteException e) {
    193             Log.e(TAG, "Error calling getProfile", e);
    194             throw e.rethrowFromSystemServer();
    195         }
    196     }
    197 
    198     /**
    199      * Disables the profile of the given iccid.
    200      *
    201      * @param cardId The Id of the eUICC.
    202      * @param iccid The iccid of the profile.
    203      * @param refresh Whether sending the REFRESH command to modem.
    204      * @param executor The executor through which the callback should be invode.
    205      * @param callback The callback to get the result code.
    206      */
    207     public void disableProfile(String cardId, String iccid, boolean refresh,
    208             @CallbackExecutor Executor executor, ResultCallback<Void> callback) {
    209         try {
    210             getIEuiccCardController().disableProfile(mContext.getOpPackageName(), cardId, iccid,
    211                     refresh, new IDisableProfileCallback.Stub() {
    212                         @Override
    213                         public void onComplete(int resultCode) {
    214                             executor.execute(() -> callback.onComplete(resultCode, null));
    215                         }
    216                     });
    217         } catch (RemoteException e) {
    218             Log.e(TAG, "Error calling disableProfile", e);
    219             throw e.rethrowFromSystemServer();
    220         }
    221     }
    222 
    223     /**
    224      * Switches from the current profile to another profile. The current profile will be disabled
    225      * and the specified profile will be enabled.
    226      *
    227      * @param cardId The Id of the eUICC.
    228      * @param iccid The iccid of the profile to switch to.
    229      * @param refresh Whether sending the REFRESH command to modem.
    230      * @param executor The executor through which the callback should be invode.
    231      * @param callback The callback to get the result code and the EuiccProfileInfo enabled.
    232      */
    233     public void switchToProfile(String cardId, String iccid, boolean refresh,
    234             @CallbackExecutor Executor executor, ResultCallback<EuiccProfileInfo> callback) {
    235         try {
    236             getIEuiccCardController().switchToProfile(mContext.getOpPackageName(), cardId, iccid,
    237                     refresh, new ISwitchToProfileCallback.Stub() {
    238                         @Override
    239                         public void onComplete(int resultCode, EuiccProfileInfo profile) {
    240                             executor.execute(() -> callback.onComplete(resultCode, profile));
    241                         }
    242                     });
    243         } catch (RemoteException e) {
    244             Log.e(TAG, "Error calling switchToProfile", e);
    245             throw e.rethrowFromSystemServer();
    246         }
    247     }
    248 
    249     /**
    250      * Sets the nickname of the profile of the given iccid.
    251      *
    252      * @param cardId The Id of the eUICC.
    253      * @param iccid The iccid of the profile.
    254      * @param nickname The nickname of the profile.
    255      * @param executor The executor through which the callback should be invode.
    256      * @param callback The callback to get the result code.
    257      */
    258     public void setNickname(String cardId, String iccid, String nickname,
    259             @CallbackExecutor Executor executor, ResultCallback<Void> callback) {
    260         try {
    261             getIEuiccCardController().setNickname(mContext.getOpPackageName(), cardId, iccid,
    262                     nickname, new ISetNicknameCallback.Stub() {
    263                         @Override
    264                         public void onComplete(int resultCode) {
    265                             executor.execute(() -> callback.onComplete(resultCode, null));
    266                         }
    267                     });
    268         } catch (RemoteException e) {
    269             Log.e(TAG, "Error calling setNickname", e);
    270             throw e.rethrowFromSystemServer();
    271         }
    272     }
    273 
    274     /**
    275      * Deletes the profile of the given iccid from eUICC.
    276      *
    277      * @param cardId The Id of the eUICC.
    278      * @param iccid The iccid of the profile.
    279      * @param executor The executor through which the callback should be invode.
    280      * @param callback The callback to get the result code.
    281      */
    282     public void deleteProfile(String cardId, String iccid, @CallbackExecutor Executor executor,
    283             ResultCallback<Void> callback) {
    284         try {
    285             getIEuiccCardController().deleteProfile(mContext.getOpPackageName(), cardId, iccid,
    286                     new IDeleteProfileCallback.Stub() {
    287                         @Override
    288                         public void onComplete(int resultCode) {
    289                             executor.execute(() -> callback.onComplete(resultCode, null));
    290                         }
    291                     });
    292         } catch (RemoteException e) {
    293             Log.e(TAG, "Error calling deleteProfile", e);
    294             throw e.rethrowFromSystemServer();
    295         }
    296     }
    297 
    298     /**
    299      * Resets the eUICC memory.
    300      *
    301      * @param cardId The Id of the eUICC.
    302      * @param options Bits of the options of resetting which parts of the eUICC memory. See
    303      *     EuiccCard for details.
    304      * @param executor The executor through which the callback should be invode.
    305      * @param callback The callback to get the result code.
    306      */
    307     public void resetMemory(String cardId, @ResetOption int options,
    308             @CallbackExecutor Executor executor, ResultCallback<Void> callback) {
    309         try {
    310             getIEuiccCardController().resetMemory(mContext.getOpPackageName(), cardId, options,
    311                     new IResetMemoryCallback.Stub() {
    312                         @Override
    313                         public void onComplete(int resultCode) {
    314                             executor.execute(() -> callback.onComplete(resultCode, null));
    315                         }
    316                     });
    317         } catch (RemoteException e) {
    318             Log.e(TAG, "Error calling resetMemory", e);
    319             throw e.rethrowFromSystemServer();
    320         }
    321     }
    322 
    323     /**
    324      * Requests the default SM-DP+ address from eUICC.
    325      *
    326      * @param cardId The Id of the eUICC.
    327      * @param executor The executor through which the callback should be invode.
    328      * @param callback The callback to get the result code and the default SM-DP+ address.
    329      */
    330     public void requestDefaultSmdpAddress(String cardId, @CallbackExecutor Executor executor,
    331             ResultCallback<String> callback) {
    332         try {
    333             getIEuiccCardController().getDefaultSmdpAddress(mContext.getOpPackageName(), cardId,
    334                     new IGetDefaultSmdpAddressCallback.Stub() {
    335                         @Override
    336                         public void onComplete(int resultCode, String address) {
    337                             executor.execute(() -> callback.onComplete(resultCode, address));
    338                         }
    339                     });
    340         } catch (RemoteException e) {
    341             Log.e(TAG, "Error calling getDefaultSmdpAddress", e);
    342             throw e.rethrowFromSystemServer();
    343         }
    344     }
    345 
    346     /**
    347      * Requests the SM-DS address from eUICC.
    348      *
    349      * @param cardId The Id of the eUICC.
    350      * @param executor The executor through which the callback should be invode.
    351      * @param callback The callback to get the result code and the SM-DS address.
    352      */
    353     public void requestSmdsAddress(String cardId, @CallbackExecutor Executor executor,
    354             ResultCallback<String> callback) {
    355         try {
    356             getIEuiccCardController().getSmdsAddress(mContext.getOpPackageName(), cardId,
    357                     new IGetSmdsAddressCallback.Stub() {
    358                         @Override
    359                         public void onComplete(int resultCode, String address) {
    360                             executor.execute(() -> callback.onComplete(resultCode, address));
    361                         }
    362                     });
    363         } catch (RemoteException e) {
    364             Log.e(TAG, "Error calling getSmdsAddress", e);
    365             throw e.rethrowFromSystemServer();
    366         }
    367     }
    368 
    369     /**
    370      * Sets the default SM-DP+ address of eUICC.
    371      *
    372      * @param cardId The Id of the eUICC.
    373      * @param defaultSmdpAddress The default SM-DP+ address to set.
    374      * @param executor The executor through which the callback should be invode.
    375      * @param callback The callback to get the result code.
    376      */
    377     public void setDefaultSmdpAddress(String cardId, String defaultSmdpAddress,
    378             @CallbackExecutor Executor executor, ResultCallback<Void> callback) {
    379         try {
    380             getIEuiccCardController().setDefaultSmdpAddress(mContext.getOpPackageName(), cardId,
    381                     defaultSmdpAddress,
    382                     new ISetDefaultSmdpAddressCallback.Stub() {
    383                         @Override
    384                         public void onComplete(int resultCode) {
    385                             executor.execute(() -> callback.onComplete(resultCode, null));
    386                         }
    387                     });
    388         } catch (RemoteException e) {
    389             Log.e(TAG, "Error calling setDefaultSmdpAddress", e);
    390             throw e.rethrowFromSystemServer();
    391         }
    392     }
    393 
    394     /**
    395      * Requests Rules Authorisation Table.
    396      *
    397      * @param cardId The Id of the eUICC.
    398      * @param executor The executor through which the callback should be invode.
    399      * @param callback the callback to get the result code and the rule authorisation table.
    400      */
    401     public void requestRulesAuthTable(String cardId, @CallbackExecutor Executor executor,
    402             ResultCallback<EuiccRulesAuthTable> callback) {
    403         try {
    404             getIEuiccCardController().getRulesAuthTable(mContext.getOpPackageName(), cardId,
    405                     new IGetRulesAuthTableCallback.Stub() {
    406                         @Override
    407                         public void onComplete(int resultCode, EuiccRulesAuthTable rat) {
    408                             executor.execute(() -> callback.onComplete(resultCode, rat));
    409                         }
    410                     });
    411         } catch (RemoteException e) {
    412             Log.e(TAG, "Error calling getRulesAuthTable", e);
    413             throw e.rethrowFromSystemServer();
    414         }
    415     }
    416 
    417     /**
    418      * Requests the eUICC challenge for new profile downloading.
    419      *
    420      * @param cardId The Id of the eUICC.
    421      * @param executor The executor through which the callback should be invode.
    422      * @param callback the callback to get the result code and the challenge.
    423      */
    424     public void requestEuiccChallenge(String cardId, @CallbackExecutor Executor executor,
    425             ResultCallback<byte[]> callback) {
    426         try {
    427             getIEuiccCardController().getEuiccChallenge(mContext.getOpPackageName(), cardId,
    428                     new IGetEuiccChallengeCallback.Stub() {
    429                         @Override
    430                         public void onComplete(int resultCode, byte[] challenge) {
    431                             executor.execute(() -> callback.onComplete(resultCode, challenge));
    432                         }
    433                     });
    434         } catch (RemoteException e) {
    435             Log.e(TAG, "Error calling getEuiccChallenge", e);
    436             throw e.rethrowFromSystemServer();
    437         }
    438     }
    439 
    440     /**
    441      * Requests the eUICC info1 defined in GSMA RSP v2.0+ for new profile downloading.
    442      *
    443      * @param cardId The Id of the eUICC.
    444      * @param executor The executor through which the callback should be invode.
    445      * @param callback the callback to get the result code and the info1.
    446      */
    447     public void requestEuiccInfo1(String cardId, @CallbackExecutor Executor executor,
    448             ResultCallback<byte[]> callback) {
    449         try {
    450             getIEuiccCardController().getEuiccInfo1(mContext.getOpPackageName(), cardId,
    451                     new IGetEuiccInfo1Callback.Stub() {
    452                         @Override
    453                         public void onComplete(int resultCode, byte[] info) {
    454                             executor.execute(() -> callback.onComplete(resultCode, info));
    455                         }
    456                     });
    457         } catch (RemoteException e) {
    458             Log.e(TAG, "Error calling getEuiccInfo1", e);
    459             throw e.rethrowFromSystemServer();
    460         }
    461     }
    462 
    463     /**
    464      * Gets the eUICC info2 defined in GSMA RSP v2.0+ for new profile downloading.
    465      *
    466      * @param cardId The Id of the eUICC.
    467      * @param executor The executor through which the callback should be invode.
    468      * @param callback the callback to get the result code and the info2.
    469      */
    470     public void requestEuiccInfo2(String cardId, @CallbackExecutor Executor executor,
    471             ResultCallback<byte[]> callback) {
    472         try {
    473             getIEuiccCardController().getEuiccInfo2(mContext.getOpPackageName(), cardId,
    474                     new IGetEuiccInfo2Callback.Stub() {
    475                         @Override
    476                         public void onComplete(int resultCode, byte[] info) {
    477                             executor.execute(() -> callback.onComplete(resultCode, info));
    478                         }
    479                     });
    480         } catch (RemoteException e) {
    481             Log.e(TAG, "Error calling getEuiccInfo2", e);
    482             throw e.rethrowFromSystemServer();
    483         }
    484     }
    485 
    486     /**
    487      * Authenticates the SM-DP+ server by the eUICC.
    488      *
    489      * @param cardId The Id of the eUICC.
    490      * @param matchingId the activation code token defined in GSMA RSP v2.0+ or empty when it is not
    491      *     required.
    492      * @param serverSigned1 ASN.1 data in byte array signed and returned by the SM-DP+ server.
    493      * @param serverSignature1 ASN.1 data in byte array indicating a SM-DP+ signature which is
    494      *     returned by SM-DP+ server.
    495      * @param euiccCiPkIdToBeUsed ASN.1 data in byte array indicating CI Public Key Identifier to be
    496      *     used by the eUICC for signature which is returned by SM-DP+ server. This is defined in
    497      *     GSMA RSP v2.0+.
    498      * @param serverCertificate ASN.1 data in byte array indicating SM-DP+ Certificate returned by
    499      *     SM-DP+ server.
    500      * @param executor The executor through which the callback should be invode.
    501      * @param callback the callback to get the result code and a byte array which represents a
    502      *     {@code AuthenticateServerResponse} defined in GSMA RSP v2.0+.
    503      */
    504     public void authenticateServer(String cardId, String matchingId, byte[] serverSigned1,
    505             byte[] serverSignature1, byte[] euiccCiPkIdToBeUsed, byte[] serverCertificate,
    506             @CallbackExecutor Executor executor, ResultCallback<byte[]> callback) {
    507         try {
    508             getIEuiccCardController().authenticateServer(
    509                     mContext.getOpPackageName(),
    510                     cardId,
    511                     matchingId,
    512                     serverSigned1,
    513                     serverSignature1,
    514                     euiccCiPkIdToBeUsed,
    515                     serverCertificate,
    516                     new IAuthenticateServerCallback.Stub() {
    517                         @Override
    518                         public void onComplete(int resultCode, byte[] response) {
    519                             executor.execute(() -> callback.onComplete(resultCode, response));
    520                         }
    521                     });
    522         } catch (RemoteException e) {
    523             Log.e(TAG, "Error calling authenticateServer", e);
    524             throw e.rethrowFromSystemServer();
    525         }
    526     }
    527 
    528     /**
    529      * Prepares the profile download request sent to SM-DP+.
    530      *
    531      * @param cardId The Id of the eUICC.
    532      * @param hashCc the hash of confirmation code. It can be null if there is no confirmation code
    533      *     required.
    534      * @param smdpSigned2 ASN.1 data in byte array indicating the data to be signed by the SM-DP+
    535      *     returned by SM-DP+ server.
    536      * @param smdpSignature2 ASN.1 data in byte array indicating the SM-DP+ signature returned by
    537      *     SM-DP+ server.
    538      * @param smdpCertificate ASN.1 data in byte array indicating the SM-DP+ Certificate returned
    539      *     by SM-DP+ server.
    540      * @param executor The executor through which the callback should be invode.
    541      * @param callback the callback to get the result code and a byte array which represents a
    542      *     {@code PrepareDownloadResponse} defined in GSMA RSP v2.0+
    543      */
    544     public void prepareDownload(String cardId, @Nullable byte[] hashCc, byte[] smdpSigned2,
    545             byte[] smdpSignature2, byte[] smdpCertificate, @CallbackExecutor Executor executor,
    546             ResultCallback<byte[]> callback) {
    547         try {
    548             getIEuiccCardController().prepareDownload(
    549                     mContext.getOpPackageName(),
    550                     cardId,
    551                     hashCc,
    552                     smdpSigned2,
    553                     smdpSignature2,
    554                     smdpCertificate,
    555                     new IPrepareDownloadCallback.Stub() {
    556                         @Override
    557                         public void onComplete(int resultCode, byte[] response) {
    558                             executor.execute(() -> callback.onComplete(resultCode, response));
    559                         }
    560                     });
    561         } catch (RemoteException e) {
    562             Log.e(TAG, "Error calling prepareDownload", e);
    563             throw e.rethrowFromSystemServer();
    564         }
    565     }
    566 
    567     /**
    568      * Loads a downloaded bound profile package onto the eUICC.
    569      *
    570      * @param cardId The Id of the eUICC.
    571      * @param boundProfilePackage the Bound Profile Package data returned by SM-DP+ server.
    572      * @param executor The executor through which the callback should be invode.
    573      * @param callback the callback to get the result code and a byte array which represents a
    574      *     {@code LoadBoundProfilePackageResponse} defined in GSMA RSP v2.0+.
    575      */
    576     public void loadBoundProfilePackage(String cardId, byte[] boundProfilePackage,
    577             @CallbackExecutor Executor executor, ResultCallback<byte[]> callback) {
    578         try {
    579             getIEuiccCardController().loadBoundProfilePackage(
    580                     mContext.getOpPackageName(),
    581                     cardId,
    582                     boundProfilePackage,
    583                     new ILoadBoundProfilePackageCallback.Stub() {
    584                         @Override
    585                         public void onComplete(int resultCode, byte[] response) {
    586                             executor.execute(() -> callback.onComplete(resultCode, response));
    587                         }
    588                     });
    589         } catch (RemoteException e) {
    590             Log.e(TAG, "Error calling loadBoundProfilePackage", e);
    591             throw e.rethrowFromSystemServer();
    592         }
    593     }
    594 
    595     /**
    596      * Cancels the current profile download session.
    597      *
    598      * @param cardId The Id of the eUICC.
    599      * @param transactionId the transaction ID returned by SM-DP+ server.
    600      * @param reason the cancel reason.
    601      * @param executor The executor through which the callback should be invode.
    602      * @param callback the callback to get the result code and an byte[] which represents a
    603      *     {@code CancelSessionResponse} defined in GSMA RSP v2.0+.
    604      */
    605     public void cancelSession(String cardId, byte[] transactionId, @CancelReason int reason,
    606             @CallbackExecutor Executor executor, ResultCallback<byte[]> callback) {
    607         try {
    608             getIEuiccCardController().cancelSession(
    609                     mContext.getOpPackageName(),
    610                     cardId,
    611                     transactionId,
    612                     reason,
    613                     new ICancelSessionCallback.Stub() {
    614                         @Override
    615                         public void onComplete(int resultCode, byte[] response) {
    616                             executor.execute(() -> callback.onComplete(resultCode, response));
    617                         }
    618                     });
    619         } catch (RemoteException e) {
    620             Log.e(TAG, "Error calling cancelSession", e);
    621             throw e.rethrowFromSystemServer();
    622         }
    623     }
    624 
    625     /**
    626      * Lists all notifications of the given {@code events}.
    627      *
    628      * @param cardId The Id of the eUICC.
    629      * @param events bits of the event types ({@link EuiccNotification.Event}) to list.
    630      * @param executor The executor through which the callback should be invode.
    631      * @param callback the callback to get the result code and the list of notifications.
    632      */
    633     public void listNotifications(String cardId, @EuiccNotification.Event int events,
    634             @CallbackExecutor Executor executor, ResultCallback<EuiccNotification[]> callback) {
    635         try {
    636             getIEuiccCardController().listNotifications(mContext.getOpPackageName(), cardId, events,
    637                     new IListNotificationsCallback.Stub() {
    638                         @Override
    639                         public void onComplete(int resultCode, EuiccNotification[] notifications) {
    640                             executor.execute(() -> callback.onComplete(resultCode, notifications));
    641                         }
    642                     });
    643         } catch (RemoteException e) {
    644             Log.e(TAG, "Error calling listNotifications", e);
    645             throw e.rethrowFromSystemServer();
    646         }
    647     }
    648 
    649     /**
    650      * Retrieves contents of all notification of the given {@code events}.
    651      *
    652      * @param cardId The Id of the eUICC.
    653      * @param events bits of the event types ({@link EuiccNotification.Event}) to list.
    654      * @param executor The executor through which the callback should be invode.
    655      * @param callback the callback to get the result code and the list of notifications.
    656      */
    657     public void retrieveNotificationList(String cardId, @EuiccNotification.Event int events,
    658             @CallbackExecutor Executor executor, ResultCallback<EuiccNotification[]> callback) {
    659         try {
    660             getIEuiccCardController().retrieveNotificationList(mContext.getOpPackageName(), cardId,
    661                     events, new IRetrieveNotificationListCallback.Stub() {
    662                         @Override
    663                         public void onComplete(int resultCode, EuiccNotification[] notifications) {
    664                             executor.execute(() -> callback.onComplete(resultCode, notifications));
    665                         }
    666                     });
    667         } catch (RemoteException e) {
    668             Log.e(TAG, "Error calling retrieveNotificationList", e);
    669             throw e.rethrowFromSystemServer();
    670         }
    671     }
    672 
    673     /**
    674      * Retrieves the content of a notification of the given {@code seqNumber}.
    675      *
    676      * @param cardId The Id of the eUICC.
    677      * @param seqNumber the sequence number of the notification.
    678      * @param executor The executor through which the callback should be invode.
    679      * @param callback the callback to get the result code and the notification.
    680      */
    681     public void retrieveNotification(String cardId, int seqNumber,
    682             @CallbackExecutor Executor executor, ResultCallback<EuiccNotification> callback) {
    683         try {
    684             getIEuiccCardController().retrieveNotification(mContext.getOpPackageName(), cardId,
    685                     seqNumber, new IRetrieveNotificationCallback.Stub() {
    686                         @Override
    687                         public void onComplete(int resultCode, EuiccNotification notification) {
    688                             executor.execute(() -> callback.onComplete(resultCode, notification));
    689                         }
    690                     });
    691         } catch (RemoteException e) {
    692             Log.e(TAG, "Error calling retrieveNotification", e);
    693             throw e.rethrowFromSystemServer();
    694         }
    695     }
    696 
    697     /**
    698      * Removes a notification from eUICC.
    699      *
    700      * @param cardId The Id of the eUICC.
    701      * @param seqNumber the sequence number of the notification.
    702      * @param executor The executor through which the callback should be invode.
    703      * @param callback the callback to get the result code.
    704      */
    705     public void removeNotificationFromList(String cardId, int seqNumber,
    706             @CallbackExecutor Executor executor, ResultCallback<Void> callback) {
    707         try {
    708             getIEuiccCardController().removeNotificationFromList(
    709                     mContext.getOpPackageName(),
    710                     cardId,
    711                     seqNumber,
    712                     new IRemoveNotificationFromListCallback.Stub() {
    713                         @Override
    714                         public void onComplete(int resultCode) {
    715                             executor.execute(() -> callback.onComplete(resultCode, null));
    716                         }
    717                     });
    718         } catch (RemoteException e) {
    719             Log.e(TAG, "Error calling removeNotificationFromList", e);
    720             throw e.rethrowFromSystemServer();
    721         }
    722     }
    723 }
    724