La tecnologia SIM integrata (eSIM o eUICC) consente agli utenti di dispositivi mobili scaricare il profilo di un operatore e attivare il servizio di un operatore senza una scheda SIM fisica. Si tratta di una specifica globale gestita da GSMA che consente il provisioning remoto di SIM (RSP) di qualsiasi dispositivo mobile. A partire da Android 9, il framework Android fornisce API standard per accesso all'eSIM e gestione dei profili degli abbonamenti sull'eSIM. Queste eUICC Le API consentono a terze parti di sviluppare le proprie app dell'operatore e il proprio profilo locale assistenti (LPA) su dispositivi Android con eSIM.
L'LPA è un'app di sistema autonoma che deve essere inclusa nel Immagine build Android. La gestione dei profili sull'eSIM viene generalmente eseguita l'LPA, in quanto funge da collegamento tra SM-DP+ (servizio remoto che prepara, memorizza e invia pacchetti di profili ai dispositivi) e il chip eUICC. L'APK LPA può facoltativamente includere un componente dell'interfaccia utente, chiamato UI o LUI, per fornire all'utente finale una posizione centralizzata per la gestione di tutti gli abbonamenti incorporati profili. Il framework Android rileva e si connette automaticamente ai LPA disponibile e instrada tutte le operazioni eUICC attraverso un'istanza LPA.
Figura 1. Architettura RSP semplificata
Gli operatori di rete mobile interessati a creare un'app dell'operatore dovrebbero consultare
le API
EuiccManager
,
che offre operazioni di gestione del profilo di alto livello come
downloadSubscription()
, switchToSubscription()
e
deleteSubscription()
.
Se sei un OEM di dispositivi e ti interessa creare la tua app di sistema LPA, devi:
estendere
EuiccService
affinché il framework Android si connetta ai tuoi servizi LPA. Inoltre,
devono utilizzare le API
EuiccCardManager
,
che forniscono funzioni ES10x basate su GSMA RSP v2.0.
Queste funzioni vengono utilizzate per inviare comandi al chip eUICC, come
prepareDownload()
, loadBoundProfilePackage()
, retrieveNotificationList()
e resetMemory()
.
Le API in
EuiccManager
richiedono un'app LPA correttamente implementata per funzionare e il chiamante
EuiccCardManager
Le API devono essere un LPA. Questa operazione viene applicata dal framework Android.
I dispositivi con Android 10 o versioni successive supportano con più eSIM. Per ulteriori informazioni, vedi Supporto di più eSIM.
Crea un'app dell'operatore
Le API eUICC in Android 9 rendono possibile operatori di rete mobile di creare app con il brand dell'operatore per gestire i propri profili. Sono inclusi il download e l'eliminazione dei profili degli abbonamenti. di proprietà dell'operatore, nonché il passaggio a un profilo di proprietà di un operatore.
Gestore Euicc
EuiccManager
è il punto di accesso principale per l'interazione delle app con
LPA. Sono incluse le app dell'operatore che scaricano, eliminano e passano a
abbonamenti di proprietà dell'operatore. È compresa anche l'app di sistema LUI,
fornisce una posizione/interfaccia utente centrale per la gestione di tutti gli abbonamenti incorporati, e
può essere un'app separata da quella che fornisce EuiccService
.
Per usare le API pubbliche, un'app dell'operatore deve prima ottenere l'istanza
Da EuiccManager
a Context#getSystemService
:
EuiccManager mgr = (EuiccManager) context.getSystemService(Context.EUICC_SERVICE);
Devi controllare se l'eSIM è supportata sul dispositivo prima di eseguire qualsiasi
Operazioni dell'eSIM. EuiccManager#isEnabled()
generalmente restituisce true
se
La funzionalità android.hardware.telephony.euicc
è definita e un pacchetto LPA è
presenti.
if (mgr == null || !mgr.isEnabled()) {
return;
}
Per informazioni sull'hardware eUICC e sulla versione del sistema operativo eSIM:
EuiccInfo info = mgr.getEuiccInfo();
String osVer = info.getOsVersion();
Molte API, ad esempio downloadSubscription()
e switchToSubscription()
, utilizzano
PendingIntent
perché potrebbero richiedere secondi o persino minuti.
PendingIntent
viene inviato con un codice risultato in
EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_
, che fornisce
codici di errore definiti dal framework, nonché un codice risultato dettagliato arbitrario
propagato dall'LPA come EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE
, consentendo
l'app dell'operatore per monitorare i fini di logging/debug. PendingIntent
il callback deve essere BroadcastReceiver
.
Per scaricare un determinato abbonamento scaricabile (creato da un codice di attivazione o un codice 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);
Definisci e utilizza l'autorizzazione in AndroidManifest.xml
:
<permission android:protectionLevel="signature" android:name="com.your.company.lpa.permission.BROADCAST" />
<uses-permission android:name="com.your.company.lpa.permission.BROADCAST"/>
Per passare a un abbonamento in base all'ID abbonamento:
// 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);
Per un elenco completo di API EuiccManager
ed esempi di codice, consulta
API eUICC.
Errori risolvibili
In alcuni casi il sistema non è in grado di completare l'operazione dell'eSIM
ma l'errore può essere risolto dall'utente. Ad esempio, downloadSubscription
potrebbe non riuscire se i metadati del profilo indicano che un codice di conferma dell'operatore
è obbligatorio. Oppure switchToSubscription
potrebbe non funzionare se l'app dell'operatore ha un operatore
privilegiati sul profilo di destinazione (ossia, l'operatore è proprietario del profilo), ma
non dispone dei privilegi di operatore rispetto al profilo attualmente abilitato, pertanto
il consenso dell'utente è obbligatorio.
In questi casi, la richiamata del chiamante viene chiamata con
EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR
. Il callback
Intent
contiene extra interni che, quando il chiamante la passa a
EuiccManager#startResolutionActivity
,
può essere richiesta tramite la LUI. L'utilizzo del codice di conferma per
di nuovo un esempio,
EuiccManager#startResolutionActivity
attiva una schermata LUI che consente all'utente di inserire un codice di conferma;
dopo l'inserimento del codice, l'operazione di download viene ripresa. Questo approccio
offre all'app dell'operatore il pieno controllo su quando viene mostrata l'UI, ma fornisce
LPA/LUI, un metodo estensibile per aggiungere una nuova gestione dei contenuti recuperabili dall'utente
in futuro senza dover modificare le app client.
Android 9 definisce questi errori risolvibili in
EuiccService
,
che la LUI deve gestire:
/**
* 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";
Privilegi dell'operatore
Se sei un operatore che sviluppa un'app del tuo operatore che chiama EuiccManager
per scaricare i profili su un dispositivo, il tuo profilo deve includere l'operatore
le regole sui privilegi corrispondenti all'app dell'operatore nei metadati. Questo è
dato che i profili di abbonamento che appartengono a operatori diversi possono coesistere in
alla eUICC di un dispositivo e a ogni app dell'operatore deve essere consentito accedere soltanto
profili di proprietà dell'operatore in questione. Ad esempio, l'operatore A non deve essere in grado
scaricare, attivare o disattivare un profilo di proprietà dell'operatore B.
Per garantire che un profilo sia accessibile solo al suo proprietario, Android utilizza un meccanismo per
concedere privilegi speciali all'app del proprietario del profilo (ossia l'app dell'operatore). La
La piattaforma Android carica i certificati archiviati nel file delle regole di accesso del profilo
(ARF) e concede alle app firmate da questi certificati l'autorizzazione per effettuare chiamate
alle API di EuiccManager
. La procedura generale è descritta di seguito:
- L'operatore firma l'APK dell'app dell'operatore; il apksigner collega il certificato di chiave pubblica all'APK.
Operator/SM-DP+ prepara un profilo e i relativi metadati, che includono un ARF che contiene:
- Firma (SHA-1 o SHA-256) del certificato di chiave pubblica dell'app dell'operatore (obbligatorio)
- Nome del pacchetto dell'app dell'operatore (vivamente consigliato)
L'app dell'operatore tenta di eseguire un'operazione eUICC con l'API
EuiccManager
.La piattaforma Android verifica l'hash SHA-1 o SHA-256 dell'app chiamante corrisponda alla firma del certificato ottenuto ARF del profilo di destinazione. Se il nome del pacchetto dell'app dell'operatore è incluso nella l'ARF, deve corrispondere anche al nome del pacchetto dell'app del chiamante.
Dopo aver verificato la firma e il nome del pacchetto (se incluso), i campi All'app chiamante viene concesso il privilegio dell'operatore al profilo di destinazione.
Poiché i metadati del profilo possono essere disponibili all'esterno del profilo stesso (in modo che LPA può recuperare i metadati del profilo da SM-DP+ prima che il profilo scaricato o da ISD-R quando il profilo è disattivato), questo dovrebbe contenere le stesse regole sui privilegi dell'operatore del profilo.
Il sistema operativo eUICC e SM-DP+ devono supportare un tag proprietario BF76
nel profilo
metadati. I contenuti del tag devono corrispondere alle regole relative ai privilegi dell'operatore restituiti
dall'applet delle regole di accesso (ARA) definito in
Privilegi dell'operatore 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
}
}
Per maggiori dettagli sulla firma dell'app, vedi Firma l'app. Per maggiori dettagli sui privilegi dell'operatore, vedi Privilegi dell'operatore UICC.
Crea un'app di assistente del profilo locale
I produttori di dispositivi possono implementare il proprio assistente di profilo locale (LPA), che devono essere agganciati con le API Android Euicc. Le seguenti sezioni forniscono una breve panoramica creare un'app LPA e integrarla nel sistema Android.
Requisiti hardware/modem
L'LPA e il sistema operativo eSIM sul chip eUICC devono supportare almeno il protocollo GSMA RSP (Remote Provisioning SIM) v2.0 o v2.2. Dovresti anche pianificare l'uso di SM-DP+ e SM-DS con una versione RSP corrispondente. Per l'architettura dettagliata RSP, consulta Specifiche dell'architettura RSP GSMA SGP.21.
Inoltre, per l'integrazione con le API eUICC in Android 9, il modem del dispositivo deve inviare funzionalità del terminale con il supporto delle funzionalità eUICC codificate (gestione dei profili locali e download profilo). Inoltre, deve implementare i seguenti metodi:
- IRadio HAL v1.1:
setSimPower
IRadio HAL v1.2:
getIccCardStatus
IRadioConfig HAL v1.0:
getSimSlotsStatus
IRadioConfig AIDL v1.0:
getAllowedCarriers
L'LPA di Google deve conoscere lo stato del blocco dell'operatore per poter consentire il download o il trasferimento di eSIM solo per l'operatore autorizzato. In caso contrario, gli utenti potrebbero scaricare e trasferire una SIM e in un secondo momento scoprire che il dispositivo è bloccato dall'operatore di un altro operatore.
I fornitori o gli OEM devono implementare l'API IRadioSim.getAllowedCarriers()HAL.
Il Fornitore RIL / Modem completerà lo stato del blocco e il carrierId dell'operatore in cui il dispositivo è bloccato nell'ambito dell'API IRadioSimResponse.getAllowedCarriersResponse()HAL.
Il modem deve riconoscere l'eSIM con il profilo di avvio predefinito abilitato come una SIM valida e tienila accesa.
Per i dispositivi con Android 10, è prevista una eUICC non rimovibile
è necessario definire l'array di ID slot. Ad esempio, vedi
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>
Per un elenco completo dei requisiti del modem, vedi Requisiti del modem per l'assistenza eSIM.
Servizio Euicc
Un LPA è costituito da due componenti separati (possono essere implementati entrambi nello stesso APK): il backend LPA e l'UI o LUI LPA.
Per implementare il backend LPA, devi estendere
EuiccService
e dichiarare questo servizio nel tuo file manifest. Il servizio deve richiedere
android.permission.BIND_EUICC_SERVICE
di autorizzazione di sistema per garantire
che il sistema possa associarsi. Il servizio deve includere anche un filtro per intent con
l'azione android.service.euicc.EuiccService
. La priorità dell'intent
deve essere impostato su un valore diverso da zero nel caso in cui vengano eseguite più implementazioni
presente sul dispositivo. Ad esempio:
<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>
Internamente, il framework Android determina l'LPA attivo e interagisce con
se necessario per supportare le API Android eUICC. È stata eseguita una query su PackageManager
tutte le app con autorizzazione android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS
,
che specifica un servizio per l'azione android.service.euicc.EuiccService
.
Viene selezionato il servizio con la priorità più alta. Se non viene trovato alcun servizio, l'LPA
il supporto è disabilitato.
Per implementare la LUI, devi fornire un'attività per le seguenti azioni:
android.service.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS
android.service.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION
Come per il servizio, ogni attività deve richiedere la
android.permission.BIND_EUICC_SERVICE
autorizzazione di sistema. Ognuno di questi deve avere un
filtro per intent con l'azione appropriata,
android.service.euicc.category.EUICC_UI
e una priorità diversa da zero.
Viene utilizzata una logica simile per scegliere le implementazioni per queste attività
scegliere l'implementazione
EuiccService
Ad esempio:
<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>
Ciò implica che l'interfaccia utente che implementa queste schermate può provenire da un'origine
APK di quello che implementa
EuiccService
Indica se avere un singolo APK o più APK (ad esempio, uno che implementa
EuiccService
e uno che offre attività LUI) è una scelta di progettazione.
EuiccCardManager
EuiccCardManager
è l'interfaccia per comunicare con il chip eSIM. it
fornisce funzioni ES10 (come descritto nelle specifiche RSP GSMA) e gestisce
comandi di richiesta/risposta APDU di basso livello nonché analisi ASN.1.
EuiccCardManager
è un'API di sistema e può essere chiamato solo con privilegi di sistema
app.
Figura 2. Sia l'app dell'operatore sia l'LPA utilizzano le API Euicc
Le API per le operazioni del profilo tramite EuiccCardManager
richiedono che il chiamante
un LPA. Questa operazione viene applicata dal framework Android. Ciò significa che il chiamante deve
estendere EuiccService
e essere dichiarati nel file manifest, come descritto in
le sezioni precedenti.
Analogamente a EuiccManager
, per usare le API EuiccCardManager
, il tuo LPA deve
per prima cosa ottieni l'istanza di EuiccCardManager
Context#getSystemService
:
EuiccCardManager cardMgr = (EuiccCardManager) context.getSystemService(Context.EUICC_CARD_SERVICE);
Quindi, per recuperare tutti i profili sulla 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);
Internamente, EuiccCardManager
si associa a EuiccCardController
(che viene eseguito in
smartphone) mediante un'interfaccia AIDL e ciascun metodo EuiccCardManager
riceve la richiamata dalla procedura telefonica attraverso un AIDL dedicato diverso
a riga di comando. Quando si utilizzano le API EuiccCardManager
, il chiamante (LPA) deve fornire un
Executor
attraverso il quale viene richiamato il callback. Questo oggetto Executor
può essere eseguito
in un singolo thread o in un pool di thread di tua scelta.
La maggior parte delle EuiccCardManager
API ha lo stesso pattern di utilizzo. Ad esempio, per caricare un file
pacchetto del profilo associato alla eUICC:
...
cardMgr.loadBoundProfilePackage(eid, boundProfilePackage,
AsyncTask.THREAD_POOL_EXECUTOR, callback);
Per passare a un altro profilo con un determinato ICCID:
...
cardMgr.switchToProfile(eid, iccid, true /* refresh */,
AsyncTask.THREAD_POOL_EXECUTOR, callback);
Per ottenere l'indirizzo SM-DP+ predefinito dal chip eUICC:
...
cardMgr.requestDefaultSmdpAddress(eid, AsyncTask.THREAD_POOL_EXECUTOR,
callback);
Per recuperare un elenco di notifiche relative agli eventi di notifica specificati:
...
cardMgr.listNotifications(eid,
EuiccNotification.Event.INSTALL
| EuiccNotification.Event.DELETE /* events */,
AsyncTask.THREAD_POOL_EXECUTOR, callback);
Attiva un profilo eSIM tramite l'app di un operatore
Su dispositivi con Android 9 o versioni successive, puoi usare un'app dell'operatore per attivare
l'eSIM e scaricare profili. L'app dell'operatore può scaricare profili
chiamata
downloadSubscription
direttamente o fornendo un codice di attivazione all'LPA.
Quando un'app dell'operatore scarica un profilo chiamando
downloadSubscription
,
la chiamata impone che l'app possa gestire il profilo tramite un BF76
tag metadati
che codifica le regole dei privilegi dell'operatore per il
profilo. Se un profilo non ha un tag BF76
o se il relativo tag BF76
non ha un tag
corrisponda alla firma dell'app dell'operatore chiamante, il download viene rifiutato.
La sezione seguente descrive l'attivazione di una eSIM tramite l'app di un operatore utilizzando un di attivazione/disattivazione.
Attiva l'eSIM usando un codice di attivazione
Se usi un codice di attivazione per attivare un profilo eSIM, l'LPA recupera
un codice di attivazione
l'app dell'operatore e scarica il profilo. Questo flusso può essere avviato dall'LPA
e l'LPA può controllare l'intero flusso dell'interfaccia utente, perciò nessuna UI dell'app dell'operatore viene
come mostrato nell'immagine. Questo approccio ignora il controllo dei tag BF76
e gli operatori di rete non
implementare l'intero flusso dell'interfaccia utente di attivazione dell'eSIM, incluso il download di un
Profilo eSIM e gestione degli errori.
Definire il servizio di provisioning eUICC dell'operatore
L'LPA e l'app dell'operatore comunicano tramite due
AIDL
interfacce:
ICarrierEuiccProvisioningService
e IGetActivationCodeCallback
. Il vettore
l'app deve implementare un'interfaccia ICarrierEuiccProvisioningService
e
espongo nella sua
dichiarazione manifest.
L'LPA deve collegarsi a ICarrierEuiccProvisioningService
e implementare
IGetActivationCodeCallback
. Per ulteriori informazioni su come implementare
esporre un'interfaccia AIDL, consulta Definizione e interfaccia AIDL.
Per definire le interfacce AIDL, crea i seguenti file AIDL sia per l'app LPA che per l'app dell'operatore.
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(); }
Esempio di implementazione LPA
Per eseguire l'associazione all'implementazione ICarrierEuiccProvisioningService
dell'app dell'operatore,
l'LPA deve copiare sia ICarrierEuiccProvisioningService.aidl
che
IGetActivationCodeCallback.aidl
al progetto e implementa
ServiceConnection
.
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
mCarrierProvisioningService = ICarrierEuiccProvisioningService.Stub.asInterface(iBinder);
}
Dopo l'associazione con ICarrierEuiccProvisioningService
dell'app dell'operatore
implementazione, l'LPA chiama getActivationCode
o
getActivationCodeForEid
per ricevere il codice di attivazione dall'app dell'operatore entro il giorno
superare l'implementazione della classe stub IGetActivationCodeCallback
.
La differenza tra getActivationCode
e getActivationCodeForEid
è che
getActivationCodeForEid
consente a un operatore di pre-associare un profilo all'account del dispositivo
EID prima dell'inizio del processo di download.
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
}
}
Esempio di implementazione per l'app dell'operatore
Affinché l'LPA si colleghi all'app dell'operatore, l'app dell'operatore deve copiare entrambi
ICarrierEuiccProvisioningService.aidl
e IGetActivationCodeCallback.aidl
per
del progetto e dichiarare il servizio ICarrierEuiccProvisioningService
AndroidManifest.xml
file. Il servizio deve richiedere
android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS
autorizzazione di sistema per garantire
che solo l'LPA, un'app con privilegi di sistema, può associarla. Il servizio deve
includi anche un filtro per intent con
Azione 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>
Per implementare il servizio dell'app dell'operatore AIDL, crea un servizio ed estendi il Stub
e implementare getActivationCode
e getActivationCodeForEid
di machine learning. L'LPA può quindi chiamare uno dei due metodi per recuperare l'attivazione del profilo
le API nel tuo codice. L'app dell'operatore dovrebbe rispondere chiamando
IGetActivationCodeCallback#onSuccess
con il codice di attivazione, se il codice era
recuperato correttamente dal server dell'operatore. Se non funziona, l'app dell'operatore
dovrebbe rispondere con 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); } } }
Avvia l'interfaccia utente dell'app dell'operatore nel flusso di attivazione LPA
Sui dispositivi con Android 11 e versioni successive, l'LPA può avviare l'UI dell'app di un operatore. È utile perché l'app dell'operatore potrebbe richiedere ulteriori informazioni dall' l'utente prima di fornire un codice di attivazione all'LPA. Ad esempio, gli operatori richiedere agli utenti di eseguire l'accesso per attivare i propri numeri di telefono o eseguire altre portazioni i servizi di machine learning.
Questa è la procedura per avviare nell'LPA l'interfaccia utente dell'app dell'operatore:
L'LPA avvia il flusso di attivazione dell'app dell'operatore inviando il metodo intent di
android.service.euicc.action.START_CARRIER_ACTIVATION
alla pacchetto dell'app dell'operatore contenente l'azione. Il destinatario dell'app dell'operatore deve essere protetti nella dichiarazione del file manifest con Daandroid:permission="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"
a evitare di ricevere intent da app 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'app dell'operatore svolge il proprio lavoro utilizzando la propria UI. Ad esempio, logging presenti nell'utente o inviare richieste HTTP al backend dell'operatore.
L'app dell'operatore risponde all'LPA chiamando il numero
setResult(int, Intent)
efinish()
.- Se l'app dell'operatore risponde con
RESULT_OK
, l'LPA continua il flusso di attivazione. Se l'app dell'operatore stabilisce che l'utente deve scansionare un codice QR anziché permettere all'LPA di vincolare l'operatore al servizio dell'app, l'app dell'operatore risponde all'LPA usandosetResult(int, Intent)
conRESULT_OK
e un'istanzaIntent
contenente il valore extra booleanoandroid.telephony.euicc.extra.USE_QR_SCANNER
impostato sutrue
. LPA poi controlla l'extra e avvia lo scanner QR invece di eseguire il binding l'implementazione diICarrierEuiccProvisioningService
dell'app dell'operatore. - Se l'app dell'operatore si arresta in modo anomalo o risponde con
RESULT_CANCELED
(questo è il codice di risposta predefinito), l'LPA annulla l'eSIM flusso di attivazione. - Se l'app dell'operatore risponde con qualcosa di diverso da
RESULT_OK
oRESULT_CANCELED
, l'LPA lo considera un errore.
Per motivi di sicurezza, l'LPA non deve accettare direttamente un fornito nell'intent di risultato per garantire che le i chiamanti non possono ricevere un codice di attivazione dall'app dell'operatore.
- Se l'app dell'operatore risponde con
Avvia il flusso di attivazione LPA in un'app dell'operatore
A partire da Android 11, le app dell'operatore possono usare le API eUICC per avviare una LUI per eSIM dell'attivazione. Questo metodo mostra l'UI del flusso di attivazione eSIM dell'LPA per l'attivazione il profilo eSIM. L'LPA invia quindi un annuncio quando il profilo eSIM e l'attivazione termina l'attivazione.
L'LPA deve dichiarare un'attività che includa un filtro per intent con Azione
android.service.euicc.action.START_EUICC_ACTIVATION
. La priorità del filtro per intent deve essere impostato su un valore diverso da zero nel caso in cui le implementazioni siano presenti sul dispositivo. Ad esempio:<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'app dell'operatore svolge il proprio lavoro utilizzando la propria UI. Ad esempio, logging presenti nell'utente o inviare richieste HTTP al backend dell'operatore.
A questo punto, l'app dell'operatore deve essere pronta per fornire un tramite la sua implementazione
ICarrierEuiccProvisioningService
. La l'app dell'operatore avvia l'LPA chiamandostartActivityForResult(Intent, int)
conandroid.telephony.euicc.action.START_EUICC_ACTIVATION
un'azione. L'LPA controlla anche l'extra booleanoandroid.telephony.euicc.extra.USE_QR_SCANNER
. Se il valore ètrue
, il valore LPA avvia lo scanner QR per consentire all'utente di scansionare il codice QR del profilo.Sul lato LPA, l'LPA si collega alla rete
ICarrierEuiccProvisioningService
implementazione per recuperare l'attivazione codice e scarica il profilo corrispondente. L'LPA visualizza tutti i dati necessari Elementi UI durante il download, ad esempio una schermata di caricamento.Quando il flusso di attivazione LPA è completo, l'LPA risponde app dell'operatore con un codice risultato, che l'app dell'operatore gestisce
onActivityResult(int, int, Intent)
.- Se l'LPA riesce a scaricare il nuovo profilo eSIM,
risponde con
RESULT_OK
. - Se l'utente annulla l'attivazione del profilo eSIM nell'LPA,
risponde con
RESULT_CANCELED
. - Se l'LPA risponde con qualcosa di diverso da
RESULT_OK
oRESULT_CANCELED
, l'app dell'operatore considera questo messaggio come un errore.
Per motivi di sicurezza, l'LPA non accetta un codice di attivazione direttamente nell'intent specificato per garantire che i chiamanti non LPA non possano il codice di attivazione dall'app dell'operatore.
- Se l'LPA riesce a scaricare il nuovo profilo eSIM,
risponde con
Supporta più eSIM
Per i dispositivi con Android 10 o versioni successive,
La classe EuiccManager
supporta i dispositivi
con più eSIM. Dispositivi con una sola eSIM in fase di upgrade
Android 10
non richiedono modifiche all'implementazione LPA come piattaforma
associa automaticamente l'istanza EuiccManager
alla eUICC predefinita. La
eUICC predefinita è determinata dalla piattaforma per i dispositivi con versione radio HAL
1.2 o successive e dall'LPA per i dispositivi con versioni radio HAL inferiori a
1.2.
Requisiti
Per supportare più eSIM, il dispositivo deve avere più di una eUICC, che può essere essere una eUICC integrata o uno slot per SIM fisica in cui è possibile inserire le eUICC rimovibili inserito.
Per supportare più eSIM, è necessaria la versione 1.2 o versioni successive dell'HAL per la radio. Radio HAL si consiglia la versione 1.4 e la versione 1.2 di RadioConfig HAL.
Implementazione
Per supportare più eSIM (incluse eUICC rimovibili o SIM programmabili),
L'LPA deve implementare
EuiccService
,
che riceve l'ID slot corrispondente all'ID carta fornito dal chiamante.
La
non_removable_euicc_slots
risorsa specificata in
arrays.xml
è un array di numeri interi che rappresentano gli ID slot dell'infrastruttura integrata di un dispositivo
eUICC. Devi specificare questa risorsa per consentire alla piattaforma di determinare
se una eUICC inserita è rimovibile.
App operatore per dispositivo con più eSIM
Quando crei un'app dell'operatore per un dispositivo con più eSIM, utilizza
createForCardId
in EuiccManager
per creare un oggetto EuiccManager
bloccato a un
ID carta specificato. L'ID carta è un valore intero che identifica in modo univoco un UICC
o una eUICC sul dispositivo.
Per ottenere l'ID carta per l'eUICC predefinita del dispositivo, utilizza la
getCardIdForDefaultEuicc
in TelephonyManager
. Questo metodo restituisce
UNSUPPORTED_CARD_ID
se la versione HAL della radio è precedente alla 1.2 e restituisce
UNINITIALIZED_CARD_ID
se il dispositivo non ha letto l'eUICC.
Puoi anche ottenere gli ID carta da
getUiccCardsInfo
e getUiccSlotsInfo
(API di sistema) in TelephonyManager
e
getCardId
a SubscriptionInfo
.
Quando viene creata un'istanza di un oggetto EuiccManager
con un ID carta specifico,
vengono indirizzate alla eUICC con quell'ID carta. Se l'eUICC diventa
non raggiungibile (ad esempio, quando viene disattivato o rimosso) EuiccManager
no
funziona più a lungo.
Puoi usare i seguenti esempi di codice per creare un'app dell'operatore.
Esempio 1: attivare un abbonamento attivo e creare un'istanza di 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);
Esempio 2: eseguire l'iterazione nelle UICC e creare un'istanza di EuiccManager
per un
eUICC rimovibile
// 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);
}
Convalida
AOSP non viene fornito con un'implementazione LPA e non è previsto avere un LPA disponibile su tutte le build Android (non tutti gli smartphone supportano l'eSIM). Per Per questo motivo, non esistono scenari di test CTS end-to-end. Tuttavia, scenari di test di base sono disponibili in AOSP per garantire che le API eUICC esposte sono valide nelle build Android.
Devi assicurarti che le build superino i seguenti scenari di test CTS (per API): /platform/cts/tests/tests/telephony/current/src/android/telephony/euicc/cts.
Gli operatori che implementano un'app dell'operatore devono eseguire le normali operazioni interne garanzia di qualità per garantire che tutte le funzionalità implementate funzionino come previsto. Al come minimo, l'app dell'operatore deve essere in grado di elencare tutti i profili degli abbonamenti di proprietà dello stesso operatore, scarica e installa un profilo, attiva un servizio sul profilo, passare da un profilo all'altro ed eliminare i profili.
Per realizzare il tuo LPA, devi superare una fase molto più test. Rivolgiti al tuo fornitore di modem, al chip eUICC o al fornitore del sistema operativo eSIM. fornitori e operatori SM-DP+ per risolvere i problemi e garantire l'interoperabilità l'LPA nell'architettura RSP. Una buona quantità di test manuali è inevitabile. Per una migliore copertura dei test, devi seguire le Piano di test RSP SGP.23 GSMA.