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.NonNull; 21 import android.annotation.Nullable; 22 import android.annotation.RequiresPermission; 23 import android.annotation.SdkConstant; 24 import android.annotation.SystemApi; 25 import android.app.Activity; 26 import android.app.PendingIntent; 27 import android.content.Context; 28 import android.content.Intent; 29 import android.content.IntentSender; 30 import android.content.pm.PackageManager; 31 import android.os.Bundle; 32 import android.os.RemoteException; 33 import android.os.ServiceManager; 34 import android.telephony.TelephonyManager; 35 36 import com.android.internal.telephony.euicc.IEuiccController; 37 38 import java.lang.annotation.Retention; 39 import java.lang.annotation.RetentionPolicy; 40 41 /** 42 * EuiccManager is the application interface to eUICCs, or eSIMs/embedded SIMs. 43 * 44 * <p>You do not instantiate this class directly; instead, you retrieve an instance through 45 * {@link Context#getSystemService(String)} and {@link Context#EUICC_SERVICE}. This instance will be 46 * created using the default eUICC. 47 * 48 * <p>On a device with multiple eUICCs, you may want to create multiple EuiccManagers. To do this 49 * you can call {@link #createForCardId}. 50 * 51 * <p>See {@link #isEnabled} before attempting to use these APIs. 52 */ 53 public class EuiccManager { 54 55 /** 56 * Intent action to launch the embedded SIM (eUICC) management settings screen. 57 * 58 * <p>This screen shows a list of embedded profiles and offers the user the ability to switch 59 * between them, download new profiles, and delete unused profiles. 60 * 61 * <p>The activity will immediately finish with {@link android.app.Activity#RESULT_CANCELED} if 62 * {@link #isEnabled} is false. 63 * 64 * This is ued by non-LPA app to bring up LUI. 65 */ 66 @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION) 67 public static final String ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS = 68 "android.telephony.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS"; 69 70 /** 71 * Broadcast Action: The eUICC OTA status is changed. 72 * <p class="note"> 73 * Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. 74 * 75 * <p class="note">This is a protected intent that can only be sent 76 * by the system. 77 * 78 * @hide 79 */ 80 @SystemApi 81 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION) 82 @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) 83 public static final String ACTION_OTA_STATUS_CHANGED = 84 "android.telephony.euicc.action.OTA_STATUS_CHANGED"; 85 86 /** 87 * Broadcast Action: The action sent to carrier app so it knows the carrier setup is not 88 * completed. 89 */ 90 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION) 91 public static final String ACTION_NOTIFY_CARRIER_SETUP_INCOMPLETE = 92 "android.telephony.euicc.action.NOTIFY_CARRIER_SETUP_INCOMPLETE"; 93 94 /** 95 * Intent action to provision an embedded subscription. 96 * 97 * <p>May be called during device provisioning to launch a screen to perform embedded SIM 98 * provisioning, e.g. if no physical SIM is present and the user elects to configure their 99 * embedded SIM. 100 * 101 * <p>The activity will immediately finish with {@link android.app.Activity#RESULT_CANCELED} if 102 * {@link #isEnabled} is false. 103 * 104 * @hide 105 */ 106 @SystemApi 107 @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION) 108 public static final String ACTION_PROVISION_EMBEDDED_SUBSCRIPTION = 109 "android.telephony.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION"; 110 111 /** 112 * Intent action to handle a resolvable error. 113 * @hide 114 */ 115 public static final String ACTION_RESOLVE_ERROR = 116 "android.telephony.euicc.action.RESOLVE_ERROR"; 117 118 /** 119 * Intent action sent by system apps (such as the Settings app) to the Telephony framework to 120 * enable or disable a subscription. Must be accompanied with {@link #EXTRA_SUBSCRIPTION_ID} and 121 * {@link #EXTRA_ENABLE_SUBSCRIPTION}, and optionally {@link #EXTRA_FROM_SUBSCRIPTION_ID}. 122 * 123 * <p>Requires the caller to be a privileged process with the 124 * {@link android.permission#CALL_PRIVILEGED} permission for the intent to reach the Telephony 125 * stack. 126 * 127 * <p>Unlike {@link #switchToSubscription(int, PendingIntent)}, using this action allows the 128 * underlying eUICC service (i.e. the LPA app) to control the UI experience during this 129 * operation. The action is received by the Telephony framework, which in turn selects and 130 * launches an appropriate LPA activity to present UI to the user. For example, the activity may 131 * show a confirmation dialog, a progress dialog, or an error dialog when necessary. 132 * 133 * <p>The launched activity will immediately finish with 134 * {@link android.app.Activity#RESULT_CANCELED} if {@link #isEnabled} is false. 135 * 136 * @hide 137 */ 138 @SystemApi 139 public static final String ACTION_TOGGLE_SUBSCRIPTION_PRIVILEGED = 140 "android.telephony.euicc.action.TOGGLE_SUBSCRIPTION_PRIVILEGED"; 141 142 /** 143 * Intent action sent by system apps (such as the Settings app) to the Telephony framework to 144 * delete a subscription. Must be accompanied with {@link #EXTRA_SUBSCRIPTION_ID}. 145 * 146 * <p>Requires the caller to be a privileged process with the 147 * {@link android.permission#CALL_PRIVILEGED} permission for the intent to reach the Telephony 148 * stack. 149 * 150 * <p>Unlike {@link #deleteSubscription(int, PendingIntent)}, using this action allows the 151 * underlying eUICC service (i.e. the LPA app) to control the UI experience during this 152 * operation. The action is received by the Telephony framework, which in turn selects and 153 * launches an appropriate LPA activity to present UI to the user. For example, the activity may 154 * show a confirmation dialog, a progress dialog, or an error dialog when necessary. 155 * 156 * <p>The launched activity will immediately finish with 157 * {@link android.app.Activity#RESULT_CANCELED} if {@link #isEnabled} is false. 158 * 159 * @hide 160 */ 161 @SystemApi 162 public static final String ACTION_DELETE_SUBSCRIPTION_PRIVILEGED = 163 "android.telephony.euicc.action.DELETE_SUBSCRIPTION_PRIVILEGED"; 164 165 /** 166 * Intent action sent by system apps (such as the Settings app) to the Telephony framework to 167 * rename a subscription. Must be accompanied with {@link #EXTRA_SUBSCRIPTION_ID} and 168 * {@link #EXTRA_SUBSCRIPTION_NICKNAME}. 169 * 170 * <p>Requires the caller to be a privileged process with the 171 * {@link android.permission#CALL_PRIVILEGED} permission for the intent to reach the Telephony 172 * stack. 173 * 174 * <p>Unlike {@link #updateSubscriptionNickname(int, String, PendingIntent)}, using this action 175 * allows the the underlying eUICC service (i.e. the LPA app) to control the UI experience 176 * during this operation. The action is received by the Telephony framework, which in turn 177 * selects and launches an appropriate LPA activity to present UI to the user. For example, the 178 * activity may show a confirmation dialog, a progress dialog, or an error dialog when 179 * necessary. 180 * 181 * <p>The launched activity will immediately finish with 182 * {@link android.app.Activity#RESULT_CANCELED} if {@link #isEnabled} is false. 183 * 184 * @hide 185 */ 186 @SystemApi 187 public static final String ACTION_RENAME_SUBSCRIPTION_PRIVILEGED = 188 "android.telephony.euicc.action.RENAME_SUBSCRIPTION_PRIVILEGED"; 189 190 /** 191 * Result code for an operation indicating that the operation succeeded. 192 */ 193 public static final int EMBEDDED_SUBSCRIPTION_RESULT_OK = 0; 194 195 /** 196 * Result code for an operation indicating that the user must take some action before the 197 * operation can continue. 198 * 199 * @see #startResolutionActivity 200 */ 201 public static final int EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR = 1; 202 203 /** 204 * Result code for an operation indicating that an unresolvable error occurred. 205 * 206 * {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} will be populated with a detailed error 207 * code for logging/debugging purposes only. 208 */ 209 public static final int EMBEDDED_SUBSCRIPTION_RESULT_ERROR = 2; 210 211 /** 212 * Key for an extra set on the {@link #ACTION_PROVISION_EMBEDDED_SUBSCRIPTION} intent for which 213 * kind of activation flow will be evolved. (see {@code EUICC_ACTIVATION_}) 214 * 215 * @hide 216 */ 217 @SystemApi 218 public static final String EXTRA_ACTIVATION_TYPE = 219 "android.telephony.euicc.extra.ACTIVATION_TYPE"; 220 221 /** 222 * Key for an extra set on {@link PendingIntent} result callbacks providing a detailed result 223 * code. 224 * 225 * <p>This code is an implementation detail of the embedded subscription manager and is only 226 * intended for logging or debugging purposes. 227 */ 228 public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE = 229 "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DETAILED_CODE"; 230 231 /** 232 * Key for an extra set on {@code #getDownloadableSubscriptionMetadata} PendingIntent result 233 * callbacks providing the downloadable subscription metadata. 234 */ 235 public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION = 236 "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION"; 237 238 /** 239 * Key for an extra set on {@link #getDefaultDownloadableSubscriptionList} PendingIntent result 240 * callbacks providing the list of available downloadable subscriptions. 241 * @hide 242 */ 243 @SystemApi 244 public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS = 245 "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS"; 246 247 /** 248 * Key for an extra set on {@link PendingIntent} result callbacks providing the resolution 249 * pending intent for {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR}s. 250 * @hide 251 */ 252 public static final String EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT = 253 "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT"; 254 255 /** 256 * Key for an extra set on the {@link #EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT} intent 257 * containing the EuiccService action to launch for resolution. 258 * @hide 259 */ 260 public static final String EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_ACTION = 261 "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_RESOLUTION_ACTION"; 262 263 /** 264 * Key for an extra set on the {@link #EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT} intent 265 * providing the callback to execute after resolution is completed. 266 * @hide 267 */ 268 public static final String EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT = 269 "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT"; 270 271 /** 272 * Key for an extra set on the {@link #ACTION_PROVISION_EMBEDDED_SUBSCRIPTION} intent for 273 * whether eSIM provisioning flow is forced to be started or not. If this extra hasn't been 274 * set, eSIM provisioning flow may be skipped and the corresponding carrier's app will be 275 * notified. Otherwise, eSIM provisioning flow will be started when 276 * {@link #ACTION_PROVISION_EMBEDDED_SUBSCRIPTION} has been received. 277 * @hide 278 */ 279 @SystemApi 280 public static final String EXTRA_FORCE_PROVISION = 281 "android.telephony.euicc.extra.FORCE_PROVISION"; 282 283 /** 284 * Key for an extra set on privileged actions {@link #ACTION_TOGGLE_SUBSCRIPTION_PRIVILEGED}, 285 * {@link #ACTION_DELETE_SUBSCRIPTION_PRIVILEGED}, and 286 * {@link #ACTION_RENAME_SUBSCRIPTION_PRIVILEGED} providing the ID of the targeted subscription. 287 * 288 * <p>Expected type of the extra data: int 289 * 290 * @hide 291 */ 292 @SystemApi 293 public static final String EXTRA_SUBSCRIPTION_ID = 294 "android.telephony.euicc.extra.SUBSCRIPTION_ID"; 295 296 /** 297 * Key for an extra set on {@link #ACTION_TOGGLE_SUBSCRIPTION_PRIVILEGED} providing a boolean 298 * value of whether to enable or disable the targeted subscription. 299 * 300 * <p>Expected type of the extra data: boolean 301 * 302 * @hide 303 */ 304 @SystemApi 305 public static final String EXTRA_ENABLE_SUBSCRIPTION = 306 "android.telephony.euicc.extra.ENABLE_SUBSCRIPTION"; 307 308 /** 309 * Key for an extra set on {@link #ACTION_RENAME_SUBSCRIPTION_PRIVILEGED} providing a new 310 * nickname for the targeted subscription. 311 * 312 * <p>Expected type of the extra data: String 313 * 314 * @hide 315 */ 316 @SystemApi 317 public static final String EXTRA_SUBSCRIPTION_NICKNAME = 318 "android.telephony.euicc.extra.SUBSCRIPTION_NICKNAME"; 319 320 /** 321 * Key for an extra set on {@link #ACTION_TOGGLE_SUBSCRIPTION_PRIVILEGED} providing the ID of 322 * the subscription we're toggling from. This extra is optional and is only used for UI 323 * purposes by the underlying eUICC service (i.e. the LPA app), such as displaying a dialog 324 * titled "Switch X with Y". If set, the provided subscription will be used as the "from" 325 * subscription in UI (the "X" in the dialog example). Otherwise, the currently active 326 * subscription that will be disabled is the "from" subscription. 327 * 328 * <p>Expected type of the extra data: int 329 * 330 * @hide 331 */ 332 @SystemApi 333 public static final String EXTRA_FROM_SUBSCRIPTION_ID = 334 "android.telephony.euicc.extra.FROM_SUBSCRIPTION_ID"; 335 336 /** 337 * Key for an extra set on privileged actions {@link #ACTION_TOGGLE_SUBSCRIPTION_PRIVILEGED} 338 * providing the physical slot ID of the target slot. 339 * 340 * <p>Expected type of the extra data: int 341 * 342 * @hide 343 */ 344 // TODO: Make this a @SystemApi. 345 public static final String EXTRA_PHYSICAL_SLOT_ID = 346 "android.telephony.euicc.extra.PHYSICAL_SLOT_ID"; 347 348 /** 349 * Optional meta-data attribute for a carrier app providing an icon to use to represent the 350 * carrier. If not provided, the app's launcher icon will be used as a fallback. 351 */ 352 public static final String META_DATA_CARRIER_ICON = "android.telephony.euicc.carriericon"; 353 354 /** 355 * Euicc activation type which will be included in {@link #EXTRA_ACTIVATION_TYPE} and used to 356 * decide which kind of activation flow should be lauched. 357 * 358 * @hide 359 */ 360 @Retention(RetentionPolicy.SOURCE) 361 @IntDef(prefix = {"EUICC_ACTIVATION_"}, value = { 362 EUICC_ACTIVATION_TYPE_DEFAULT, 363 EUICC_ACTIVATION_TYPE_BACKUP, 364 EUICC_ACTIVATION_TYPE_TRANSFER, 365 EUICC_ACTIVATION_TYPE_ACCOUNT_REQUIRED, 366 }) 367 public @interface EuiccActivationType{} 368 369 370 /** 371 * The default euicc activation type which includes checking server side and downloading the 372 * profile based on carrier's download configuration. 373 * 374 * @hide 375 */ 376 @SystemApi 377 public static final int EUICC_ACTIVATION_TYPE_DEFAULT = 1; 378 379 /** 380 * The euicc activation type used when the default download process failed. LPA will start the 381 * backup flow and try to download the profile for the carrier. 382 * 383 * @hide 384 */ 385 @SystemApi 386 public static final int EUICC_ACTIVATION_TYPE_BACKUP = 2; 387 388 /** 389 * The activation flow of eSIM seamless transfer will be used. LPA will start normal eSIM 390 * activation flow and if it's failed, the name of the carrier selected will be recorded. After 391 * the future device pairing, LPA will contact this carrier to transfer it from the other device 392 * to this device. 393 * 394 * @hide 395 */ 396 @SystemApi 397 public static final int EUICC_ACTIVATION_TYPE_TRANSFER = 3; 398 399 /** 400 * The activation flow of eSIM requiring user account will be started. This can only be used 401 * when there is user account signed in. Otherwise, the flow will be failed. 402 * 403 * @hide 404 */ 405 @SystemApi 406 public static final int EUICC_ACTIVATION_TYPE_ACCOUNT_REQUIRED = 4; 407 408 /** 409 * Euicc OTA update status which can be got by {@link #getOtaStatus} 410 * @hide 411 */ 412 @SystemApi 413 @Retention(RetentionPolicy.SOURCE) 414 @IntDef(prefix = {"EUICC_OTA_"}, value = { 415 EUICC_OTA_IN_PROGRESS, 416 EUICC_OTA_FAILED, 417 EUICC_OTA_SUCCEEDED, 418 EUICC_OTA_NOT_NEEDED, 419 EUICC_OTA_STATUS_UNAVAILABLE 420 421 }) 422 public @interface OtaStatus{} 423 424 /** 425 * An OTA is in progress. During this time, the eUICC is not available and the user may lose 426 * network access. 427 * @hide 428 */ 429 @SystemApi 430 public static final int EUICC_OTA_IN_PROGRESS = 1; 431 432 /** 433 * The OTA update failed. 434 * @hide 435 */ 436 @SystemApi 437 public static final int EUICC_OTA_FAILED = 2; 438 439 /** 440 * The OTA update finished successfully. 441 * @hide 442 */ 443 @SystemApi 444 public static final int EUICC_OTA_SUCCEEDED = 3; 445 446 /** 447 * The OTA update not needed since current eUICC OS is latest. 448 * @hide 449 */ 450 @SystemApi 451 public static final int EUICC_OTA_NOT_NEEDED = 4; 452 453 /** 454 * The OTA status is unavailable since eUICC service is unavailable. 455 * @hide 456 */ 457 @SystemApi 458 public static final int EUICC_OTA_STATUS_UNAVAILABLE = 5; 459 460 private final Context mContext; 461 private int mCardId; 462 463 /** @hide */ EuiccManager(Context context)464 public EuiccManager(Context context) { 465 mContext = context; 466 TelephonyManager tm = (TelephonyManager) 467 context.getSystemService(Context.TELEPHONY_SERVICE); 468 mCardId = tm.getCardIdForDefaultEuicc(); 469 } 470 471 /** @hide */ EuiccManager(Context context, int cardId)472 private EuiccManager(Context context, int cardId) { 473 mContext = context; 474 mCardId = cardId; 475 } 476 477 /** 478 * Create a new EuiccManager object pinned to the given card ID. 479 * 480 * @return an EuiccManager that uses the given card ID for all calls. 481 */ 482 @NonNull createForCardId(int cardId)483 public EuiccManager createForCardId(int cardId) { 484 return new EuiccManager(mContext, cardId); 485 } 486 487 /** 488 * Whether embedded subscriptions are currently enabled. 489 * 490 * <p>Even on devices with the {@link PackageManager#FEATURE_TELEPHONY_EUICC} feature, embedded 491 * subscriptions may be turned off, e.g. because of a carrier restriction from an inserted 492 * physical SIM. Therefore, this runtime check should be used before accessing embedded 493 * subscription APIs. 494 * 495 * @return true if embedded subscriptions are currently enabled. 496 */ isEnabled()497 public boolean isEnabled() { 498 // In the future, this may reach out to IEuiccController (if non-null) to check any dynamic 499 // restrictions. 500 return getIEuiccController() != null && refreshCardIdIfUninitialized(); 501 } 502 503 /** 504 * Returns the EID identifying the eUICC hardware. 505 * 506 * <p>Requires that the calling app has carrier privileges on the active subscription on the 507 * current eUICC. A calling app with carrier privileges for one eUICC may not necessarily have 508 * access to the EID of another eUICC. 509 * 510 * @return the EID. May be null if the eUICC is not ready. 511 */ 512 @Nullable getEid()513 public String getEid() { 514 if (!isEnabled()) { 515 return null; 516 } 517 try { 518 return getIEuiccController().getEid(mCardId, mContext.getOpPackageName()); 519 } catch (RemoteException e) { 520 throw e.rethrowFromSystemServer(); 521 } 522 } 523 524 /** 525 * Returns the current status of eUICC OTA. 526 * 527 * <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. 528 * 529 * @return the status of eUICC OTA. If the eUICC is not ready, 530 * {@link OtaStatus#EUICC_OTA_STATUS_UNAVAILABLE} will be returned. 531 * 532 * @hide 533 */ 534 @SystemApi 535 @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) getOtaStatus()536 public int getOtaStatus() { 537 if (!isEnabled()) { 538 return EUICC_OTA_STATUS_UNAVAILABLE; 539 } 540 try { 541 return getIEuiccController().getOtaStatus(mCardId); 542 } catch (RemoteException e) { 543 throw e.rethrowFromSystemServer(); 544 } 545 } 546 547 /** 548 * Attempt to download the given {@link DownloadableSubscription}. 549 * 550 * <p>Requires the {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission, 551 * or the calling app must be authorized to manage both the currently-active subscription on the 552 * current eUICC and the subscription to be downloaded according to the subscription metadata. 553 * Without the former, an {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR} will be 554 * returned in the callback intent to prompt the user to accept the download. 555 * 556 * <p>On a multi-active SIM device, requires the 557 * {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission, or a calling app 558 * only if the targeted eUICC does not currently have an active subscription or the calling app 559 * is authorized to manage the active subscription on the target eUICC, and the calling app is 560 * authorized to manage any active subscription on any SIM. Without it, an 561 * {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR} will be returned in the callback 562 * intent to prompt the user to accept the download. The caller should also be authorized to 563 * manage the subscription to be downloaded. 564 * 565 * @param subscription the subscription to download. 566 * @param switchAfterDownload if true, the profile will be activated upon successful download. 567 * @param callbackIntent a PendingIntent to launch when the operation completes. 568 */ 569 @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) downloadSubscription(DownloadableSubscription subscription, boolean switchAfterDownload, PendingIntent callbackIntent)570 public void downloadSubscription(DownloadableSubscription subscription, 571 boolean switchAfterDownload, PendingIntent callbackIntent) { 572 if (!isEnabled()) { 573 sendUnavailableError(callbackIntent); 574 return; 575 } 576 try { 577 getIEuiccController().downloadSubscription(mCardId, subscription, switchAfterDownload, 578 mContext.getOpPackageName(), null /* resolvedBundle */, callbackIntent); 579 } catch (RemoteException e) { 580 throw e.rethrowFromSystemServer(); 581 } 582 } 583 584 /** 585 * Start an activity to resolve a user-resolvable error. 586 * 587 * <p>If an operation returns {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR}, this 588 * method may be called to prompt the user to resolve the issue. 589 * 590 * <p>This method may only be called once for a particular error. 591 * 592 * @param activity the calling activity (which should be in the foreground). 593 * @param requestCode an application-specific request code which will be provided to 594 * {@link Activity#onActivityResult} upon completion. Note that the operation may still be 595 * in progress when the resolution activity completes; it is not fully finished until the 596 * callback intent is triggered. 597 * @param resultIntent the Intent provided to the initial callback intent which failed with 598 * {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR}. 599 * @param callbackIntent a PendingIntent to launch when the operation completes. This is 600 * trigered upon completion of the original operation that required user resolution. 601 * @throws android.content.IntentSender.SendIntentException if called more than once. 602 */ startResolutionActivity(Activity activity, int requestCode, Intent resultIntent, PendingIntent callbackIntent)603 public void startResolutionActivity(Activity activity, int requestCode, Intent resultIntent, 604 PendingIntent callbackIntent) throws IntentSender.SendIntentException { 605 PendingIntent resolutionIntent = 606 resultIntent.getParcelableExtra(EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT); 607 if (resolutionIntent == null) { 608 throw new IllegalArgumentException("Invalid result intent"); 609 } 610 Intent fillInIntent = new Intent(); 611 fillInIntent.putExtra(EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT, 612 callbackIntent); 613 activity.startIntentSenderForResult(resolutionIntent.getIntentSender(), requestCode, 614 fillInIntent, 0 /* flagsMask */, 0 /* flagsValues */, 0 /* extraFlags */); 615 } 616 617 /** 618 * Continue an operation after the user resolves an error. 619 * 620 * <p>To be called by the LUI upon completion of a resolvable error flow. 621 * 622 * <p>Requires that the calling app has the 623 * {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. 624 * 625 * @param resolutionIntent The original intent used to start the LUI. 626 * @param resolutionExtras Resolution-specific extras depending on the result of the resolution. 627 * For example, this may indicate whether the user has consented or may include the input 628 * they provided. 629 * @hide 630 */ 631 @SystemApi 632 @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) continueOperation(Intent resolutionIntent, Bundle resolutionExtras)633 public void continueOperation(Intent resolutionIntent, Bundle resolutionExtras) { 634 if (!isEnabled()) { 635 PendingIntent callbackIntent = 636 resolutionIntent.getParcelableExtra( 637 EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT); 638 if (callbackIntent != null) { 639 sendUnavailableError(callbackIntent); 640 } 641 return; 642 } 643 try { 644 getIEuiccController().continueOperation(mCardId, resolutionIntent, resolutionExtras); 645 } catch (RemoteException e) { 646 throw e.rethrowFromSystemServer(); 647 } 648 } 649 650 /** 651 * Fills in the metadata for a DownloadableSubscription. 652 * 653 * <p>May be used in cases that a DownloadableSubscription was constructed to download a 654 * profile, but the metadata for the profile is unknown (e.g. we only know the activation code). 655 * The callback will be triggered with an Intent with 656 * {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION} set to the 657 * downloadable subscription metadata upon success. 658 * 659 * <p>Requires that the calling app has the 660 * {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. This is for 661 * internal system use only. 662 * 663 * @param subscription the subscription which needs metadata filled in 664 * @param callbackIntent a PendingIntent to launch when the operation completes. 665 * @hide 666 */ 667 @SystemApi 668 @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) getDownloadableSubscriptionMetadata( DownloadableSubscription subscription, PendingIntent callbackIntent)669 public void getDownloadableSubscriptionMetadata( 670 DownloadableSubscription subscription, PendingIntent callbackIntent) { 671 if (!isEnabled()) { 672 sendUnavailableError(callbackIntent); 673 return; 674 } 675 try { 676 getIEuiccController().getDownloadableSubscriptionMetadata(mCardId, subscription, 677 mContext.getOpPackageName(), callbackIntent); 678 } catch (RemoteException e) { 679 throw e.rethrowFromSystemServer(); 680 } 681 } 682 683 /** 684 * Gets metadata for subscription which are available for download on this device. 685 * 686 * <p>Subscriptions returned here may be passed to {@link #downloadSubscription}. They may have 687 * been pre-assigned to this particular device, for example. The callback will be triggered with 688 * an Intent with {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS} set to the 689 * list of available subscriptions upon success. 690 * 691 * <p>Requires that the calling app has the 692 * {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. This is for 693 * internal system use only. 694 * 695 * @param callbackIntent a PendingIntent to launch when the operation completes. 696 * @hide 697 */ 698 @SystemApi 699 @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) getDefaultDownloadableSubscriptionList(PendingIntent callbackIntent)700 public void getDefaultDownloadableSubscriptionList(PendingIntent callbackIntent) { 701 if (!isEnabled()) { 702 sendUnavailableError(callbackIntent); 703 return; 704 } 705 try { 706 getIEuiccController().getDefaultDownloadableSubscriptionList(mCardId, 707 mContext.getOpPackageName(), callbackIntent); 708 } catch (RemoteException e) { 709 throw e.rethrowFromSystemServer(); 710 } 711 } 712 713 /** 714 * Returns information about the eUICC chip/device. 715 * 716 * @return the {@link EuiccInfo}. May be null if the eUICC is not ready. 717 */ 718 @Nullable getEuiccInfo()719 public EuiccInfo getEuiccInfo() { 720 if (!isEnabled()) { 721 return null; 722 } 723 try { 724 return getIEuiccController().getEuiccInfo(mCardId); 725 } catch (RemoteException e) { 726 throw e.rethrowFromSystemServer(); 727 } 728 } 729 730 /** 731 * Deletes the given subscription. 732 * 733 * <p>If this subscription is currently active, the device will first switch away from it onto 734 * an "empty" subscription. 735 * 736 * <p>Requires that the calling app has carrier privileges according to the metadata of the 737 * profile to be deleted, or the 738 * {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. 739 * 740 * @param subscriptionId the ID of the subscription to delete. 741 * @param callbackIntent a PendingIntent to launch when the operation completes. 742 */ 743 @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) deleteSubscription(int subscriptionId, PendingIntent callbackIntent)744 public void deleteSubscription(int subscriptionId, PendingIntent callbackIntent) { 745 if (!isEnabled()) { 746 sendUnavailableError(callbackIntent); 747 return; 748 } 749 try { 750 getIEuiccController().deleteSubscription(mCardId, 751 subscriptionId, mContext.getOpPackageName(), callbackIntent); 752 } catch (RemoteException e) { 753 throw e.rethrowFromSystemServer(); 754 } 755 } 756 757 /** 758 * Switch to (enable) the given subscription. 759 * 760 * <p>Requires the {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission, 761 * or the calling app must be authorized to manage both the currently-active subscription and 762 * the subscription to be enabled according to the subscription metadata. Without the former, 763 * an {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR} will be returned in the callback 764 * intent to prompt the user to accept the download. 765 * 766 * <p>On a multi-active SIM device, requires the 767 * {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission, or a calling app 768 * only if the targeted eUICC does not currently have an active subscription or the calling app 769 * is authorized to manage the active subscription on the target eUICC, and the calling app is 770 * authorized to manage any active subscription on any SIM. Without it, an 771 * {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR} will be returned in the callback 772 * intent to prompt the user to accept the download. The caller should also be authorized to 773 * manage the subscription to be enabled. 774 * 775 * @param subscriptionId the ID of the subscription to enable. May be 776 * {@link android.telephony.SubscriptionManager#INVALID_SUBSCRIPTION_ID} to deactivate the 777 * current profile without activating another profile to replace it. If it's a disable 778 * operation, requires the {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} 779 * permission, or the calling app must be authorized to manage the active subscription on 780 * the target eUICC. 781 * @param callbackIntent a PendingIntent to launch when the operation completes. 782 */ 783 @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) switchToSubscription(int subscriptionId, PendingIntent callbackIntent)784 public void switchToSubscription(int subscriptionId, PendingIntent callbackIntent) { 785 if (!isEnabled()) { 786 sendUnavailableError(callbackIntent); 787 return; 788 } 789 try { 790 getIEuiccController().switchToSubscription(mCardId, 791 subscriptionId, mContext.getOpPackageName(), callbackIntent); 792 } catch (RemoteException e) { 793 throw e.rethrowFromSystemServer(); 794 } 795 } 796 797 /** 798 * Update the nickname for the given subscription. 799 * 800 * <p>Requires that the calling app has carrier privileges according to the metadata of the 801 * profile to be updated, or the 802 * {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. 803 * 804 * @param subscriptionId the ID of the subscription to update. 805 * @param nickname the new nickname to apply. 806 * @param callbackIntent a PendingIntent to launch when the operation completes. 807 */ 808 @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) updateSubscriptionNickname( int subscriptionId, @Nullable String nickname, @NonNull PendingIntent callbackIntent)809 public void updateSubscriptionNickname( 810 int subscriptionId, @Nullable String nickname, @NonNull PendingIntent callbackIntent) { 811 if (!isEnabled()) { 812 sendUnavailableError(callbackIntent); 813 return; 814 } 815 try { 816 getIEuiccController().updateSubscriptionNickname(mCardId, 817 subscriptionId, nickname, mContext.getOpPackageName(), callbackIntent); 818 } catch (RemoteException e) { 819 throw e.rethrowFromSystemServer(); 820 } 821 } 822 823 /** 824 * Erase all subscriptions and reset the eUICC. 825 * 826 * <p>Requires that the calling app has the 827 * {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. 828 * 829 * @param callbackIntent a PendingIntent to launch when the operation completes. 830 * @hide 831 */ 832 @SystemApi 833 @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) eraseSubscriptions(PendingIntent callbackIntent)834 public void eraseSubscriptions(PendingIntent callbackIntent) { 835 if (!isEnabled()) { 836 sendUnavailableError(callbackIntent); 837 return; 838 } 839 try { 840 getIEuiccController().eraseSubscriptions(mCardId, callbackIntent); 841 } catch (RemoteException e) { 842 throw e.rethrowFromSystemServer(); 843 } 844 } 845 846 /** 847 * Ensure that subscriptions will be retained on the next factory reset. 848 * 849 * <p>By default, all subscriptions on the eUICC are erased the first time a device boots (ever 850 * and after factory resets). This ensures that the data is wiped after a factory reset is 851 * performed via fastboot or recovery mode, as these modes do not support the necessary radio 852 * communication needed to wipe the eSIM. 853 * 854 * <p>However, this method may be called right before a factory reset issued via settings when 855 * the user elects to retain subscriptions. Doing so will mark them for retention so that they 856 * are not cleared after the ensuing reset. 857 * 858 * <p>Requires that the calling app has the {@link android.Manifest.permission#MASTER_CLEAR} 859 * permission. This is for internal system use only. 860 * 861 * @param callbackIntent a PendingIntent to launch when the operation completes. 862 * @hide 863 */ retainSubscriptionsForFactoryReset(PendingIntent callbackIntent)864 public void retainSubscriptionsForFactoryReset(PendingIntent callbackIntent) { 865 if (!isEnabled()) { 866 sendUnavailableError(callbackIntent); 867 return; 868 } 869 try { 870 getIEuiccController().retainSubscriptionsForFactoryReset(mCardId, callbackIntent); 871 } catch (RemoteException e) { 872 throw e.rethrowFromSystemServer(); 873 } 874 } 875 876 /** 877 * Refreshes the cardId if its uninitialized, and returns whether we should continue the 878 * operation. 879 * <p> 880 * Note that after a successful refresh, the mCardId may be TelephonyManager.UNSUPPORTED_CARD_ID 881 * on older HALs. For backwards compatability, we continue to the LPA and let it decide which 882 * card to use. 883 */ refreshCardIdIfUninitialized()884 private boolean refreshCardIdIfUninitialized() { 885 // Refresh mCardId if its UNINITIALIZED_CARD_ID 886 if (mCardId == TelephonyManager.UNINITIALIZED_CARD_ID) { 887 TelephonyManager tm = (TelephonyManager) 888 mContext.getSystemService(Context.TELEPHONY_SERVICE); 889 mCardId = tm.getCardIdForDefaultEuicc(); 890 } 891 if (mCardId == TelephonyManager.UNINITIALIZED_CARD_ID) { 892 return false; 893 } 894 return true; 895 } 896 sendUnavailableError(PendingIntent callbackIntent)897 private static void sendUnavailableError(PendingIntent callbackIntent) { 898 try { 899 callbackIntent.send(EMBEDDED_SUBSCRIPTION_RESULT_ERROR); 900 } catch (PendingIntent.CanceledException e) { 901 // Caller canceled the callback; do nothing. 902 } 903 } 904 getIEuiccController()905 private static IEuiccController getIEuiccController() { 906 return IEuiccController.Stub.asInterface(ServiceManager.getService("econtroller")); 907 } 908 } 909