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