1 /* 2 * Copyright (C) 2017 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.Manifest; 19 import android.annotation.IntDef; 20 import android.annotation.Nullable; 21 import android.annotation.RequiresPermission; 22 import android.annotation.SdkConstant; 23 import android.annotation.SystemApi; 24 import android.app.Activity; 25 import android.app.PendingIntent; 26 import android.content.Context; 27 import android.content.Intent; 28 import android.content.IntentSender; 29 import android.content.pm.PackageManager; 30 import android.os.Bundle; 31 import android.os.RemoteException; 32 import android.os.ServiceManager; 33 34 import com.android.internal.telephony.euicc.IEuiccController; 35 36 import java.lang.annotation.Retention; 37 import java.lang.annotation.RetentionPolicy; 38 39 /** 40 * EuiccManager is the application interface to eUICCs, or eSIMs/embedded SIMs. 41 * 42 * <p>You do not instantiate this class directly; instead, you retrieve an instance through 43 * {@link Context#getSystemService(String)} and {@link Context#EUICC_SERVICE}. 44 * 45 * <p>See {@link #isEnabled} before attempting to use these APIs. 46 */ 47 public class EuiccManager { 48 49 /** 50 * Intent action to launch the embedded SIM (eUICC) management settings screen. 51 * 52 * <p>This screen shows a list of embedded profiles and offers the user the ability to switch 53 * between them, download new profiles, and delete unused profiles. 54 * 55 * <p>The activity will immediately finish with {@link android.app.Activity#RESULT_CANCELED} if 56 * {@link #isEnabled} is false. 57 * 58 * This is ued by non-LPA app to bring up LUI. 59 */ 60 @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION) 61 public static final String ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS = 62 "android.telephony.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS"; 63 64 65 /** 66 * Broadcast Action: The eUICC OTA status is changed. 67 * <p class="note"> 68 * Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. 69 * 70 * <p class="note">This is a protected intent that can only be sent 71 * by the system. 72 * 73 * @hide 74 */ 75 @SystemApi 76 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION) 77 @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) 78 public static final String ACTION_OTA_STATUS_CHANGED = 79 "android.telephony.euicc.action.OTA_STATUS_CHANGED"; 80 81 /** 82 * Broadcast Action: The action sent to carrier app so it knows the carrier setup is not 83 * completed. 84 */ 85 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION) 86 public static final String ACTION_NOTIFY_CARRIER_SETUP_INCOMPLETE = 87 "android.telephony.euicc.action.NOTIFY_CARRIER_SETUP_INCOMPLETE"; 88 89 /** 90 * Intent action to provision an embedded subscription. 91 * 92 * <p>May be called during device provisioning to launch a screen to perform embedded SIM 93 * provisioning, e.g. if no physical SIM is present and the user elects to configure their 94 * embedded SIM. 95 * 96 * <p>The activity will immediately finish with {@link android.app.Activity#RESULT_CANCELED} if 97 * {@link #isEnabled} is false. 98 * 99 * @hide 100 */ 101 @SystemApi 102 @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION) 103 public static final String ACTION_PROVISION_EMBEDDED_SUBSCRIPTION = 104 "android.telephony.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION"; 105 106 /** 107 * Intent action to handle a resolvable error. 108 * @hide 109 */ 110 public static final String ACTION_RESOLVE_ERROR = 111 "android.telephony.euicc.action.RESOLVE_ERROR"; 112 113 /** 114 * Result code for an operation indicating that the operation succeeded. 115 */ 116 public static final int EMBEDDED_SUBSCRIPTION_RESULT_OK = 0; 117 118 /** 119 * Result code for an operation indicating that the user must take some action before the 120 * operation can continue. 121 * 122 * @see #startResolutionActivity 123 */ 124 public static final int EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR = 1; 125 126 /** 127 * Result code for an operation indicating that an unresolvable error occurred. 128 * 129 * {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} will be populated with a detailed error 130 * code for logging/debugging purposes only. 131 */ 132 public static final int EMBEDDED_SUBSCRIPTION_RESULT_ERROR = 2; 133 134 /** 135 * Key for an extra set on {@link PendingIntent} result callbacks providing a detailed result 136 * code. 137 * 138 * <p>This code is an implementation detail of the embedded subscription manager and is only 139 * intended for logging or debugging purposes. 140 */ 141 public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE = 142 "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DETAILED_CODE"; 143 144 /** 145 * Key for an extra set on {@code #getDownloadableSubscriptionMetadata} PendingIntent result 146 * callbacks providing the downloadable subscription metadata. 147 */ 148 public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION = 149 "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION"; 150 151 /** 152 * Key for an extra set on {@link #getDefaultDownloadableSubscriptionList} PendingIntent result 153 * callbacks providing the list of available downloadable subscriptions. 154 * @hide 155 */ 156 @SystemApi 157 public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS = 158 "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS"; 159 160 /** 161 * Key for an extra set on {@link PendingIntent} result callbacks providing the resolution 162 * pending intent for {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR}s. 163 * @hide 164 */ 165 public static final String EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT = 166 "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT"; 167 168 /** 169 * Key for an extra set on the {@link #EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT} intent 170 * containing the EuiccService action to launch for resolution. 171 * @hide 172 */ 173 public static final String EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_ACTION = 174 "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_RESOLUTION_ACTION"; 175 176 /** 177 * Key for an extra set on the {@link #EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT} intent 178 * providing the callback to execute after resolution is completed. 179 * @hide 180 */ 181 public static final String EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT = 182 "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT"; 183 184 /** 185 * Key for an extra set on the {@link #ACTION_PROVISION_EMBEDDED_SUBSCRIPTION} intent for 186 * whether the user choses to use eUICC to set up network in SUW. 187 * @hide 188 */ 189 public static final String EXTRA_FORCE_PROVISION = 190 "android.telephony.euicc.extra.FORCE_PROVISION"; 191 192 /** 193 * Optional meta-data attribute for a carrier app providing an icon to use to represent the 194 * carrier. If not provided, the app's launcher icon will be used as a fallback. 195 */ 196 public static final String META_DATA_CARRIER_ICON = "android.telephony.euicc.carriericon"; 197 198 /** 199 * Euicc OTA update status which can be got by {@link #getOtaStatus} 200 * @hide 201 */ 202 @SystemApi 203 @Retention(RetentionPolicy.SOURCE) 204 @IntDef(prefix = {"EUICC_OTA_"}, value = { 205 EUICC_OTA_IN_PROGRESS, 206 EUICC_OTA_FAILED, 207 EUICC_OTA_SUCCEEDED, 208 EUICC_OTA_NOT_NEEDED, 209 EUICC_OTA_STATUS_UNAVAILABLE 210 211 }) 212 public @interface OtaStatus{} 213 214 /** 215 * An OTA is in progress. During this time, the eUICC is not available and the user may lose 216 * network access. 217 * @hide 218 */ 219 @SystemApi 220 public static final int EUICC_OTA_IN_PROGRESS = 1; 221 222 /** 223 * The OTA update failed. 224 * @hide 225 */ 226 @SystemApi 227 public static final int EUICC_OTA_FAILED = 2; 228 229 /** 230 * The OTA update finished successfully. 231 * @hide 232 */ 233 @SystemApi 234 public static final int EUICC_OTA_SUCCEEDED = 3; 235 236 /** 237 * The OTA update not needed since current eUICC OS is latest. 238 * @hide 239 */ 240 @SystemApi 241 public static final int EUICC_OTA_NOT_NEEDED = 4; 242 243 /** 244 * The OTA status is unavailable since eUICC service is unavailable. 245 * @hide 246 */ 247 @SystemApi 248 public static final int EUICC_OTA_STATUS_UNAVAILABLE = 5; 249 250 private final Context mContext; 251 252 /** @hide */ EuiccManager(Context context)253 public EuiccManager(Context context) { 254 mContext = context; 255 } 256 257 /** 258 * Whether embedded subscriptions are currently enabled. 259 * 260 * <p>Even on devices with the {@link PackageManager#FEATURE_TELEPHONY_EUICC} feature, embedded 261 * subscriptions may be turned off, e.g. because of a carrier restriction from an inserted 262 * physical SIM. Therefore, this runtime check should be used before accessing embedded 263 * subscription APIs. 264 * 265 * @return true if embedded subscriptions are currently enabled. 266 */ isEnabled()267 public boolean isEnabled() { 268 // In the future, this may reach out to IEuiccController (if non-null) to check any dynamic 269 // restrictions. 270 return getIEuiccController() != null; 271 } 272 273 /** 274 * Returns the EID identifying the eUICC hardware. 275 * 276 * <p>Requires that the calling app has carrier privileges on the active subscription on the 277 * eUICC. 278 * 279 * @return the EID. May be null if {@link #isEnabled()} is false or the eUICC is not ready. 280 */ 281 @Nullable getEid()282 public String getEid() { 283 if (!isEnabled()) { 284 return null; 285 } 286 try { 287 return getIEuiccController().getEid(); 288 } catch (RemoteException e) { 289 throw e.rethrowFromSystemServer(); 290 } 291 } 292 293 /** 294 * Returns the current status of eUICC OTA. 295 * 296 * <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. 297 * 298 * @return the status of eUICC OTA. If {@link #isEnabled()} is false or the eUICC is not ready, 299 * {@link OtaStatus#EUICC_OTA_STATUS_UNAVAILABLE} will be returned. 300 * 301 * @hide 302 */ 303 @SystemApi 304 @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) getOtaStatus()305 public int getOtaStatus() { 306 if (!isEnabled()) { 307 return EUICC_OTA_STATUS_UNAVAILABLE; 308 } 309 try { 310 return getIEuiccController().getOtaStatus(); 311 } catch (RemoteException e) { 312 throw e.rethrowFromSystemServer(); 313 } 314 } 315 316 /** 317 * Attempt to download the given {@link DownloadableSubscription}. 318 * 319 * <p>Requires the {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission, 320 * or the calling app must be authorized to manage both the currently-active subscription and 321 * the subscription to be downloaded according to the subscription metadata. Without the former, 322 * an {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR} will be returned in the callback 323 * intent to prompt the user to accept the download. 324 * 325 * @param subscription the subscription to download. 326 * @param switchAfterDownload if true, the profile will be activated upon successful download. 327 * @param callbackIntent a PendingIntent to launch when the operation completes. 328 */ 329 @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) downloadSubscription(DownloadableSubscription subscription, boolean switchAfterDownload, PendingIntent callbackIntent)330 public void downloadSubscription(DownloadableSubscription subscription, 331 boolean switchAfterDownload, PendingIntent callbackIntent) { 332 if (!isEnabled()) { 333 sendUnavailableError(callbackIntent); 334 return; 335 } 336 try { 337 getIEuiccController().downloadSubscription(subscription, switchAfterDownload, 338 mContext.getOpPackageName(), callbackIntent); 339 } catch (RemoteException e) { 340 throw e.rethrowFromSystemServer(); 341 } 342 } 343 344 /** 345 * Start an activity to resolve a user-resolvable error. 346 * 347 * <p>If an operation returns {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR}, this 348 * method may be called to prompt the user to resolve the issue. 349 * 350 * <p>This method may only be called once for a particular error. 351 * 352 * @param activity the calling activity (which should be in the foreground). 353 * @param requestCode an application-specific request code which will be provided to 354 * {@link Activity#onActivityResult} upon completion. Note that the operation may still be 355 * in progress when the resolution activity completes; it is not fully finished until the 356 * callback intent is triggered. 357 * @param resultIntent the Intent provided to the initial callback intent which failed with 358 * {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR}. 359 * @param callbackIntent a PendingIntent to launch when the operation completes. This is 360 * trigered upon completion of the original operation that required user resolution. 361 * @throws android.content.IntentSender.SendIntentException if called more than once. 362 */ startResolutionActivity(Activity activity, int requestCode, Intent resultIntent, PendingIntent callbackIntent)363 public void startResolutionActivity(Activity activity, int requestCode, Intent resultIntent, 364 PendingIntent callbackIntent) throws IntentSender.SendIntentException { 365 PendingIntent resolutionIntent = 366 resultIntent.getParcelableExtra(EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT); 367 if (resolutionIntent == null) { 368 throw new IllegalArgumentException("Invalid result intent"); 369 } 370 Intent fillInIntent = new Intent(); 371 fillInIntent.putExtra(EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT, 372 callbackIntent); 373 activity.startIntentSenderForResult(resolutionIntent.getIntentSender(), requestCode, 374 fillInIntent, 0 /* flagsMask */, 0 /* flagsValues */, 0 /* extraFlags */); 375 } 376 377 /** 378 * Continue an operation after the user resolves an error. 379 * 380 * <p>To be called by the LUI upon completion of a resolvable error flow. 381 * 382 * <p>Requires that the calling app has the 383 * {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. 384 * 385 * @param resolutionIntent The original intent used to start the LUI. 386 * @param resolutionExtras Resolution-specific extras depending on the result of the resolution. 387 * For example, this may indicate whether the user has consented or may include the input 388 * they provided. 389 * @hide 390 */ 391 @SystemApi 392 @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) continueOperation(Intent resolutionIntent, Bundle resolutionExtras)393 public void continueOperation(Intent resolutionIntent, Bundle resolutionExtras) { 394 if (!isEnabled()) { 395 PendingIntent callbackIntent = 396 resolutionIntent.getParcelableExtra( 397 EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT); 398 if (callbackIntent != null) { 399 sendUnavailableError(callbackIntent); 400 } 401 return; 402 } 403 try { 404 getIEuiccController().continueOperation(resolutionIntent, resolutionExtras); 405 } catch (RemoteException e) { 406 throw e.rethrowFromSystemServer(); 407 } 408 } 409 410 /** 411 * Fills in the metadata for a DownloadableSubscription. 412 * 413 * <p>May be used in cases that a DownloadableSubscription was constructed to download a 414 * profile, but the metadata for the profile is unknown (e.g. we only know the activation code). 415 * The callback will be triggered with an Intent with 416 * {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION} set to the 417 * downloadable subscription metadata upon success. 418 * 419 * <p>Requires that the calling app has the 420 * {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. This is for 421 * internal system use only. 422 * 423 * @param subscription the subscription which needs metadata filled in 424 * @param callbackIntent a PendingIntent to launch when the operation completes. 425 * @hide 426 */ 427 @SystemApi 428 @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) getDownloadableSubscriptionMetadata( DownloadableSubscription subscription, PendingIntent callbackIntent)429 public void getDownloadableSubscriptionMetadata( 430 DownloadableSubscription subscription, PendingIntent callbackIntent) { 431 if (!isEnabled()) { 432 sendUnavailableError(callbackIntent); 433 return; 434 } 435 try { 436 getIEuiccController().getDownloadableSubscriptionMetadata( 437 subscription, mContext.getOpPackageName(), callbackIntent); 438 } catch (RemoteException e) { 439 throw e.rethrowFromSystemServer(); 440 } 441 } 442 443 /** 444 * Gets metadata for subscription which are available for download on this device. 445 * 446 * <p>Subscriptions returned here may be passed to {@link #downloadSubscription}. They may have 447 * been pre-assigned to this particular device, for example. The callback will be triggered with 448 * an Intent with {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS} set to the 449 * list of available subscriptions upon success. 450 * 451 * <p>Requires that the calling app has the 452 * {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. This is for 453 * internal system use only. 454 * 455 * @param callbackIntent a PendingIntent to launch when the operation completes. 456 * @hide 457 */ 458 @SystemApi 459 @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) getDefaultDownloadableSubscriptionList(PendingIntent callbackIntent)460 public void getDefaultDownloadableSubscriptionList(PendingIntent callbackIntent) { 461 if (!isEnabled()) { 462 sendUnavailableError(callbackIntent); 463 return; 464 } 465 try { 466 getIEuiccController().getDefaultDownloadableSubscriptionList( 467 mContext.getOpPackageName(), callbackIntent); 468 } catch (RemoteException e) { 469 throw e.rethrowFromSystemServer(); 470 } 471 } 472 473 /** 474 * Returns information about the eUICC chip/device. 475 * 476 * @return the {@link EuiccInfo}. May be null if {@link #isEnabled()} is false or the eUICC is 477 * not ready. 478 */ 479 @Nullable getEuiccInfo()480 public EuiccInfo getEuiccInfo() { 481 if (!isEnabled()) { 482 return null; 483 } 484 try { 485 return getIEuiccController().getEuiccInfo(); 486 } catch (RemoteException e) { 487 throw e.rethrowFromSystemServer(); 488 } 489 } 490 491 /** 492 * Deletes the given subscription. 493 * 494 * <p>If this subscription is currently active, the device will first switch away from it onto 495 * an "empty" subscription. 496 * 497 * <p>Requires that the calling app has carrier privileges according to the metadata of the 498 * profile to be deleted, or the 499 * {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. 500 * 501 * @param subscriptionId the ID of the subscription to delete. 502 * @param callbackIntent a PendingIntent to launch when the operation completes. 503 */ 504 @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) deleteSubscription(int subscriptionId, PendingIntent callbackIntent)505 public void deleteSubscription(int subscriptionId, PendingIntent callbackIntent) { 506 if (!isEnabled()) { 507 sendUnavailableError(callbackIntent); 508 return; 509 } 510 try { 511 getIEuiccController().deleteSubscription( 512 subscriptionId, mContext.getOpPackageName(), callbackIntent); 513 } catch (RemoteException e) { 514 throw e.rethrowFromSystemServer(); 515 } 516 } 517 518 /** 519 * Switch to (enable) the given subscription. 520 * 521 * <p>Requires the {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission, 522 * or the calling app must be authorized to manage both the currently-active subscription and 523 * the subscription to be enabled according to the subscription metadata. Without the former, 524 * an {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR} will be returned in the callback 525 * intent to prompt the user to accept the download. 526 * 527 * @param subscriptionId the ID of the subscription to enable. May be 528 * {@link android.telephony.SubscriptionManager#INVALID_SUBSCRIPTION_ID} to deactivate the 529 * current profile without activating another profile to replace it. 530 * @param callbackIntent a PendingIntent to launch when the operation completes. 531 */ 532 @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) switchToSubscription(int subscriptionId, PendingIntent callbackIntent)533 public void switchToSubscription(int subscriptionId, PendingIntent callbackIntent) { 534 if (!isEnabled()) { 535 sendUnavailableError(callbackIntent); 536 return; 537 } 538 try { 539 getIEuiccController().switchToSubscription( 540 subscriptionId, mContext.getOpPackageName(), callbackIntent); 541 } catch (RemoteException e) { 542 throw e.rethrowFromSystemServer(); 543 } 544 } 545 546 /** 547 * Update the nickname for the given subscription. 548 * 549 * <p>Requires that the calling app has the 550 * {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. This is for 551 * internal system use only. 552 * 553 * @param subscriptionId the ID of the subscription to update. 554 * @param nickname the new nickname to apply. 555 * @param callbackIntent a PendingIntent to launch when the operation completes. 556 * @hide 557 */ 558 @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) updateSubscriptionNickname( int subscriptionId, String nickname, PendingIntent callbackIntent)559 public void updateSubscriptionNickname( 560 int subscriptionId, String nickname, PendingIntent callbackIntent) { 561 if (!isEnabled()) { 562 sendUnavailableError(callbackIntent); 563 return; 564 } 565 try { 566 getIEuiccController().updateSubscriptionNickname( 567 subscriptionId, nickname, callbackIntent); 568 } catch (RemoteException e) { 569 throw e.rethrowFromSystemServer(); 570 } 571 } 572 573 /** 574 * Erase all subscriptions and reset the eUICC. 575 * 576 * <p>Requires that the calling app has the 577 * {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. 578 * 579 * @param callbackIntent a PendingIntent to launch when the operation completes. 580 * @hide 581 */ 582 @SystemApi 583 @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) eraseSubscriptions(PendingIntent callbackIntent)584 public void eraseSubscriptions(PendingIntent callbackIntent) { 585 if (!isEnabled()) { 586 sendUnavailableError(callbackIntent); 587 return; 588 } 589 try { 590 getIEuiccController().eraseSubscriptions(callbackIntent); 591 } catch (RemoteException e) { 592 throw e.rethrowFromSystemServer(); 593 } 594 } 595 596 /** 597 * Ensure that subscriptions will be retained on the next factory reset. 598 * 599 * <p>By default, all subscriptions on the eUICC are erased the first time a device boots (ever 600 * and after factory resets). This ensures that the data is wiped after a factory reset is 601 * performed via fastboot or recovery mode, as these modes do not support the necessary radio 602 * communication needed to wipe the eSIM. 603 * 604 * <p>However, this method may be called right before a factory reset issued via settings when 605 * the user elects to retain subscriptions. Doing so will mark them for retention so that they 606 * are not cleared after the ensuing reset. 607 * 608 * <p>Requires that the calling app has the {@link android.Manifest.permission#MASTER_CLEAR} 609 * permission. This is for internal system use only. 610 * 611 * @param callbackIntent a PendingIntent to launch when the operation completes. 612 * @hide 613 */ retainSubscriptionsForFactoryReset(PendingIntent callbackIntent)614 public void retainSubscriptionsForFactoryReset(PendingIntent callbackIntent) { 615 if (!isEnabled()) { 616 sendUnavailableError(callbackIntent); 617 return; 618 } 619 try { 620 getIEuiccController().retainSubscriptionsForFactoryReset(callbackIntent); 621 } catch (RemoteException e) { 622 throw e.rethrowFromSystemServer(); 623 } 624 } 625 sendUnavailableError(PendingIntent callbackIntent)626 private static void sendUnavailableError(PendingIntent callbackIntent) { 627 try { 628 callbackIntent.send(EMBEDDED_SUBSCRIPTION_RESULT_ERROR); 629 } catch (PendingIntent.CanceledException e) { 630 // Caller canceled the callback; do nothing. 631 } 632 } 633 getIEuiccController()634 private static IEuiccController getIEuiccController() { 635 return IEuiccController.Stub.asInterface(ServiceManager.getService("econtroller")); 636 } 637 } 638