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