blob: cde10ea7cd090400c14cc24420733bd9de842f20 [file] [log] [blame]
Jeff Davidson35cda392017-02-27 09:46:00 -08001/*
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 */
16package android.telephony.euicc;
17
Holly Jiuyu Sund60a07f02018-03-13 17:20:07 -070018import android.Manifest;
Qingxi Li54058362017-12-13 15:13:02 -080019import android.annotation.IntDef;
Jordan Liu260189c2019-02-28 11:38:40 -080020import android.annotation.NonNull;
Jeff Davidson35cda392017-02-27 09:46:00 -080021import android.annotation.Nullable;
Holly Jiuyu Sund60a07f02018-03-13 17:20:07 -070022import android.annotation.RequiresPermission;
Jeff Davidson35cda392017-02-27 09:46:00 -080023import android.annotation.SdkConstant;
Qingxi Li54058362017-12-13 15:13:02 -080024import android.annotation.SystemApi;
Jeff Davidson35cda392017-02-27 09:46:00 -080025import android.app.Activity;
26import android.app.PendingIntent;
27import android.content.Context;
28import android.content.Intent;
Jeff Davidsoncfa70fa2017-04-06 16:02:36 -070029import android.content.IntentSender;
Jeff Davidson35cda392017-02-27 09:46:00 -080030import android.content.pm.PackageManager;
Jeff Davidsoncfa70fa2017-04-06 16:02:36 -070031import android.os.Bundle;
Jeff Davidson35cda392017-02-27 09:46:00 -080032import android.os.RemoteException;
33import android.os.ServiceManager;
Jordan Liuc1c89e42018-12-10 16:10:16 -080034import android.telephony.TelephonyManager;
Jeff Davidson35cda392017-02-27 09:46:00 -080035
36import com.android.internal.telephony.euicc.IEuiccController;
37
Qingxi Li54058362017-12-13 15:13:02 -080038import java.lang.annotation.Retention;
39import java.lang.annotation.RetentionPolicy;
40
Jeff Davidson35cda392017-02-27 09:46:00 -080041/**
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
Jordan Liuc1c89e42018-12-10 16:10:16 -080045 * {@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}.
Jeff Davidson35cda392017-02-27 09:46:00 -080050 *
51 * <p>See {@link #isEnabled} before attempting to use these APIs.
Jeff Davidson35cda392017-02-27 09:46:00 -080052 */
53public 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.
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -080063 *
64 * This is ued by non-LPA app to bring up LUI.
Jeff Davidson35cda392017-02-27 09:46:00 -080065 */
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
Qingxi Li6019f9c2017-12-14 15:36:06 -080070 /**
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.
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -080077 *
78 * @hide
Qingxi Li6019f9c2017-12-14 15:36:06 -080079 */
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -080080 @SystemApi
Qingxi Li6019f9c2017-12-14 15:36:06 -080081 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
Holly Jiuyu Sund60a07f02018-03-13 17:20:07 -070082 @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
Qingxi Lica8c90a2018-01-19 12:24:05 -080083 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.
Qingxi Lica8c90a2018-01-19 12:24:05 -080089 */
90 @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -080091 public static final String ACTION_NOTIFY_CARRIER_SETUP_INCOMPLETE =
92 "android.telephony.euicc.action.NOTIFY_CARRIER_SETUP_INCOMPLETE";
Qingxi Li6019f9c2017-12-14 15:36:06 -080093
Jeff Davidson35cda392017-02-27 09:46:00 -080094 /**
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
Qingxi Li2d7f90c2017-11-30 18:49:00 -0800102 * {@link #isEnabled} is false.
Jeff Davidson35cda392017-02-27 09:46:00 -0800103 *
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -0800104 * @hide
Jeff Davidson35cda392017-02-27 09:46:00 -0800105 */
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -0800106 @SystemApi
Jeff Davidson35cda392017-02-27 09:46:00 -0800107 @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 /**
Jeff Davidsoncfa70fa2017-04-06 16:02:36 -0700112 * 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 /**
Patrick Huangf43a0cc2019-01-14 17:47:56 -0800119 * 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
Patrick Huang0d081f42019-03-19 14:58:51 -0700121 * {@link #EXTRA_ENABLE_SUBSCRIPTION}, and optionally {@link #EXTRA_FROM_SUBSCRIPTION_ID}.
Patrick Huangf43a0cc2019-01-14 17:47:56 -0800122 *
Patrick Huang0d081f42019-03-19 14:58:51 -0700123 * <p>Requires the caller to be a privileged process with the
Patrick Huang8002fe42019-03-14 19:25:47 -0700124 * {@link android.permission#CALL_PRIVILEGED} permission for the intent to reach the Telephony
125 * stack.
126 *
Patrick Huangf43a0cc2019-01-14 17:47:56 -0800127 * <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 *
Patrick Huang0d081f42019-03-19 14:58:51 -0700146 * <p>Requires the caller to be a privileged process with the
Patrick Huang8002fe42019-03-14 19:25:47 -0700147 * {@link android.permission#CALL_PRIVILEGED} permission for the intent to reach the Telephony
148 * stack.
149 *
Patrick Huangf43a0cc2019-01-14 17:47:56 -0800150 * <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 *
Patrick Huang0d081f42019-03-19 14:58:51 -0700170 * <p>Requires the caller to be a privileged process with the
Patrick Huang8002fe42019-03-14 19:25:47 -0700171 * {@link android.permission#CALL_PRIVILEGED} permission for the intent to reach the Telephony
172 * stack.
173 *
Patrick Huangf43a0cc2019-01-14 17:47:56 -0800174 * <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 /**
Jeff Davidson35cda392017-02-27 09:46:00 -0800191 * 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 /**
Jeff Davidson83f8bc82017-05-15 10:22:20 -0700204 * Result code for an operation indicating that an unresolvable error occurred.
Jeff Davidson35cda392017-02-27 09:46:00 -0800205 *
Jeff Davidson83f8bc82017-05-15 10:22:20 -0700206 * {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE} will be populated with a detailed error
207 * code for logging/debugging purposes only.
Jeff Davidson35cda392017-02-27 09:46:00 -0800208 */
Jeff Davidson83f8bc82017-05-15 10:22:20 -0700209 public static final int EMBEDDED_SUBSCRIPTION_RESULT_ERROR = 2;
Jeff Davidson35cda392017-02-27 09:46:00 -0800210
211 /**
Qingxi Lif697be52018-12-19 13:50:22 -0800212 * 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 /**
Jeff Davidson35cda392017-02-27 09:46:00 -0800222 * 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 /**
Holly Jiuyu Sun59159c42018-03-15 18:06:42 -0700232 * Key for an extra set on {@code #getDownloadableSubscriptionMetadata} PendingIntent result
Jeff Davidson35cda392017-02-27 09:46:00 -0800233 * callbacks providing the downloadable subscription metadata.
Jeff Davidson35cda392017-02-27 09:46:00 -0800234 */
235 public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION =
236 "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION";
237
Jeff Davidsoncfa70fa2017-04-06 16:02:36 -0700238 /**
Jeff Davidson91c3d072017-04-12 12:17:11 -0700239 * Key for an extra set on {@link #getDefaultDownloadableSubscriptionList} PendingIntent result
240 * callbacks providing the list of available downloadable subscriptions.
241 * @hide
Jeff Davidson91c3d072017-04-12 12:17:11 -0700242 */
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -0800243 @SystemApi
Jeff Davidson91c3d072017-04-12 12:17:11 -0700244 public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS =
245 "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS";
246
247 /**
Jeff Davidsoncfa70fa2017-04-06 16:02:36 -0700248 * 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
Jeff Davidsonf0d8c892017-06-13 12:39:59 -0700271 /**
qingxicfffe752017-08-14 14:28:27 -0700272 * Key for an extra set on the {@link #ACTION_PROVISION_EMBEDDED_SUBSCRIPTION} intent for
Qingxi Li4b527772019-03-11 19:22:32 -0700273 * 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.
qingxicfffe752017-08-14 14:28:27 -0700277 * @hide
278 */
Qingxi Licfb6e7b2018-11-12 18:00:20 -0800279 @SystemApi
qingxicfffe752017-08-14 14:28:27 -0700280 public static final String EXTRA_FORCE_PROVISION =
281 "android.telephony.euicc.extra.FORCE_PROVISION";
282
283 /**
Patrick Huangf43a0cc2019-01-14 17:47:56 -0800284 * 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 *
Patrick Huang4db3a992019-03-18 15:56:39 -0700288 * <p>Expected type of the extra data: int
289 *
Patrick Huangf43a0cc2019-01-14 17:47:56 -0800290 * @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 *
Patrick Huang4db3a992019-03-18 15:56:39 -0700300 * <p>Expected type of the extra data: boolean
301 *
Patrick Huangf43a0cc2019-01-14 17:47:56 -0800302 * @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 *
Patrick Huang4db3a992019-03-18 15:56:39 -0700312 * <p>Expected type of the extra data: String
313 *
Patrick Huangf43a0cc2019-01-14 17:47:56 -0800314 * @hide
315 */
316 @SystemApi
317 public static final String EXTRA_SUBSCRIPTION_NICKNAME =
318 "android.telephony.euicc.extra.SUBSCRIPTION_NICKNAME";
319
320 /**
Patrick Huang0d081f42019-03-19 14:58:51 -0700321 * 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 /**
Jeff Davidsonf0d8c892017-06-13 12:39:59 -0700337 * Optional meta-data attribute for a carrier app providing an icon to use to represent the
338 * carrier. If not provided, the app's launcher icon will be used as a fallback.
339 */
340 public static final String META_DATA_CARRIER_ICON = "android.telephony.euicc.carriericon";
341
Qingxi Li54058362017-12-13 15:13:02 -0800342 /**
Qingxi Lif697be52018-12-19 13:50:22 -0800343 * Euicc activation type which will be included in {@link #EXTRA_ACTIVATION_TYPE} and used to
344 * decide which kind of activation flow should be lauched.
345 *
346 * @hide
347 */
348 @Retention(RetentionPolicy.SOURCE)
349 @IntDef(prefix = {"EUICC_ACTIVATION_"}, value = {
350 EUICC_ACTIVATION_TYPE_DEFAULT,
351 EUICC_ACTIVATION_TYPE_BACKUP,
Qingxi Lid1a57f22019-01-22 20:14:52 -0800352 EUICC_ACTIVATION_TYPE_TRANSFER,
353 EUICC_ACTIVATION_TYPE_ACCOUNT_REQUIRED,
Qingxi Lif697be52018-12-19 13:50:22 -0800354 })
355 public @interface EuiccActivationType{}
356
357
358 /**
359 * The default euicc activation type which includes checking server side and downloading the
360 * profile based on carrier's download configuration.
361 *
362 * @hide
363 */
364 @SystemApi
365 public static final int EUICC_ACTIVATION_TYPE_DEFAULT = 1;
366
367 /**
368 * The euicc activation type used when the default download process failed. LPA will start the
369 * backup flow and try to download the profile for the carrier.
370 *
371 * @hide
372 */
373 @SystemApi
374 public static final int EUICC_ACTIVATION_TYPE_BACKUP = 2;
375
376 /**
377 * The activation flow of eSIM seamless transfer will be used. LPA will start normal eSIM
378 * activation flow and if it's failed, the name of the carrier selected will be recorded. After
379 * the future device pairing, LPA will contact this carrier to transfer it from the other device
380 * to this device.
381 *
382 * @hide
383 */
384 @SystemApi
385 public static final int EUICC_ACTIVATION_TYPE_TRANSFER = 3;
386
Qingxi Lid1a57f22019-01-22 20:14:52 -0800387 /**
388 * The activation flow of eSIM requiring user account will be started. This can only be used
389 * when there is user account signed in. Otherwise, the flow will be failed.
390 *
391 * @hide
392 */
393 @SystemApi
394 public static final int EUICC_ACTIVATION_TYPE_ACCOUNT_REQUIRED = 4;
Qingxi Lif697be52018-12-19 13:50:22 -0800395
396 /**
Qingxi Li54058362017-12-13 15:13:02 -0800397 * Euicc OTA update status which can be got by {@link #getOtaStatus}
398 * @hide
399 */
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -0800400 @SystemApi
Qingxi Li54058362017-12-13 15:13:02 -0800401 @Retention(RetentionPolicy.SOURCE)
402 @IntDef(prefix = {"EUICC_OTA_"}, value = {
403 EUICC_OTA_IN_PROGRESS,
404 EUICC_OTA_FAILED,
405 EUICC_OTA_SUCCEEDED,
406 EUICC_OTA_NOT_NEEDED,
407 EUICC_OTA_STATUS_UNAVAILABLE
408
409 })
410 public @interface OtaStatus{}
411
412 /**
413 * An OTA is in progress. During this time, the eUICC is not available and the user may lose
414 * network access.
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -0800415 * @hide
Qingxi Li54058362017-12-13 15:13:02 -0800416 */
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -0800417 @SystemApi
Qingxi Li54058362017-12-13 15:13:02 -0800418 public static final int EUICC_OTA_IN_PROGRESS = 1;
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -0800419
420 /**
421 * The OTA update failed.
422 * @hide
423 */
424 @SystemApi
Qingxi Li54058362017-12-13 15:13:02 -0800425 public static final int EUICC_OTA_FAILED = 2;
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -0800426
427 /**
428 * The OTA update finished successfully.
429 * @hide
430 */
431 @SystemApi
Qingxi Li54058362017-12-13 15:13:02 -0800432 public static final int EUICC_OTA_SUCCEEDED = 3;
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -0800433
434 /**
435 * The OTA update not needed since current eUICC OS is latest.
436 * @hide
437 */
438 @SystemApi
Qingxi Li54058362017-12-13 15:13:02 -0800439 public static final int EUICC_OTA_NOT_NEEDED = 4;
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -0800440
441 /**
442 * The OTA status is unavailable since eUICC service is unavailable.
443 * @hide
444 */
445 @SystemApi
Qingxi Li54058362017-12-13 15:13:02 -0800446 public static final int EUICC_OTA_STATUS_UNAVAILABLE = 5;
447
Jeff Davidson35cda392017-02-27 09:46:00 -0800448 private final Context mContext;
Holly Jiuyu Sunb94f8d32019-01-30 15:25:24 -0800449 private int mCardId;
Jeff Davidson35cda392017-02-27 09:46:00 -0800450
451 /** @hide */
452 public EuiccManager(Context context) {
453 mContext = context;
Jordan Liuc1c89e42018-12-10 16:10:16 -0800454 TelephonyManager tm = (TelephonyManager)
455 context.getSystemService(Context.TELEPHONY_SERVICE);
456 mCardId = tm.getCardIdForDefaultEuicc();
457 }
458
459 /** @hide */
460 private EuiccManager(Context context, int cardId) {
461 mContext = context;
462 mCardId = cardId;
463 }
464
465 /**
466 * Create a new EuiccManager object pinned to the given card ID.
467 *
468 * @return an EuiccManager that uses the given card ID for all calls.
469 */
Jordan Liu260189c2019-02-28 11:38:40 -0800470 @NonNull
Jordan Liuc1c89e42018-12-10 16:10:16 -0800471 public EuiccManager createForCardId(int cardId) {
472 return new EuiccManager(mContext, cardId);
Jeff Davidson35cda392017-02-27 09:46:00 -0800473 }
474
475 /**
476 * Whether embedded subscriptions are currently enabled.
477 *
478 * <p>Even on devices with the {@link PackageManager#FEATURE_TELEPHONY_EUICC} feature, embedded
479 * subscriptions may be turned off, e.g. because of a carrier restriction from an inserted
480 * physical SIM. Therefore, this runtime check should be used before accessing embedded
481 * subscription APIs.
482 *
483 * @return true if embedded subscriptions are currently enabled.
484 */
485 public boolean isEnabled() {
486 // In the future, this may reach out to IEuiccController (if non-null) to check any dynamic
487 // restrictions.
Holly Jiuyu Sunb94f8d32019-01-30 15:25:24 -0800488 return getIEuiccController() != null;
Jeff Davidson35cda392017-02-27 09:46:00 -0800489 }
490
491 /**
492 * Returns the EID identifying the eUICC hardware.
493 *
494 * <p>Requires that the calling app has carrier privileges on the active subscription on the
Jordan Liuc1c89e42018-12-10 16:10:16 -0800495 * current eUICC. A calling app with carrier privileges for one eUICC may not necessarily have
496 * access to the EID of another eUICC.
Jeff Davidson35cda392017-02-27 09:46:00 -0800497 *
Holly Jiuyu Sunb94f8d32019-01-30 15:25:24 -0800498 * @return the EID. May be null if the eUICC is not ready.
Jeff Davidson35cda392017-02-27 09:46:00 -0800499 */
500 @Nullable
501 public String getEid() {
Jordan Liucb47d1d2019-02-01 14:15:05 -0800502 if (!refreshCardIdIfUninitialized()) {
Jeff Davidson35cda392017-02-27 09:46:00 -0800503 return null;
504 }
505 try {
Holly Jiuyu Sun6bf03592019-01-17 14:41:14 -0800506 return getIEuiccController().getEid(mCardId, mContext.getOpPackageName());
Jeff Davidson35cda392017-02-27 09:46:00 -0800507 } catch (RemoteException e) {
508 throw e.rethrowFromSystemServer();
509 }
510 }
511
512 /**
Qingxi Li54058362017-12-13 15:13:02 -0800513 * Returns the current status of eUICC OTA.
514 *
515 * <p>Requires the {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
516 *
Holly Jiuyu Sunb94f8d32019-01-30 15:25:24 -0800517 * @return the status of eUICC OTA. If the eUICC is not ready,
518 * {@link OtaStatus#EUICC_OTA_STATUS_UNAVAILABLE} will be returned.
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -0800519 *
520 * @hide
Qingxi Li54058362017-12-13 15:13:02 -0800521 */
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -0800522 @SystemApi
Holly Jiuyu Sund60a07f02018-03-13 17:20:07 -0700523 @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
Qingxi Li54058362017-12-13 15:13:02 -0800524 public int getOtaStatus() {
Jordan Liucb47d1d2019-02-01 14:15:05 -0800525 if (!refreshCardIdIfUninitialized()) {
Qingxi Li54058362017-12-13 15:13:02 -0800526 return EUICC_OTA_STATUS_UNAVAILABLE;
527 }
528 try {
Jordan Liuc1c89e42018-12-10 16:10:16 -0800529 return getIEuiccController().getOtaStatus(mCardId);
Qingxi Li54058362017-12-13 15:13:02 -0800530 } catch (RemoteException e) {
531 throw e.rethrowFromSystemServer();
532 }
533 }
534
535 /**
Jeff Davidson35cda392017-02-27 09:46:00 -0800536 * Attempt to download the given {@link DownloadableSubscription}.
537 *
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -0800538 * <p>Requires the {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission,
Jordan Liuc1c89e42018-12-10 16:10:16 -0800539 * or the calling app must be authorized to manage both the currently-active subscription on the
540 * current eUICC and the subscription to be downloaded according to the subscription metadata.
541 * Without the former, an {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR} will be
542 * returned in the callback intent to prompt the user to accept the download.
Jeff Davidson35cda392017-02-27 09:46:00 -0800543 *
Holly Jiuyu Sun6bf03592019-01-17 14:41:14 -0800544 * <p>On a multi-active SIM device, requires the
545 * {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission, or a calling app
546 * only if the targeted eUICC does not currently have an active subscription or the calling app
547 * is authorized to manage the active subscription on the target eUICC, and the calling app is
548 * authorized to manage any active subscription on any SIM. Without it, an
549 * {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR} will be returned in the callback
550 * intent to prompt the user to accept the download. The caller should also be authorized to
551 * manage the subscription to be downloaded.
552 *
Jeff Davidson35cda392017-02-27 09:46:00 -0800553 * @param subscription the subscription to download.
554 * @param switchAfterDownload if true, the profile will be activated upon successful download.
555 * @param callbackIntent a PendingIntent to launch when the operation completes.
556 */
Holly Jiuyu Sund60a07f02018-03-13 17:20:07 -0700557 @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
Jeff Davidson35cda392017-02-27 09:46:00 -0800558 public void downloadSubscription(DownloadableSubscription subscription,
559 boolean switchAfterDownload, PendingIntent callbackIntent) {
Jordan Liucb47d1d2019-02-01 14:15:05 -0800560 if (!refreshCardIdIfUninitialized()) {
Jeff Davidson35cda392017-02-27 09:46:00 -0800561 sendUnavailableError(callbackIntent);
562 return;
563 }
564 try {
Jordan Liuc1c89e42018-12-10 16:10:16 -0800565 getIEuiccController().downloadSubscription(mCardId, subscription, switchAfterDownload,
Holly Jiuyu Sun881fe4c2018-10-24 20:16:04 -0700566 mContext.getOpPackageName(), null /* resolvedBundle */, callbackIntent);
Jeff Davidson35cda392017-02-27 09:46:00 -0800567 } catch (RemoteException e) {
568 throw e.rethrowFromSystemServer();
569 }
570 }
571
572 /**
573 * Start an activity to resolve a user-resolvable error.
574 *
575 * <p>If an operation returns {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR}, this
576 * method may be called to prompt the user to resolve the issue.
577 *
Jeff Davidsoncfa70fa2017-04-06 16:02:36 -0700578 * <p>This method may only be called once for a particular error.
579 *
Jeff Davidson35cda392017-02-27 09:46:00 -0800580 * @param activity the calling activity (which should be in the foreground).
581 * @param requestCode an application-specific request code which will be provided to
582 * {@link Activity#onActivityResult} upon completion. Note that the operation may still be
583 * in progress when the resolution activity completes; it is not fully finished until the
584 * callback intent is triggered.
585 * @param resultIntent the Intent provided to the initial callback intent which failed with
586 * {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR}.
587 * @param callbackIntent a PendingIntent to launch when the operation completes. This is
588 * trigered upon completion of the original operation that required user resolution.
Jeff Davidsoncfa70fa2017-04-06 16:02:36 -0700589 * @throws android.content.IntentSender.SendIntentException if called more than once.
Jeff Davidson35cda392017-02-27 09:46:00 -0800590 */
591 public void startResolutionActivity(Activity activity, int requestCode, Intent resultIntent,
Jeff Davidsoncfa70fa2017-04-06 16:02:36 -0700592 PendingIntent callbackIntent) throws IntentSender.SendIntentException {
593 PendingIntent resolutionIntent =
594 resultIntent.getParcelableExtra(EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_INTENT);
595 if (resolutionIntent == null) {
596 throw new IllegalArgumentException("Invalid result intent");
597 }
598 Intent fillInIntent = new Intent();
599 fillInIntent.putExtra(EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT,
600 callbackIntent);
601 activity.startIntentSenderForResult(resolutionIntent.getIntentSender(), requestCode,
602 fillInIntent, 0 /* flagsMask */, 0 /* flagsValues */, 0 /* extraFlags */);
603 }
604
605 /**
606 * Continue an operation after the user resolves an error.
607 *
608 * <p>To be called by the LUI upon completion of a resolvable error flow.
609 *
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -0800610 * <p>Requires that the calling app has the
611 * {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
612 *
Jeff Davidsoncfa70fa2017-04-06 16:02:36 -0700613 * @param resolutionIntent The original intent used to start the LUI.
614 * @param resolutionExtras Resolution-specific extras depending on the result of the resolution.
615 * For example, this may indicate whether the user has consented or may include the input
616 * they provided.
617 * @hide
618 */
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -0800619 @SystemApi
Holly Jiuyu Sund60a07f02018-03-13 17:20:07 -0700620 @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
Jeff Davidsoncfa70fa2017-04-06 16:02:36 -0700621 public void continueOperation(Intent resolutionIntent, Bundle resolutionExtras) {
Jordan Liucb47d1d2019-02-01 14:15:05 -0800622 if (!refreshCardIdIfUninitialized()) {
Jeff Davidsoncfa70fa2017-04-06 16:02:36 -0700623 PendingIntent callbackIntent =
624 resolutionIntent.getParcelableExtra(
625 EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT);
626 if (callbackIntent != null) {
627 sendUnavailableError(callbackIntent);
628 }
629 return;
630 }
631 try {
Jordan Liuc1c89e42018-12-10 16:10:16 -0800632 getIEuiccController().continueOperation(mCardId, resolutionIntent, resolutionExtras);
Jeff Davidsoncfa70fa2017-04-06 16:02:36 -0700633 } catch (RemoteException e) {
634 throw e.rethrowFromSystemServer();
635 }
Jeff Davidson35cda392017-02-27 09:46:00 -0800636 }
637
638 /**
639 * Fills in the metadata for a DownloadableSubscription.
640 *
641 * <p>May be used in cases that a DownloadableSubscription was constructed to download a
642 * profile, but the metadata for the profile is unknown (e.g. we only know the activation code).
643 * The callback will be triggered with an Intent with
644 * {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION} set to the
645 * downloadable subscription metadata upon success.
646 *
647 * <p>Requires that the calling app has the
648 * {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. This is for
649 * internal system use only.
650 *
651 * @param subscription the subscription which needs metadata filled in
652 * @param callbackIntent a PendingIntent to launch when the operation completes.
653 * @hide
Jeff Davidson35cda392017-02-27 09:46:00 -0800654 */
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -0800655 @SystemApi
Holly Jiuyu Sund60a07f02018-03-13 17:20:07 -0700656 @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
Jeff Davidson35cda392017-02-27 09:46:00 -0800657 public void getDownloadableSubscriptionMetadata(
658 DownloadableSubscription subscription, PendingIntent callbackIntent) {
Jordan Liucb47d1d2019-02-01 14:15:05 -0800659 if (!refreshCardIdIfUninitialized()) {
Jeff Davidson35cda392017-02-27 09:46:00 -0800660 sendUnavailableError(callbackIntent);
661 return;
662 }
663 try {
Jordan Liuc1c89e42018-12-10 16:10:16 -0800664 getIEuiccController().getDownloadableSubscriptionMetadata(mCardId, subscription,
665 mContext.getOpPackageName(), callbackIntent);
Jeff Davidson35cda392017-02-27 09:46:00 -0800666 } catch (RemoteException e) {
667 throw e.rethrowFromSystemServer();
668 }
669 }
670
Jeff Davidson91c3d072017-04-12 12:17:11 -0700671 /**
672 * Gets metadata for subscription which are available for download on this device.
673 *
674 * <p>Subscriptions returned here may be passed to {@link #downloadSubscription}. They may have
675 * been pre-assigned to this particular device, for example. The callback will be triggered with
676 * an Intent with {@link #EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS} set to the
677 * list of available subscriptions upon success.
678 *
679 * <p>Requires that the calling app has the
680 * {@link android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission. This is for
681 * internal system use only.
682 *
683 * @param callbackIntent a PendingIntent to launch when the operation completes.
684 * @hide
Jeff Davidson91c3d072017-04-12 12:17:11 -0700685 */
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -0800686 @SystemApi
Holly Jiuyu Sund60a07f02018-03-13 17:20:07 -0700687 @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
Jeff Davidson91c3d072017-04-12 12:17:11 -0700688 public void getDefaultDownloadableSubscriptionList(PendingIntent callbackIntent) {
Jordan Liucb47d1d2019-02-01 14:15:05 -0800689 if (!refreshCardIdIfUninitialized()) {
Jeff Davidson91c3d072017-04-12 12:17:11 -0700690 sendUnavailableError(callbackIntent);
691 return;
692 }
693 try {
Jordan Liuc1c89e42018-12-10 16:10:16 -0800694 getIEuiccController().getDefaultDownloadableSubscriptionList(mCardId,
Jeff Davidsonb4c67ec2017-06-13 15:28:57 -0700695 mContext.getOpPackageName(), callbackIntent);
Jeff Davidson91c3d072017-04-12 12:17:11 -0700696 } catch (RemoteException e) {
697 throw e.rethrowFromSystemServer();
698 }
699 }
700
701 /**
702 * Returns information about the eUICC chip/device.
703 *
Holly Jiuyu Sunb94f8d32019-01-30 15:25:24 -0800704 * @return the {@link EuiccInfo}. May be null if the eUICC is not ready.
Jeff Davidson91c3d072017-04-12 12:17:11 -0700705 */
706 @Nullable
707 public EuiccInfo getEuiccInfo() {
Jordan Liucb47d1d2019-02-01 14:15:05 -0800708 if (!refreshCardIdIfUninitialized()) {
Jeff Davidson91c3d072017-04-12 12:17:11 -0700709 return null;
710 }
711 try {
Jordan Liuc1c89e42018-12-10 16:10:16 -0800712 return getIEuiccController().getEuiccInfo(mCardId);
Jeff Davidson91c3d072017-04-12 12:17:11 -0700713 } catch (RemoteException e) {
714 throw e.rethrowFromSystemServer();
715 }
716 }
717
718 /**
719 * Deletes the given subscription.
720 *
721 * <p>If this subscription is currently active, the device will first switch away from it onto
722 * an "empty" subscription.
723 *
724 * <p>Requires that the calling app has carrier privileges according to the metadata of the
725 * profile to be deleted, or the
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -0800726 * {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
Jeff Davidson91c3d072017-04-12 12:17:11 -0700727 *
728 * @param subscriptionId the ID of the subscription to delete.
729 * @param callbackIntent a PendingIntent to launch when the operation completes.
730 */
Holly Jiuyu Sund60a07f02018-03-13 17:20:07 -0700731 @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
Jeff Davidson91c3d072017-04-12 12:17:11 -0700732 public void deleteSubscription(int subscriptionId, PendingIntent callbackIntent) {
Jordan Liucb47d1d2019-02-01 14:15:05 -0800733 if (!refreshCardIdIfUninitialized()) {
Jeff Davidson91c3d072017-04-12 12:17:11 -0700734 sendUnavailableError(callbackIntent);
735 return;
736 }
737 try {
Jordan Liuc1c89e42018-12-10 16:10:16 -0800738 getIEuiccController().deleteSubscription(mCardId,
Jeff Davidson91c3d072017-04-12 12:17:11 -0700739 subscriptionId, mContext.getOpPackageName(), callbackIntent);
740 } catch (RemoteException e) {
741 throw e.rethrowFromSystemServer();
742 }
743 }
744
745 /**
746 * Switch to (enable) the given subscription.
747 *
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -0800748 * <p>Requires the {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission,
Jeff Davidson91c3d072017-04-12 12:17:11 -0700749 * or the calling app must be authorized to manage both the currently-active subscription and
750 * the subscription to be enabled according to the subscription metadata. Without the former,
751 * an {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR} will be returned in the callback
752 * intent to prompt the user to accept the download.
753 *
Holly Jiuyu Sun6bf03592019-01-17 14:41:14 -0800754 * <p>On a multi-active SIM device, requires the
755 * {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission, or a calling app
756 * only if the targeted eUICC does not currently have an active subscription or the calling app
757 * is authorized to manage the active subscription on the target eUICC, and the calling app is
758 * authorized to manage any active subscription on any SIM. Without it, an
759 * {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR} will be returned in the callback
760 * intent to prompt the user to accept the download. The caller should also be authorized to
761 * manage the subscription to be enabled.
762 *
Jeff Davidson91c3d072017-04-12 12:17:11 -0700763 * @param subscriptionId the ID of the subscription to enable. May be
764 * {@link android.telephony.SubscriptionManager#INVALID_SUBSCRIPTION_ID} to deactivate the
Holly Jiuyu Sun6bf03592019-01-17 14:41:14 -0800765 * current profile without activating another profile to replace it. If it's a disable
766 * operation, requires the {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS}
767 * permission, or the calling app must be authorized to manage the active subscription on
768 * the target eUICC.
Jeff Davidson91c3d072017-04-12 12:17:11 -0700769 * @param callbackIntent a PendingIntent to launch when the operation completes.
770 */
Holly Jiuyu Sund60a07f02018-03-13 17:20:07 -0700771 @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
Jeff Davidson91c3d072017-04-12 12:17:11 -0700772 public void switchToSubscription(int subscriptionId, PendingIntent callbackIntent) {
Jordan Liucb47d1d2019-02-01 14:15:05 -0800773 if (!refreshCardIdIfUninitialized()) {
Jeff Davidson91c3d072017-04-12 12:17:11 -0700774 sendUnavailableError(callbackIntent);
775 return;
776 }
777 try {
Jordan Liuc1c89e42018-12-10 16:10:16 -0800778 getIEuiccController().switchToSubscription(mCardId,
Jeff Davidson91c3d072017-04-12 12:17:11 -0700779 subscriptionId, mContext.getOpPackageName(), callbackIntent);
780 } catch (RemoteException e) {
781 throw e.rethrowFromSystemServer();
782 }
783 }
784
785 /**
786 * Update the nickname for the given subscription.
787 *
Holly Jiuyu Sun5b44f9b2019-01-09 13:33:14 -0800788 * <p>Requires that the calling app has carrier privileges according to the metadata of the
789 * profile to be updated, or the
790 * {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
Jeff Davidson91c3d072017-04-12 12:17:11 -0700791 *
792 * @param subscriptionId the ID of the subscription to update.
793 * @param nickname the new nickname to apply.
794 * @param callbackIntent a PendingIntent to launch when the operation completes.
Jeff Davidson91c3d072017-04-12 12:17:11 -0700795 */
Holly Jiuyu Sund60a07f02018-03-13 17:20:07 -0700796 @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
Jeff Davidson91c3d072017-04-12 12:17:11 -0700797 public void updateSubscriptionNickname(
Holly Jiuyu Sunf6fc4ee2019-02-28 15:02:50 -0800798 int subscriptionId, @Nullable String nickname, @NonNull PendingIntent callbackIntent) {
Jordan Liucb47d1d2019-02-01 14:15:05 -0800799 if (!refreshCardIdIfUninitialized()) {
Jeff Davidson91c3d072017-04-12 12:17:11 -0700800 sendUnavailableError(callbackIntent);
801 return;
802 }
803 try {
Jordan Liuc1c89e42018-12-10 16:10:16 -0800804 getIEuiccController().updateSubscriptionNickname(mCardId,
Holly Jiuyu Sun5b44f9b2019-01-09 13:33:14 -0800805 subscriptionId, nickname, mContext.getOpPackageName(), callbackIntent);
Jeff Davidson91c3d072017-04-12 12:17:11 -0700806 } catch (RemoteException e) {
807 throw e.rethrowFromSystemServer();
808 }
809 }
810
811 /**
812 * Erase all subscriptions and reset the eUICC.
813 *
814 * <p>Requires that the calling app has the
Holly Jiuyu Sund60a07f02018-03-13 17:20:07 -0700815 * {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission.
Jeff Davidson91c3d072017-04-12 12:17:11 -0700816 *
817 * @param callbackIntent a PendingIntent to launch when the operation completes.
818 * @hide
819 */
Holly Jiuyu Sund60a07f02018-03-13 17:20:07 -0700820 @SystemApi
821 @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
Jeff Davidson91c3d072017-04-12 12:17:11 -0700822 public void eraseSubscriptions(PendingIntent callbackIntent) {
Jordan Liucb47d1d2019-02-01 14:15:05 -0800823 if (!refreshCardIdIfUninitialized()) {
Jeff Davidson91c3d072017-04-12 12:17:11 -0700824 sendUnavailableError(callbackIntent);
825 return;
826 }
827 try {
Jordan Liuc1c89e42018-12-10 16:10:16 -0800828 getIEuiccController().eraseSubscriptions(mCardId, callbackIntent);
Jeff Davidson91c3d072017-04-12 12:17:11 -0700829 } catch (RemoteException e) {
830 throw e.rethrowFromSystemServer();
831 }
832 }
833
Jeff Davidson7b69a862017-06-16 15:20:34 -0700834 /**
835 * Ensure that subscriptions will be retained on the next factory reset.
836 *
837 * <p>By default, all subscriptions on the eUICC are erased the first time a device boots (ever
838 * and after factory resets). This ensures that the data is wiped after a factory reset is
839 * performed via fastboot or recovery mode, as these modes do not support the necessary radio
840 * communication needed to wipe the eSIM.
841 *
842 * <p>However, this method may be called right before a factory reset issued via settings when
843 * the user elects to retain subscriptions. Doing so will mark them for retention so that they
844 * are not cleared after the ensuing reset.
845 *
846 * <p>Requires that the calling app has the {@link android.Manifest.permission#MASTER_CLEAR}
847 * permission. This is for internal system use only.
848 *
849 * @param callbackIntent a PendingIntent to launch when the operation completes.
850 * @hide
851 */
852 public void retainSubscriptionsForFactoryReset(PendingIntent callbackIntent) {
Jordan Liucb47d1d2019-02-01 14:15:05 -0800853 if (!refreshCardIdIfUninitialized()) {
Jeff Davidson7b69a862017-06-16 15:20:34 -0700854 sendUnavailableError(callbackIntent);
855 return;
856 }
857 try {
Jordan Liuc1c89e42018-12-10 16:10:16 -0800858 getIEuiccController().retainSubscriptionsForFactoryReset(mCardId, callbackIntent);
Jeff Davidson7b69a862017-06-16 15:20:34 -0700859 } catch (RemoteException e) {
860 throw e.rethrowFromSystemServer();
861 }
862 }
863
Jordan Liucb47d1d2019-02-01 14:15:05 -0800864 /**
865 * Refreshes the cardId if its uninitialized, and returns whether we should continue the
866 * operation.
867 * <p>
868 * Note that after a successful refresh, the mCardId may be TelephonyManager.UNSUPPORTED_CARD_ID
869 * on older HALs. For backwards compatability, we continue to the LPA and let it decide which
870 * card to use.
871 */
872 private boolean refreshCardIdIfUninitialized() {
873 // Refresh mCardId if its UNINITIALIZED_CARD_ID
874 if (mCardId == TelephonyManager.UNINITIALIZED_CARD_ID) {
Holly Jiuyu Sunb94f8d32019-01-30 15:25:24 -0800875 TelephonyManager tm = (TelephonyManager)
876 mContext.getSystemService(Context.TELEPHONY_SERVICE);
877 mCardId = tm.getCardIdForDefaultEuicc();
878 }
Jordan Liucb47d1d2019-02-01 14:15:05 -0800879 if (mCardId == TelephonyManager.UNINITIALIZED_CARD_ID) {
880 return false;
881 }
Holly Jiuyu Sunb94f8d32019-01-30 15:25:24 -0800882 return true;
883 }
884
Jeff Davidson35cda392017-02-27 09:46:00 -0800885 private static void sendUnavailableError(PendingIntent callbackIntent) {
886 try {
Jeff Davidson83f8bc82017-05-15 10:22:20 -0700887 callbackIntent.send(EMBEDDED_SUBSCRIPTION_RESULT_ERROR);
Jeff Davidson35cda392017-02-27 09:46:00 -0800888 } catch (PendingIntent.CanceledException e) {
889 // Caller canceled the callback; do nothing.
890 }
891 }
Holly Jiuyu Sunc2193d42017-12-13 21:02:05 -0800892
Holly Jiuyu Sun4f73b9c2017-12-12 20:17:09 -0800893 private static IEuiccController getIEuiccController() {
Holly Jiuyu Sunc2193d42017-12-13 21:02:05 -0800894 return IEuiccController.Stub.asInterface(ServiceManager.getService("econtroller"));
895 }
Jeff Davidson35cda392017-02-27 09:46:00 -0800896}