La technologie SIM intégrée (eSIM, ou eUICC) permet aux utilisateurs mobiles de de télécharger un profil d'opérateur et d'activer le service d'un opérateur carte SIM physique. Il s'agit d'une spécification globale pilotée par la GSMA qui permet le provisionnement à distance de la carte SIM (RSP) de n'importe quel appareil mobile. À partir d'Android 9, le framework Android fournit des API standards l'accès à l'eSIM et la gestion des profils d'abonnement sur l'eSIM. Ces eUICC les API permettent aux tiers de développer leurs propres applications d'opérateur et leur profil local. sur les appareils Android compatibles eSIM.
Le LPA est une application système autonome qui doit être incluse dans Image de build Android La gestion des profils sur l'eSIM est généralement assurée par le LPA, car il sert de pont entre le SM-DP+ (service à distance qui prépare, stocke et livre les packages de profil aux appareils) et la puce eUICC. L'APK LPA peut éventuellement inclure un composant d'UI, appelé UI LPA, ou LUI, pour fournir à l'utilisateur final un emplacement centralisé pour gérer tous les abonnements intégrés profils. Le framework Android détecte et s'y connecte automatiquement disponible et achemine toutes les opérations eUICC via une instance LPA.
Figure 1 : Architecture RSP simplifiée
Les opérateurs de réseau mobile qui souhaitent créer une application d'opérateur doivent se tourner vers
les API
EuiccManager
qui permet d'effectuer des opérations générales de gestion des profils, telles que
downloadSubscription()
, switchToSubscription()
et
deleteSubscription()
Si vous êtes un OEM d'appareils et que vous souhaitez créer votre propre application système LPA, vous devez
étendre
EuiccService
pour que le framework Android se connecte
à vos services LPA. De plus, vous
devez utiliser les API
EuiccCardManager
qui fournissent des fonctions ES10x basées sur GSMA RSP v2.0.
Ces fonctions sont utilisées pour envoyer des commandes à la puce eUICC, telles que
prepareDownload()
, loadBoundProfilePackage()
, retrieveNotificationList()
et resetMemory()
.
Les API de
EuiccManager
ont besoin d'une application LPA correctement
implémentée pour fonctionner et que l'appelant de
EuiccCardManager
Les API doivent être des LPA. Cette règle est appliquée par le framework Android.
Compatibilité avec les appareils équipés d'Android 10 ou version ultérieure appareils avec plusieurs eSIM. Pour en savoir plus, consultez Compatibilité avec plusieurs eSIM.
Créer une appli d'opérateur
Les API eUICC d'Android 9 permettent les opérateurs de réseau mobile peuvent créer des applications aux couleurs de l'opérateur afin de gérer des profils. Cela inclut le téléchargement et la suppression de profils d'abonnement appartenant à l'opérateur, et passer à un profil appartenant à un opérateur.
EuiccManager
EuiccManager
est le principal point d'entrée des applications pour interagir avec
LPA. Cela inclut les applis d'opérateurs qui téléchargent, suppriment
abonnements appartenant à l'opérateur. Cela inclut également l'application
système LUI, qui
fournit un emplacement/une interface utilisateur centralisé pour gérer tous les abonnements intégrés ;
Il peut s'agir d'une application distincte de celle qui fournit EuiccService
.
Pour utiliser les API publiques, l'application d'opérateur doit d'abord obtenir l'instance de
EuiccManager
à Context#getSystemService
:
EuiccManager mgr = (EuiccManager) context.getSystemService(Context.EUICC_SERVICE);
Vous devez vérifier si l'eSIM est compatible avec l'appareil avant d'effectuer une
Opérations eSIM. EuiccManager#isEnabled()
renvoie généralement true
si le
android.hardware.telephony.euicc
est définie et un package LPA est
à l'heure actuelle.
if (mgr == null || !mgr.isEnabled()) {
return;
}
Pour obtenir des informations sur le matériel eUICC et la version de l'OS eSIM:
EuiccInfo info = mgr.getEuiccInfo();
String osVer = info.getOsVersion();
De nombreuses API, telles que downloadSubscription()
et switchToSubscription()
, utilisent
PendingIntent
, car leur exécution peut prendre quelques secondes, voire quelques minutes.
PendingIntent
est envoyé avec un code de résultat dans
EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_
, qui fournit
des codes d'erreur définis par le framework, ainsi qu'un code de résultat détaillé arbitraire
propagé à partir du LPA sous
la forme EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
, permettant
l'application de l'opérateur pour effectuer le suivi à des fins de journalisation/débogage. PendingIntent
Le rappel doit être BroadcastReceiver
.
Pour télécharger un abonnement téléchargeable donné (créé à partir d'un code d'activation ou un code QR):
// Register receiver.
static final String ACTION_DOWNLOAD_SUBSCRIPTION = "download_subscription";
static final String LPA_DECLARED_PERMISSION
= "com.your.company.lpa.permission.BROADCAST";
BroadcastReceiver receiver =
new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (!action.equals(intent.getAction())) {
return;
}
resultCode = getResultCode();
detailedCode = intent.getIntExtra(
EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE,
0 /* defaultValue*/);
// If the result code is a resolvable error, call startResolutionActivity
if (resultCode == EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR) {
PendingIntent callbackIntent = PendingIntent.getBroadcast(
getContext(), 0 /* requestCode */, intent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
mgr.startResolutionActivity(
activity,
0 /* requestCode */,
intent,
callbackIntent);
}
resultIntent = intent;
}
};
context.registerReceiver(receiver,
new IntentFilter(ACTION_DOWNLOAD_SUBSCRIPTION),
LPA_DECLARED_PERMISSION /* broadcastPermission*/,
null /* handler */);
// Download subscription asynchronously.
DownloadableSubscription sub = DownloadableSubscription
.forActivationCode(code /* encodedActivationCode*/);
Intent intent = new Intent(action).setPackage(context.getPackageName());
PendingIntent callbackIntent = PendingIntent.getBroadcast(
getContext(), 0 /* requestCode */, intent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
mgr.downloadSubscription(sub, true /* switchAfterDownload */,
callbackIntent);
Définissez et utilisez l'autorisation dans AndroidManifest.xml
:
<permission android:protectionLevel="signature" android:name="com.your.company.lpa.permission.BROADCAST" />
<uses-permission android:name="com.your.company.lpa.permission.BROADCAST"/>
Pour passer à un abonnement en fonction de l'ID d'abonnement:
// Register receiver.
static final String ACTION_SWITCH_TO_SUBSCRIPTION = "switch_to_subscription";
static final String LPA_DECLARED_PERMISSION
= "com.your.company.lpa.permission.BROADCAST";
BroadcastReceiver receiver =
new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (!action.equals(intent.getAction())) {
return;
}
resultCode = getResultCode();
detailedCode = intent.getIntExtra(
EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE,
0 /* defaultValue*/);
resultIntent = intent;
}
};
context.registerReceiver(receiver,
new IntentFilter(ACTION_SWITCH_TO_SUBSCRIPTION),
LPA_DECLARED_PERMISSION /* broadcastPermission*/,
null /* handler */);
// Switch to a subscription asynchronously.
Intent intent = new Intent(action).setPackage(context.getPackageName());
PendingIntent callbackIntent = PendingIntent.getBroadcast(
getContext(), 0 /* requestCode */, intent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
mgr.switchToSubscription(1 /* subscriptionId */, callbackIntent);
Pour obtenir la liste complète des API EuiccManager
et des exemples de code, consultez
API eUICC.
Erreurs pouvant être résolues
Dans certains cas, le système ne parvient pas à effectuer l'opération de l'eSIM.
mais l'erreur peut être
résolue par l'utilisateur. Exemple : downloadSubscription
peut échouer si les métadonnées du profil indiquent qu'un code de confirmation de l'opérateur
est obligatoire. Sinon, l'switchToSubscription
peut échouer si l'appli de l'opérateur est associée
des privilèges sur le profil de destination (c'est-à-dire que l'opérateur est propriétaire du profil), mais
ne dispose d'aucun privilège d'opérateur sur le profil actuellement activé et, par conséquent,
le consentement de l'utilisateur est requis.
Dans ce cas, le rappel de l'appelant est appelé avec
EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR
Rappel
Intent
contient des extras internes de telle sorte que lorsque l'appelant le transmet à
EuiccManager#startResolutionActivity
,
de résolution peut être demandée
via l'interface utilisateur. Utiliser le code de confirmation pour
à nouveau,
EuiccManager#startResolutionActivity
déclenche un écran LUI qui permet à l'utilisateur de saisir un code de confirmation ;
Une fois le code saisi, le téléchargement reprend. Cette approche
permet à l'application de l'opérateur de contrôler totalement le moment où l'interface utilisateur s'affiche, mais donne
LPA/LUI, une méthode extensible permettant d'ajouter une nouvelle gestion des récupérations par l'utilisateur
de problèmes à l'avenir sans avoir besoin de modifier les applications clientes.
Android 9 définit ces erreurs pouvant être résolues dans
EuiccService
que l'interface utilisateur doit gérer:
/**
* Alert the user that this action will result in an active SIM being
* deactivated. To implement the LUI triggered by the system, you need to define
* this in AndroidManifest.xml.
*/
public static final String ACTION_RESOLVE_DEACTIVATE_SIM =
"android.service.euicc.action.RESOLVE_DEACTIVATE_SIM";
/**
* Alert the user about a download/switch being done for an app that doesn't
* currently have carrier privileges.
*/
public static final String ACTION_RESOLVE_NO_PRIVILEGES =
"android.service.euicc.action.RESOLVE_NO_PRIVILEGES";
/** Ask the user to resolve all the resolvable errors. */
public static final String ACTION_RESOLVE_RESOLVABLE_ERRORS =
"android.service.euicc.action.RESOLVE_RESOLVABLE_ERRORS";
Droits d'opérateur
Si vous êtes un opérateur et que vous développez votre propre application d'opérateur qui appelle EuiccManager
pour télécharger des profils sur un appareil, votre profil doit inclure l'opérateur
des règles de privilèges correspondant à l'application de votre opérateur dans les métadonnées. C'est
car les profils d'abonnement de différents opérateurs peuvent coexister
l'eUICC d'un appareil, et chaque appli d'opérateur ne doit être autorisée à accéder qu'à
les profils appartenant à cet opérateur. Par exemple, l'opérateur A ne doit pas pouvoir
télécharger, activer ou désactiver un profil appartenant à l'opérateur B ;
Pour s'assurer qu'un profil n'est accessible qu'à son propriétaire, Android utilise un mécanisme permettant
accorder des privilèges spéciaux à l'application du propriétaire du profil (c'est-à-dire à l'application de l'opérateur) La
La plate-forme Android charge les certificats stockés dans le fichier de règles d'accès du profil.
(ARF) et autorise les applis signées à l'aide de ces certificats à passer des appels
vers les API EuiccManager
. Le processus général est décrit ci-dessous:
- L'opérateur signe l'APK de l'application de l'opérateur. la apksigner associe le certificat de clé publique à l'APK.
L'opérateur/SM-DP+ prépare un profil et ses métadonnées, qui incluent un ARF contenant:
- Signature (SHA-1 ou SHA-256) du certificat de clé publique de l'application de l'opérateur (obligatoire)
- Nom de package de l'application de l'opérateur (vivement recommandé)
L'application de l'opérateur tente d'effectuer une opération eUICC avec l'API
EuiccManager
.La plate-forme Android vérifie le hachage SHA-1 ou SHA-256 de l'appel d'API certificat correspond à la signature du certificat obtenu à partir du ARF du profil cible. Si le nom de package de l'application de l'opérateur figure dans le fichier de récupération de compte, il doit également correspondre au nom du package de l'application appelante.
Une fois que la signature et le nom du package (le cas échéant) ont été vérifiés, le un droit d'opérateur est accordé à l'application appelante via le profil cible.
Étant donné que les métadonnées de profil peuvent être disponibles en dehors du profil lui-même, LPA peut récupérer les métadonnées de profil à partir de SM-DP+ avant que le profil ne soit téléchargée ou à partir d'ISD-R lorsque le profil est désactivé), il doit contenir les mêmes règles en matière de droits d'opérateur que dans le profil.
L'OS eUICC et SM-DP+ doivent être compatibles avec un tag propriétaire BF76
dans le profil
de métadonnées. Le contenu du tag doit respecter les mêmes règles en matière de droits d'opérateur que celles renvoyées
par l'applet de règle d'accès (ARA) défini dans
Droits d'opérateur UICC:
RefArDo ::= [PRIVATE 2] SEQUENCE { -- Tag E2
refDo [PRIVATE 1] SEQUENCE { -- Tag E1
deviceAppIdRefDo [PRIVATE 1] OCTET STRING (SIZE(20|32)), -- Tag C1
pkgRefDo [PRIVATE 10] OCTET STRING (SIZE(0..127)) OPTIONAL -- Tag CA
},
arDo [PRIVATE 3] SEQUENCE { -- Tag E3
permArDo [PRIVATE 27] OCTET STRING (SIZE(8)) -- Tag DB
}
}
Pour en savoir plus sur la signature d'application, consultez Signez votre application. Pour en savoir plus sur les droits d'opérateur, consultez Droits d'opérateur UICC.
Créer une application d'assistant de profil local
Les fabricants d'appareils peuvent implémenter leur propre assistant de profil local (LPA), qui doit être accrochée grâce aux API Android Euicc. Les sections suivantes présentent brièvement créer une application LPA et l’intégrer au système Android.
Configuration matérielle/configuration requise pour le modem
Le LPA et l'OS eSIM sur la puce eUICC doivent être compatibles au minimum avec les réseaux GSMA RSP provisionnement de la carte SIM) v2.0 ou v2.2. Vous devez également prévoir d'utiliser SM-DP+ et SM-DS avec une version RSP correspondante. Pour en savoir plus sur l'architecture RSP, consultez Spécification d'architecture RSP GSMA SGP.21
De plus, pour intégrer les API eUICC dans Android 9, le modem de l'appareil doit envoyer les capacités du terminal et prend en charge les fonctionnalités eUICC encodées (gestion des profils en local téléchargement du profil). Il doit également implémenter les méthodes suivantes:
- IRadio HAL v1.1:
setSimPower
IRadio HAL v1.2:
getIccCardStatus
IRadioConfig HAL v1.0:
getSimSlotsStatus
IRadioConfig AIDL v1.0:
getAllowedCarriers
L'application Google LPA doit connaître l'état du verrouillage de l'opérateur afin de pouvoir autoriser le téléchargement ou le transfert d'eSIM uniquement pour l'opérateur autorisé. Dans le cas contraire, les utilisateurs risquent de télécharger et de transférer leur carte SIM, puis de réaliser plus tard que l'opérateur de leur appareil est bloqué par un autre opérateur.
Les fournisseurs ou les OEM doivent implémenter l'API IRadioSim.getAllowedCarriers()HAL.
Dans le cadre de l'API IRadioSimResponse.getAllowedCarriersResponse()HAL, le fournisseur RIL / Modem doit renseigner l'état du verrouillage et l'ID du transporteur de l'opérateur sur lequel l'appareil est verrouillé.
Le modem doit reconnaître l'eSIM avec le profil de démarrage par défaut activé en tant que une carte SIM valide et laissez la carte sous tension.
Pour les appareils équipés d'Android 10,
Vous devez définir un tableau d'ID d'emplacement. Par exemple, consultez
arrays.xml
<resources>
<!-- Device-specific array of SIM slot indexes which are are embedded eUICCs.
e.g. If a device has two physical slots with indexes 0, 1, and slot 1 is an
eUICC, then the value of this array should be:
<integer-array name="non_removable_euicc_slots">
<item>1</item>
</integer-array>
If a device has three physical slots and slot 1 and 2 are eUICCs, then the value of
this array should be:
<integer-array name="non_removable_euicc_slots">
<item>1</item>
<item>2</item>
</integer-array>
This is used to differentiate between removable eUICCs and built in eUICCs, and should
be set by OEMs for devices which use eUICCs. -->
<integer-array name="non_removable_euicc_slots">
<item>1</item>
</integer-array>
</resources>
Pour obtenir la liste complète des exigences de modem, consultez Exigences de modem pour la prise en charge des eSIM.
EuiccService
Un LPA se compose de deux composants distincts (ils peuvent tous deux être implémentés dans le même APK): le backend LPA et l'UI LPA ou LUI.
Pour implémenter le backend LPA, vous devez étendre
EuiccService
et déclarez ce service dans votre fichier manifeste. Le service doit exiger
android.permission.BIND_EUICC_SERVICE
l'autorisation système pour s'assurer que uniquement
le système peut s'y associer. Le service doit également inclure un filtre d'intent avec
l'action android.service.euicc.EuiccService
. La priorité de l'intent
le filtre doit être défini sur une valeur non nulle dans le cas où plusieurs implémentations seraient
présentes sur l'appareil. Exemple :
<service
android:name=".EuiccServiceImpl"
android:permission="android.permission.BIND_EUICC_SERVICE">
<intent-filter android:priority="100">
<action android:name="android.service.euicc.EuiccService" />
</intent-filter>
</service>
En interne, le framework Android détermine le LPA actif et interagit avec
afin de prendre en charge les API Android eUICC. La requête PackageManager
est interrogée
toutes les applications disposant de l'autorisation android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS
qui spécifie un service pour l'action android.service.euicc.EuiccService
.
Le service ayant la priorité la plus élevée est sélectionné. Si aucun service n'est trouvé, LPA
la prise en charge est désactivée.
Pour implémenter l'interface utilisateur, vous devez fournir une activité pour les actions suivantes:
android.service.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS
android.service.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION
Comme pour le service, chaque activité doit nécessiter
Autorisation système android.permission.BIND_EUICC_SERVICE
. Chacun d'eux doit comporter
le filtre d'intent correspondant à l'action appropriée,
la catégorie android.service.euicc.category.EUICC_UI
et une priorité non nulle.
Une logique similaire est utilisée pour choisir les implémentations pour ces activités
le choix de l'implémentation
EuiccService
Exemple :
<activity android:name=".MyLuiActivity"
android:exported="true"
android:permission="android.permission.BIND_EUICC_SERVICE">
<intent-filter android:priority="100">
<action android:name="android.service.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS" />
<action android:name="android.service.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.service.euicc.category.EUICC_UI" />
</intent-filter>
</activity>
Cela implique que l'UI qui implémente ces écrans peut provenir
APK issu de celui qui met en œuvre
EuiccService
Indique s'il faut un seul ou plusieurs APK (par exemple, un qui implémente
EuiccService
et un autre qui fournit des activités LUI) est un choix de conception.
EuiccCardManager
EuiccCardManager
est l'interface permettant de communiquer avec la puce eSIM. Il
fournit les fonctions ES10 (telles que décrites dans la spécification RSP GSMA) et gère les
les commandes de requête/réponse APDU de bas niveau
ainsi que l'analyse ASN.1.
EuiccCardManager
est une API système qui ne peut être appelée que par des privilèges système
applications.
Figure 2. L'application de l'opérateur et l'application LPA utilisent des API Euicc
Les API d'opération de profil via EuiccCardManager
exigent que l'appelant soit
un LPA. Cette règle est appliquée par le framework Android. Cela signifie que l'appelant doit
étendre EuiccService
et être déclaré dans votre fichier manifeste, comme décrit dans
les sections précédentes.
Comme pour EuiccManager
, pour utiliser les API EuiccCardManager
, votre LPA doit
obtenez d'abord l'instance de EuiccCardManager
via
Context#getSystemService
:
EuiccCardManager cardMgr = (EuiccCardManager) context.getSystemService(Context.EUICC_CARD_SERVICE);
Ensuite, pour obtenir tous les profils sur l'eUICC:
ResultCallback<EuiccProfileInfo[]> callback =
new ResultCallback<EuiccProfileInfo[]>() {
@Override
public void onComplete(int resultCode,
EuiccProfileInfo[] result) {
if (resultCode == EuiccCardManagerReflector.RESULT_OK) {
// handle result
} else {
// handle error
}
}
};
cardMgr.requestAllProfiles(eid, AsyncTask.THREAD_POOL_EXECUTOR, callback);
En interne, EuiccCardManager
se lie à EuiccCardController
(qui s'exécute dans le
un processus téléphonique) via une interface AIDL et chaque méthode EuiccCardManager
reçoit son rappel du processus téléphonique via un autre service AIDL dédié
de commande. Lorsque vous utilisez les API EuiccCardManager
, l'appelant (LPA) doit fournir une
Executor
via lequel le rappel est invoqué. Cet objet Executor
peut s'exécuter sur
sur un seul thread ou sur un pool de threads de votre choix.
La plupart des API EuiccCardManager
ont le même schéma d'utilisation. Par exemple, pour charger un
de profil lié à l'eUICC:
...
cardMgr.loadBoundProfilePackage(eid, boundProfilePackage,
AsyncTask.THREAD_POOL_EXECUTOR, callback);
Pour passer à un autre profil avec un ICCID donné:
...
cardMgr.switchToProfile(eid, iccid, true /* refresh */,
AsyncTask.THREAD_POOL_EXECUTOR, callback);
Pour obtenir l'adresse SM-DP+ par défaut à partir de la puce eUICC:
...
cardMgr.requestDefaultSmdpAddress(eid, AsyncTask.THREAD_POOL_EXECUTOR,
callback);
Pour récupérer la liste des notifications des événements de notification donnés:
...
cardMgr.listNotifications(eid,
EuiccNotification.Event.INSTALL
| EuiccNotification.Event.DELETE /* events */,
AsyncTask.THREAD_POOL_EXECUTOR, callback);
Activer un profil eSIM via une application d'opérateur
Sur les appareils équipés d'Android 9 ou version ultérieure, vous pouvez utiliser l'application de l'opérateur pour activer
l'eSIM et télécharger les profils. L'application de l'opérateur peut
télécharger des profils en
Appel en cours
downloadSubscription
directement ou en fournissant un code
d'activation à la LPA.
Lorsqu'une application d'opérateur télécharge un profil en appelant
downloadSubscription
l'appel impose que l'application puisse gérer le profil via un BF76
balise de métadonnées
qui encode les règles de privilège de l'opérateur pour le
profil. Si un profil ne comporte pas de balise BF76
ou si sa balise BF76
n'en comporte pas
ne correspond pas à la signature de l'application de l'opérateur téléphonique, le téléchargement est refusé.
La section ci-dessous décrit l'activation d'une eSIM via l'application d'un opérateur à l'aide d'un code d'activation.
Activer l'eSIM à l'aide d'un code d'activation
Lorsque vous utilisez un code d'activation pour activer un profil eSIM, le LPA récupère
un code d'activation
l'application de l'opérateur
et télécharge le profil. Ce flux peut être lancé par le LPA
et le LPA peut contrôler l'ensemble du flux d'UI, ce qui signifie qu'aucune UI d'application d'opérateur n'est
affichés. Cette approche permet de contourner la vérification du tag BF76
, et les opérateurs réseau
besoin d'implémenter l'intégralité du flux d'interface utilisateur d'activation eSIM, y compris le téléchargement d'un
le profil eSIM et la gestion des erreurs.
Définir le service de provisionnement eUICC de l'opérateur
L’application LPA et l’application de l’opérateur
communiquent via deux
AIDL
interfaces:
ICarrierEuiccProvisioningService
et IGetActivationCodeCallback
. L'opérateur
l'application doit implémenter une interface ICarrierEuiccProvisioningService
et
l'exposer dans son
déclaration du fichier manifeste.
Le LPA doit être lié à ICarrierEuiccProvisioningService
et implémenter
IGetActivationCodeCallback
Pour en savoir plus sur l'implémentation et
exposer une interface AIDL : consultez la section Définition et interface AIDL.
Pour définir les interfaces AIDL, créez les fichiers AIDL suivants pour l'application LPA et celle de l'opérateur.
ICarrierEuiccProvisioningService.aidl
package android.service.euicc; import android.service.euicc.IGetActivationCodeCallback; oneway interface ICarrierEuiccProvisioningService { // The method to get the activation code from the carrier app. The caller needs to pass in // the implementation of IGetActivationCodeCallback as the parameter. void getActivationCode(in IGetActivationCodeCallback callback); // The method to get the activation code from the carrier app. The caller needs to pass in // the activation code string as the first parameter and the implementation of // IGetActivationCodeCallback as the second parameter. This method provides the carrier // app the device EID which allows a carrier to pre-bind a profile to the device's EID before // the download process begins. void getActivationCodeForEid(in String eid, in IGetActivationCodeCallback callback); }
IGetActivationCodeCallback.aidl
package android.service.euicc; oneway interface IGetActivationCodeCallback { // The call back method needs to be called when the carrier app gets the activation // code successfully. The caller needs to pass in the activation code string as the // parameter. void onSuccess(String activationCode); // The call back method needs to be called when the carrier app failed to get the // activation code. void onFailure(); }
Exemple d'implémentation de l'application LPA
Pour vous lier à l'implémentation ICarrierEuiccProvisioningService
de l'application de l'opérateur,
le LPA doit copier à la fois ICarrierEuiccProvisioningService.aidl
et
IGetActivationCodeCallback.aidl
à votre projet et implémenter
ServiceConnection
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
mCarrierProvisioningService = ICarrierEuiccProvisioningService.Stub.asInterface(iBinder);
}
Après la liaison au ICarrierEuiccProvisioningService
de l'appli de l'opérateur
l'implémentation, le LPA appelle getActivationCode
ou
getActivationCodeForEid
pour obtenir le code d'activation de l'application de l'opérateur d'ici le
en transmettant l'implémentation de la classe bouchon IGetActivationCodeCallback
.
La différence entre getActivationCode
et getActivationCodeForEid
est que
getActivationCodeForEid
permet à un opérateur de pré-lier un profil à l'appareil
EID avant le début du processus de téléchargement.
void getActivationCodeFromCarrierApp() {
IGetActivationCodeCallback.Stub callback =
new IGetActivationCodeCallback.Stub() {
@Override
public void onSuccess(String activationCode) throws RemoteException {
// Handle the case LPA success to get activation code from a carrier app.
}
@Override
public void onFailure() throws RemoteException {
// Handle the case LPA failed to get activation code from a carrier app.
}
};
try {
mCarrierProvisioningService.getActivationCode(callback);
} catch (RemoteException e) {
// Handle Remote Exception
}
}
Exemple d'implémentation pour une application d'opérateur
Pour que la LPA s'associe à l'application de l'opérateur, celle-ci doit copier les deux
ICarrierEuiccProvisioningService.aidl
et IGetActivationCodeCallback.aidl
à
votre projet et déclarez le service ICarrierEuiccProvisioningService
dans
AndroidManifest.xml
. Le service doit exiger
android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS
autorisation système pour garantir
que seul le LPA, une application privilégiée du système, peut s’y lier. Le service doit
incluent également un filtre d'intent
Action android.service.euicc.action.BIND_CARRIER_PROVISIONING_SERVICE
.
AndroidManifest.xml
<application> ... <service android:name=".CarrierEuiccProvisioningService" android:exported="true" android:permission="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"> <intent-filter> <action android:name="android.service.euicc.action.BIND_CARRIER_PROVISIONING_SERVICE"/> </intent-filter> </service> ... </application>
Pour implémenter le service d'application de l'opérateur AIDL, créez un service, étendez Stub
et implémenter getActivationCode
et getActivationCodeForEid
.
méthodes. Le LPA peut ensuite appeler l'une ou l'autre des méthodes pour récupérer l'activation du profil.
du code source. L'application de l'opérateur doit répondre en appelant
IGetActivationCodeCallback#onSuccess
par le code d'activation, si le code était
récupérées sur le serveur de l'opérateur. En cas d'échec, l'application de l'opérateur
doit répondre par IGetActivationCodeCallback#onFailure
.
CarrierEuiccProvisioningService.java
import android.service.euicc.ICarrierEuiccProvisioningService; import android.service.euicc.ICarrierEuiccProvisioningService.Stub; import android.service.euicc.IGetActivationCodeCallback; public class CarrierEuiccProvisioningService extends Service { private final ICarrierEuiccProvisioningService.Stub binder = new Stub() { @Override public void getActivationCode(IGetActivationCodeCallback callback) throws RemoteException { String activationCode = // do whatever work necessary to get an activation code (HTTP requests to carrier server, fetch from storage, etc.) callback.onSuccess(activationCode); } @Override public void getActivationCodeForEid(String eid, IGetActivationCodeCallback callback) throws RemoteException { String activationCode = // do whatever work necessary (HTTP requests, fetch from storage, etc.) callback.onSuccess(activationCode); } } }
Démarrer l'interface utilisateur de l'application de l'opérateur dans le flux d'activation de l'application LPA
Sur les appareils équipés d'Android 11 ou version ultérieure, le LPA peut lancer l'interface utilisateur d'une application d'opérateur. Ceci est utile, car l'appli d'un opérateur peut avoir besoin d'informations supplémentaires avant de fournir un code d'activation au LPA. Par exemple, les opérateurs peuvent exiger des utilisateurs qu'ils se connectent pour activer leur numéro de téléphone ou effectuer d'autres transferts services.
Voici le processus permettant de démarrer l'interface utilisateur d'une application d'opérateur dans le LPA:
La LPA lance le flux d'activation de l'application de l'opérateur en envoyant le l'intent
android.service.euicc.action.START_CARRIER_ACTIVATION
à la classe package d'application de l'opérateur contenant l'action. (Le récepteur de l'application de l'opérateur doit être protégées dans la déclaration du fichier manifesteandroid:permission="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"
jusqu'à éviter de recevoir des intents d'applications non LPA.)String packageName = // The carrier app's package name Intent carrierAppIntent = new Intent(“android.service.euicc.action.START_CARRIER_ACTIVATION”) .setPackage(packageName); ResolveInfo activity = context.getPackageManager().resolveActivity(carrierAppIntent, 0); carrierAppIntent .setClassName(activity.activityInfo.packageName, activity.activityInfo.name); startActivityForResult(carrierAppIntent, requestCode);
L'application de l'opérateur effectue son travail à l'aide de sa propre interface utilisateur. Par exemple, Logging ou l'envoi de requêtes HTTP au backend de l'opérateur.
L'application de l'opérateur répond au LPA en appelant
setResult(int, Intent)
etfinish()
.- Si l'application de l'opérateur répond avec
RESULT_OK
, le LPA poursuit le flux d'activation. Si l'application de l'opérateur détermine que l'utilisateur doit scanner un code QR au lieu de laisser l'application LPA lier l'opérateur l'application de l'opérateur répond à la LPA en utilisantsetResult(int, Intent)
avecRESULT_OK
et une instanceIntent
contenant l'extra booléenandroid.telephony.euicc.extra.USE_QR_SCANNER
défini surtrue
. LPA puis vérifie l'extra et lance le lecteur de code QR au lieu de lier l'implémentationICarrierEuiccProvisioningService
de l'application de l'opérateur ; - Si l'application de l'opérateur plante ou répond avec
RESULT_CANCELED
(il s'agit du code de réponse par défaut), le LPA annule l'eSIM processus d'activation. - Si l'application de l'opérateur renvoie un résultat autre que
RESULT_OK
ouRESULT_CANCELED
, le LPA le traite comme une erreur.
Pour des raisons de sécurité, le LPA ne doit pas accepter directement un code d'activation fourni dans l'intent de résultat pour garantir que les tests non-LPA les appelants ne peuvent pas obtenir de code d'activation via l'application de l'opérateur.
- Si l'application de l'opérateur répond avec
Lancer le flux d'activation LPA dans une application d'opérateur
À partir d'Android 11, les applis d'opérateur peuvent utiliser les API eUICC pour démarrer une LUI pour l'eSIM l'activation. Cette méthode présente l'UI du flux d'activation eSIM de la LPA à activer le profil eSIM. La LPA envoie ensuite une annonce lorsque le profil eSIM l'activation est terminée.
Le LPA doit déclarer une activité comprenant un filtre d'intent avec Action
android.service.euicc.action.START_EUICC_ACTIVATION
. La priorité du filtre d'intent doit être défini sur une valeur non nulle si plusieurs implémentations présentes sur l'appareil. Exemple :<application> ... <activity android:name=".CarrierAppInitActivity" android:exported="true"> <intent-filter android:priority="100"> <action android:name="android.service.euicc.action.START_EUICC_ACTIVATION" /> </intent-filter> </activity> ... </application>
L'application de l'opérateur effectue son travail à l'aide de sa propre interface utilisateur. Par exemple, Logging ou l'envoi de requêtes HTTP au backend de l'opérateur.
À ce stade, l'application de l'opérateur doit être prête à fournir une activation. via son implémentation
ICarrierEuiccProvisioningService
. La l'application de l'opérateur lance l'application du LPA en appelantstartActivityForResult(Intent, int)
avec leandroid.telephony.euicc.action.START_EUICC_ACTIVATION
action. Le LPA vérifie également l'extra booléenandroid.telephony.euicc.extra.USE_QR_SCANNER
Si la valeur esttrue
, le LPA lance le lecteur de code QR pour permettre à l'utilisateur de scanner le code QR du profil.Du côté de la LPA, celle-ci se lie au LPA Implémentation de
ICarrierEuiccProvisioningService
pour récupérer l'activation code et téléchargez le profil correspondant. Le LPA affiche toutes les données Des éléments d'interface utilisateur pendant le téléchargement, comme un écran de chargementUne fois le flux d'activation de LPA terminé, le LPA répond au l'application de l'opérateur avec un code de résultat, que l'appli de l'opérateur gère dans
onActivityResult(int, int, Intent)
- Si le LPA réussit à télécharger le nouveau profil eSIM, il
répond avec
RESULT_OK
. - Si l'utilisateur annule l'activation du profil eSIM dans le LPA, il
répond avec
RESULT_CANCELED
. - Si l'application LPA renvoie une réponse autre que
RESULT_OK
ouRESULT_CANCELED
, l'appli de l'opérateur considère cela comme une erreur.
Pour des raisons de sécurité, l'API LPA n'accepte pas les codes d'activation. directement dans l'intent fourni pour garantir que les appelants non-LPA ne peuvent pas le code d'activation à partir de l'application de l'opérateur.
- Si le LPA réussit à télécharger le nouveau profil eSIM, il
répond avec
Assurer la compatibilité avec plusieurs cartes eSIM
Pour les appareils équipés d'Android 10 ou version ultérieure,
La classe EuiccManager
est compatible avec les appareils
avec plusieurs eSIM. Appareils avec une seule eSIM qui passent à
Android 10
n'exigent aucune modification de l'implémentation de LPA en tant que plate-forme
associe automatiquement l'instance EuiccManager
à l'eUICC par défaut. La
L'eUICC par défaut est déterminé par la plate-forme pour les appareils dotés de la version HAL radio
1.2 ou version ultérieure et par LPA pour les appareils dotés de versions HAL radio antérieures à
1.2.
Conditions requises
Pour prendre en charge plusieurs eSIM, l'appareil doit disposer de plusieurs eUICC, ce qui peut être soit un eUICC intégré, soit un emplacement SIM physique où des eUICC amovibles peuvent être inséré.
La version 1.2 ou ultérieure de Radio HAL est requise pour prendre en charge plusieurs eSIM. Radio HAL Les versions 1.4 et 1.2 de RadioConfig HAL sont recommandées.
Implémentation
Pour prendre en charge plusieurs eSIM (y compris les cartes EUICC amovibles ou les cartes SIM programmables), la
doivent implémenter
EuiccService
qui reçoit l'ID d'emplacement correspondant à l'ID de la carte fournie par l'appelant.
La
non_removable_euicc_slots
ressource spécifiée dans
arrays.xml
est un tableau d'entiers représentant les ID d'emplacement de l'instance
eUICC Vous devez spécifier cette ressource pour permettre à la plate-forme de déterminer
si un eUICC inséré est amovible ou non.
Application de l'opérateur pour l'appareil avec plusieurs eSIM
Lorsque vous créez une application d'opérateur pour un appareil avec plusieurs eSIM, utilisez le
createForCardId
dans EuiccManager
pour créer un objet EuiccManager
épinglé à un
l'ID de la carte fournie. L'ID de carte est un nombre entier qui identifie un UICC de manière unique.
ou eUICC sur l'appareil.
Pour obtenir l'ID de carte correspondant à l'eUICC par défaut de l'appareil, utilisez le
getCardIdForDefaultEuicc
dans TelephonyManager
. Cette méthode renvoie
UNSUPPORTED_CARD_ID
si la version radio HAL est antérieure à 1.2 et renvoie
UNINITIALIZED_CARD_ID
si l'appareil n'a pas lu l'eUICC.
Vous pouvez également obtenir
les ID de carte de
getUiccCardsInfo
et getUiccSlotsInfo
(API système) dans TelephonyManager
, et
getCardId
dans SubscriptionInfo
.
Lorsqu'un objet EuiccManager
a été instancié avec un ID de carte spécifique, tous
des opérations sont dirigées vers l’eUICC
avec cet ID de carte. Si l'eUICC devient
inaccessible (par exemple, lorsqu'elle est désactivée ou supprimée) EuiccManager
non
fonctionne plus longtemps.
Vous pouvez utiliser les exemples de code suivants pour créer une application d'opérateur.
Exemple 1: Obtenir un abonnement actif et instancier EuiccManager
// Get the active subscription and instantiate an EuiccManager for the eUICC which holds
// that subscription
SubscriptionManager subMan = (SubscriptionManager)
mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
int cardId = subMan.getActiveSubscriptionInfo().getCardId();
EuiccManager euiccMan = (EuiccManager) mContext.getSystemService(Context.EUICC_SERVICE)
.createForCardId(cardId);
Exemple 2: Effectuer une itération via les UICC et instancier EuiccManager
pour un
eUICC amovible
// On a device with a built-in eUICC and a removable eUICC, iterate through the UICC cards
// to instantiate an EuiccManager associated with a removable eUICC
TelephonyManager telMan = (TelephonyManager)
mContext.getSystemService(Context.TELEPHONY_SERVICE);
List<UiccCardInfo> infos = telMan.getUiccCardsInfo();
int removableCardId = -1; // valid cardIds are 0 or greater
for (UiccCardInfo info : infos) {
if (info.isRemovable()) {
removableCardId = info.getCardId();
break;
}
}
if (removableCardId != -1) {
EuiccManager euiccMan = (EuiccManager) mContext.getSystemService(Context.EUICC_SERVICE)
.createForCardId(removableCardId);
}
Validation
AOSP n’est pas fourni avec une implémentation LPA et vous n’êtes pas censé ont un LPA disponible sur tous les builds Android (tous les téléphones ne sont pas compatibles avec eSIM). Pour il n'existe aucun scénario de test CTS de bout en bout. Toutefois, les scénarios de test de base sont disponibles dans AOSP pour garantir que les API eUICC exposées sont valides dans les builds Android.
Vous devez vous assurer que les builds réussissent les scénarios de test CTS suivants (pour les API): /platform/cts/tests/tests/telephony/current/src/android/telephony/euicc/cts.
Les opérateurs qui mettent en place une application d'opérateur doivent appliquer leurs processus habituels en interne assurance qualité cycles pour s'assurer que toutes les fonctionnalités implémentées fonctionnent comme prévu. Au l'application de l'opérateur doit pouvoir répertorier tous les profils d'abonnement appartenant au même opérateur, télécharger et installer un profil, activer un service, sur le profil, passer d'un profil à l'autre et supprimer des profils.
Si vous créez votre propre APA, vous devez vous soumettre à des examens tests. Vous devez contacter le fournisseur de votre modem, de votre puce électronique eUICC ou de votre système d'exploitation eSIM, les opérateurs et fournisseurs SM-DP+ pour résoudre les problèmes et garantir l'interopérabilité des votre LPA dans l'architecture RSP. Une bonne partie des tests manuels est inévitable. Pour optimiser la couverture de test, suivez les instructions Plan de test RSP GSMA SGP.23