EuiccService.java revision 83f8bc81be65cb09720c6d8dac7717d4652cd931
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 */ 16package android.service.euicc; 17 18import android.annotation.CallSuper; 19import android.annotation.Nullable; 20import android.app.Service; 21import android.content.Intent; 22import android.os.IBinder; 23import android.os.RemoteException; 24import android.telephony.euicc.DownloadableSubscription; 25import android.telephony.euicc.EuiccInfo; 26import android.util.ArraySet; 27 28/** 29 * Service interface linking the system with an eUICC local profile assistant (LPA) application. 30 * 31 * <p>An LPA consists of two separate components (which may both be implemented in the same APK): 32 * the LPA backend, and the LPA UI or LUI. 33 * 34 * <p>To implement the LPA backend, you must extend this class and declare this service in your 35 * manifest file. The service must require the 36 * {@link android.Manifest.permission#BIND_EUICC_SERVICE} permission and include an intent filter 37 * with the {@link #EUICC_SERVICE_INTERFACE} action. The priority of the intent filter must be set 38 * to a non-zero value in case multiple implementations are present on the device. For example: 39 * 40 * <pre>{@code 41 * <service android:name=".MyEuiccService" 42 * android:permission="android.permission.BIND_EUICC_SERVICE"> 43 * <intent-filter android:priority="100"> 44 * <action android:name="android.service.euicc.EuiccService" /> 45 * </intent-filter> 46 * </service> 47 * }</pre> 48 * 49 * <p>To implement the LUI, you must provide an activity for the following actions: 50 * 51 * <ul> 52 * <li>{@link #ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS} 53 * <li>{@link #ACTION_PROVISION_EMBEDDED_SUBSCRIPTION} 54 * </ul> 55 * 56 * <p>As with the service, each activity must require the 57 * {@link android.Manifest.permission#BIND_EUICC_SERVICE} permission. Each should have an intent 58 * filter with the appropriate action, the {@link #CATEGORY_EUICC_UI} category, and a non-zero 59 * priority. 60 * 61 * TODO(b/35851809): Make this a SystemApi. 62 * @hide 63 */ 64public abstract class EuiccService extends Service { 65 /** Action which must be included in this service's intent filter. */ 66 public static final String EUICC_SERVICE_INTERFACE = "android.service.euicc.EuiccService"; 67 68 /** Category which must be defined to all UI actions, for efficient lookup. */ 69 public static final String CATEGORY_EUICC_UI = "android.service.euicc.category.EUICC_UI"; 70 71 // LUI actions. These are passthroughs of the corresponding EuiccManager actions. 72 73 /** @see android.telephony.euicc.EuiccManager#ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS */ 74 public static final String ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS = 75 "android.service.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS"; 76 /** @see android.telephony.euicc.EuiccManager#ACTION_PROVISION_EMBEDDED_SUBSCRIPTION */ 77 public static final String ACTION_PROVISION_EMBEDDED_SUBSCRIPTION = 78 "android.service.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION"; 79 80 // LUI resolution actions. These are called by the platform to resolve errors in situations that 81 // require user interaction. 82 // TODO(b/33075886): Define extras for any input parameters to these dialogs once they are 83 // more scoped out. 84 /** Alert the user that this action will result in an active SIM being deactivated. */ 85 public static final String ACTION_RESOLVE_DEACTIVATE_SIM = 86 "android.service.euicc.action.RESOLVE_DEACTIVATE_SIM"; 87 /** 88 * Alert the user about a download/switch being done for an app that doesn't currently have 89 * carrier privileges. 90 */ 91 public static final String ACTION_RESOLVE_NO_PRIVILEGES = 92 "android.service.euicc.action.RESOLVE_NO_PRIVILEGES"; 93 94 /** Result code for a successful operation. */ 95 public static final int RESULT_OK = 0; 96 /** Result code indicating that an active SIM must be deactivated to perform the operation. */ 97 public static final int RESULT_MUST_DEACTIVATE_SIM = -1; 98 // New predefined codes should have negative values. 99 100 /** Start of implementation-specific error results. */ 101 public static final int RESULT_FIRST_USER = 1; 102 103 /** 104 * List of all valid resolution actions for validation purposes. 105 * @hide 106 */ 107 public static final ArraySet<String> RESOLUTION_ACTIONS; 108 static { 109 RESOLUTION_ACTIONS = new ArraySet<>(); 110 RESOLUTION_ACTIONS.add(EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM); 111 RESOLUTION_ACTIONS.add(EuiccService.ACTION_RESOLVE_NO_PRIVILEGES); 112 } 113 114 /** Boolean extra for resolution actions indicating whether the user granted consent. */ 115 public static final String RESOLUTION_EXTRA_CONSENT = "consent"; 116 117 private final IEuiccService.Stub mStubWrapper; 118 119 public EuiccService() { 120 mStubWrapper = new IEuiccServiceWrapper(); 121 } 122 123 /** 124 * If overriding this method, call through to the super method for any unknown actions. 125 * {@inheritDoc} 126 */ 127 @Override 128 @CallSuper 129 public IBinder onBind(Intent intent) { 130 return mStubWrapper; 131 } 132 133 /** 134 * Return the EID of the eUICC. 135 * 136 * @param slotId ID of the SIM slot being queried. This is currently not populated but is here 137 * to future-proof the APIs. 138 * @return the EID. 139 * @see android.telephony.euicc.EuiccManager#getEid 140 */ 141 // TODO(b/36260308): Update doc when we have multi-SIM support. 142 public abstract String onGetEid(int slotId); 143 144 /** 145 * Populate {@link DownloadableSubscription} metadata for the given downloadable subscription. 146 * 147 * @param slotId ID of the SIM slot to use for the operation. This is currently not populated 148 * but is here to future-proof the APIs. 149 * @param subscription A subscription whose metadata needs to be populated. 150 * @param forceDeactivateSim If true, and if an active SIM must be deactivated to access the 151 * eUICC, perform this action automatically. Otherwise, {@link #RESULT_MUST_DEACTIVATE_SIM)} 152 * should be returned to allow the user to consent to this operation first. 153 * @return The result of the operation. 154 * @see android.telephony.euicc.EuiccManager#getDownloadableSubscriptionMetadata 155 */ 156 public abstract GetDownloadableSubscriptionMetadataResult onGetDownloadableSubscriptionMetadata( 157 int slotId, DownloadableSubscription subscription, boolean forceDeactivateSim); 158 159 /** 160 * Return metadata for subscriptions which are available for download for this device. 161 * 162 * @param slotId ID of the SIM slot to use for the operation. This is currently not populated 163 * but is here to future-proof the APIs. 164 * @param forceDeactivateSim If true, and if an active SIM must be deactivated to access the 165 * eUICC, perform this action automatically. Otherwise, {@link #RESULT_MUST_DEACTIVATE_SIM)} 166 * should be returned to allow the user to consent to this operation first. 167 * @return The result of the list operation. 168 * @see android.telephony.euicc.EuiccManager#getDefaultDownloadableSubscriptionList 169 */ 170 public abstract GetDefaultDownloadableSubscriptionListResult 171 onGetDefaultDownloadableSubscriptionList(int slotId, boolean forceDeactivateSim); 172 173 /** 174 * Download the given subscription. 175 * 176 * @param slotId ID of the SIM slot to use for the operation. This is currently not populated 177 * but is here to future-proof the APIs. 178 * @param subscription The subscription to download. 179 * @param switchAfterDownload If true, the subscription should be enabled upon successful 180 * download. 181 * @param forceDeactivateSim If true, and if an active SIM must be deactivated to access the 182 * eUICC, perform this action automatically. Otherwise, {@link #RESULT_MUST_DEACTIVATE_SIM} 183 * should be returned to allow the user to consent to this operation first. 184 * @return the result of the download operation. May be one of the predefined {@code RESULT_} 185 * constants or any implementation-specific code starting with {@link #RESULT_FIRST_USER}. 186 * @see android.telephony.euicc.EuiccManager#downloadSubscription 187 */ 188 public abstract int onDownloadSubscription(int slotId, 189 DownloadableSubscription subscription, boolean switchAfterDownload, 190 boolean forceDeactivateSim); 191 192 /** 193 * Return a list of all @link EuiccProfileInfo}s. 194 * 195 * @param slotId ID of the SIM slot to use for the operation. This is currently not populated 196 * but is here to future-proof the APIs. 197 * @return The result of the operation. 198 * @see android.telephony.SubscriptionManager#getAvailableSubscriptionInfoList 199 * @see android.telephony.SubscriptionManager#getAccessibleSubscriptionInfoList 200 */ 201 public abstract GetEuiccProfileInfoListResult onGetEuiccProfileInfoList(int slotId); 202 203 /** 204 * Return info about the eUICC chip/device. 205 * 206 * @param slotId ID of the SIM slot to use for the operation. This is currently not populated 207 * but is here to future-proof the APIs. 208 * @return the {@link EuiccInfo} for the eUICC chip/device. 209 * @see android.telephony.euicc.EuiccManager#getEuiccInfo 210 */ 211 public abstract EuiccInfo onGetEuiccInfo(int slotId); 212 213 /** 214 * Delete the given subscription. 215 * 216 * <p>If the subscription is currently active, it should be deactivated first (equivalent to a 217 * physical SIM being ejected). 218 * 219 * @param slotId ID of the SIM slot to use for the operation. This is currently not populated 220 * but is here to future-proof the APIs. 221 * @param iccid the ICCID of the subscription to delete. 222 * @return the result of the delete operation. May be one of the predefined {@code RESULT_} 223 * constants or any implementation-specific code starting with {@link #RESULT_FIRST_USER}. 224 * @see android.telephony.euicc.EuiccManager#deleteSubscription 225 */ 226 public abstract int onDeleteSubscription(int slotId, String iccid); 227 228 /** 229 * Switch to the given subscription. 230 * 231 * @param slotId ID of the SIM slot to use for the operation. This is currently not populated 232 * but is here to future-proof the APIs. 233 * @param iccid the ICCID of the subscription to enable. May be null, in which case the current 234 * profile should be deactivated and no profile should be activated to replace it - this is 235 * equivalent to a physical SIM being ejected. 236 * @param forceDeactivateSim If true, and if an active SIM must be deactivated to access the 237 * eUICC, perform this action automatically. Otherwise, {@link #RESULT_MUST_DEACTIVATE_SIM} 238 * should be returned to allow the user to consent to this operation first. 239 * @return the result of the switch operation. May be one of the predefined {@code RESULT_} 240 * constants or any implementation-specific code starting with {@link #RESULT_FIRST_USER}. 241 * @see android.telephony.euicc.EuiccManager#switchToSubscription 242 */ 243 public abstract int onSwitchToSubscription(int slotId, @Nullable String iccid, 244 boolean forceDeactivateSim); 245 246 /** 247 * Update the nickname of the given subscription. 248 * 249 * @param slotId ID of the SIM slot to use for the operation. This is currently not populated 250 * but is here to future-proof the APIs. 251 * @param iccid the ICCID of the subscription to update. 252 * @param nickname the new nickname to apply. 253 * @return the result of the update operation. May be one of the predefined {@code RESULT_} 254 * constants or any implementation-specific code starting with {@link #RESULT_FIRST_USER}. 255 * @see android.telephony.euicc.EuiccManager#updateSubscriptionNickname 256 */ 257 public abstract int onUpdateSubscriptionNickname(int slotId, String iccid, 258 String nickname); 259 260 /** 261 * Erase all of the subscriptions on the device. 262 * 263 * <p>This is intended to be used for device resets. As such, the reset should be performed even 264 * if an active SIM must be deactivated in order to access the eUICC. 265 * 266 * @param slotId ID of the SIM slot to use for the operation. This is currently not populated 267 * but is here to future-proof the APIs. 268 * @return the result of the erase operation. May be one of the predefined {@code RESULT_} 269 * constants or any implementation-specific code starting with {@link #RESULT_FIRST_USER}. 270 * @see android.telephony.euicc.EuiccManager#eraseSubscriptions 271 */ 272 public abstract int onEraseSubscriptions(int slotId); 273 274 /** 275 * Wrapper around IEuiccService that forwards calls to implementations of {@link EuiccService}. 276 */ 277 private class IEuiccServiceWrapper extends IEuiccService.Stub { 278 @Override 279 public void downloadSubscription(int slotId, DownloadableSubscription subscription, 280 boolean switchAfterDownload, boolean forceDeactivateSim, 281 IDownloadSubscriptionCallback callback) { 282 int result = EuiccService.this.onDownloadSubscription( 283 slotId, subscription, switchAfterDownload, forceDeactivateSim); 284 try { 285 callback.onComplete(result); 286 } catch (RemoteException e) { 287 // Can't communicate with the phone process; ignore. 288 } 289 } 290 291 @Override 292 public void getEid(int slotId, IGetEidCallback callback) { 293 String eid = EuiccService.this.onGetEid(slotId); 294 try { 295 callback.onSuccess(eid); 296 } catch (RemoteException e) { 297 // Can't communicate with the phone process; ignore. 298 } 299 } 300 301 @Override 302 public void getDownloadableSubscriptionMetadata(int slotId, 303 DownloadableSubscription subscription, 304 boolean forceDeactivateSim, 305 IGetDownloadableSubscriptionMetadataCallback callback) { 306 GetDownloadableSubscriptionMetadataResult result = 307 EuiccService.this.onGetDownloadableSubscriptionMetadata( 308 slotId, subscription, forceDeactivateSim); 309 try { 310 callback.onComplete(result); 311 } catch (RemoteException e) { 312 // Can't communicate with the phone process; ignore. 313 } 314 } 315 316 @Override 317 public void getDefaultDownloadableSubscriptionList(int slotId, boolean forceDeactivateSim, 318 IGetDefaultDownloadableSubscriptionListCallback callback) { 319 GetDefaultDownloadableSubscriptionListResult result = 320 EuiccService.this.onGetDefaultDownloadableSubscriptionList( 321 slotId, forceDeactivateSim); 322 try { 323 callback.onComplete(result); 324 } catch (RemoteException e) { 325 // Can't communicate with the phone process; ignore. 326 } 327 } 328 329 @Override 330 public void getEuiccProfileInfoList(int slotId, IGetEuiccProfileInfoListCallback callback) { 331 GetEuiccProfileInfoListResult result = 332 EuiccService.this.onGetEuiccProfileInfoList(slotId); 333 try { 334 callback.onComplete(result); 335 } catch (RemoteException e) { 336 // Can't communicate with the phone process; ignore. 337 } 338 } 339 340 @Override 341 public void getEuiccInfo(int slotId, IGetEuiccInfoCallback callback) { 342 EuiccInfo euiccInfo = EuiccService.this.onGetEuiccInfo(slotId); 343 try { 344 callback.onSuccess(euiccInfo); 345 } catch (RemoteException e) { 346 // Can't communicate with the phone process; ignore. 347 } 348 } 349 350 @Override 351 public void deleteSubscription(int slotId, String iccid, 352 IDeleteSubscriptionCallback callback) { 353 int result = EuiccService.this.onDeleteSubscription(slotId, iccid); 354 try { 355 callback.onComplete(result); 356 } catch (RemoteException e) { 357 // Can't communicate with the phone process; ignore. 358 } 359 } 360 361 @Override 362 public void switchToSubscription(int slotId, String iccid, boolean forceDeactivateSim, 363 ISwitchToSubscriptionCallback callback) { 364 int result = 365 EuiccService.this.onSwitchToSubscription(slotId, iccid, forceDeactivateSim); 366 try { 367 callback.onComplete(result); 368 } catch (RemoteException e) { 369 // Can't communicate with the phone process; ignore. 370 } 371 } 372 373 @Override 374 public void updateSubscriptionNickname(int slotId, String iccid, String nickname, 375 IUpdateSubscriptionNicknameCallback callback) { 376 int result = EuiccService.this.onUpdateSubscriptionNickname(slotId, iccid, nickname); 377 try { 378 callback.onComplete(result); 379 } catch (RemoteException e) { 380 // Can't communicate with the phone process; ignore. 381 } 382 } 383 384 @Override 385 public void eraseSubscriptions(int slotId, IEraseSubscriptionsCallback callback) { 386 int result = EuiccService.this.onEraseSubscriptions(slotId); 387 try { 388 callback.onComplete(result); 389 } catch (RemoteException e) { 390 // Can't communicate with the phone process; ignore. 391 } 392 } 393 } 394} 395