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