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