Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.

Implementando eSIM

La tecnología de SIM integrada (eSIM o eUICC) permite a los usuarios móviles descargar un perfil de operador y activar el servicio de un operador sin tener una tarjeta SIM física. Es una especificación global impulsada por GSMA que permite el aprovisionamiento remoto de SIM (RSP) de cualquier dispositivo móvil. A partir de Android 9, el marco de Android proporciona API estándar para acceder a eSIM y administrar perfiles de suscripción en eSIM. Estas API eUICC permiten a terceras partes para desarrollar sus propias aplicaciones de transporte y auxiliares perfil locales (APLs) en dispositivos Android compatibles con la Esim.

LPA es una aplicación de sistema independiente que debe incluirse en la imagen de compilación de Android. La gestión de los perfiles en la eSIM generalmente la realiza la LPA, ya que sirve como puente entre el SM-DP + (servicio remoto que prepara, almacena y entrega paquetes de perfiles a los dispositivos) y el chip eUICC. El APK de LPA puede incluir opcionalmente un componente de interfaz de usuario, llamado UI de LPA o LUI, para proporcionar un lugar central para que el usuario final administre todos los perfiles de suscripción integrados. El marco de Android descubre y se conecta automáticamente a la mejor LPA disponible y enruta todas las operaciones de eUICC a través de una instancia de LPA.

Arquitectura simplificada de aprovisionamiento remoto de SIM (RSP)

Arquitectura Figura 1. simplificado RSP

Operadores de redes móviles interesados en crear una aplicación de soporte deben mirar a las API en EuiccManager , que proporciona operaciones de gestión de perfil de alto nivel, tales como downloadSubscription() , switchToSubscription() , y deleteSubscription() .

Si usted es un dispositivo OEM interesado en crear su propio sistema de aplicación LPA, debe extender EuiccService para el marco de Android para conectarse a los servicios de LPA. Además, usted debe utilizar las API en EuiccCardManager , que proporcionan funciones ES10x basado en GSMA RSP v2.0. Estas funciones se utilizan para emitir comandos al chip eUICC, como prepareDownload() , loadBoundProfilePackage() , retrieveNotificationList() , y resetMemory() .

Las APIs en EuiccManager requieren una aplicación de LPA se aplica adecuadamente a la función y la persona que llama de EuiccCardManager API debe ser un LPA. Esto lo aplica el marco de Android.

Los dispositivos que ejecutan Android 10 o superior pueden admitir dispositivos con múltiples eSIM. Para obtener más información, consulte Utilización de varias IEN-EM .

Hacer una aplicación de operador

Las API de eUICC en Android 9 hacen posible que los operadores de redes móviles creen aplicaciones con la marca del operador para administrar sus perfiles directamente. Esto incluye descargar y eliminar perfiles de suscripción propiedad del operador, así como cambiar a un perfil propiedad de un operador.

EuiccManager

EuiccManager es el principal punto de entrada para aplicaciones para interactuar con el LPA. Esto incluye las aplicaciones del operador que descargan, eliminan y cambian a suscripciones propiedad del operador. Esto también incluye la aplicación del sistema LUI, que proporciona una ubicación / UI central para administrar todas las suscripciones embebidos, y puede ser una aplicación separada de la que proporciona la EuiccService .

Para utilizar las API públicas, una aplicación transportista debe obtener primero la instancia de EuiccManager través Context#getSystemService :

EuiccManager mgr = (EuiccManager) context.getSystemService(Context.EUICC_SERVICE);

Debe verificar si eSIM es compatible con el dispositivo antes de realizar cualquier operación de eSIM. EuiccManager#isEnabled() devuelve generalmente true si el android.hardware.telephony.euicc se define característica y un paquete de LPA está presente.

boolean isEnabled = mgr.isEnabled();
if (!isEnabled) {
    return;
}

Para obtener información sobre el hardware eUICC y la versión del sistema operativo eSIM:

EuiccInfo info = mgr.getEuiccInfo();
String osVer = info.getOsVersion();

Muchas API, como downloadSubscription() y switchToSubscription() , el uso PendingIntent devoluciones de llamada, ya que pueden tardar segundos o incluso minutos en completarse. PendingIntent se envía con un código de resultado en el EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_ espacio, que proporciona códigos de error del marco definido por el, así como un código de resultado detallada arbitraria propagado desde el LPA como EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE , permitiendo la aplicación de soporte para realizar un seguimiento para / propósitos de depuración de registro. El PendingIntent devolución de llamada debe ser BroadcastReceiver .

Para descargar una suscripción dada descargable (creado a partir de un código de activación o un código 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*/);
                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);
PendingIntent callbackIntent = PendingIntent.getBroadcast(
        getContext(), 0 /* requestCode */, intent,
        PendingIntent.FLAG_UPDATE_CURRENT);
mgr.downloadSubscription(sub, true /* switchAfterDownload */,
        callbackIntent);

Para cambiar a una suscripción con el ID de suscripción:

// 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);
PendingIntent callbackIntent = PendingIntent.getBroadcast(
        getContext(), 0 /* requestCode */, intent,
        PendingIntent.FLAG_UPDATE_CURRENT);
mgr.switchToSubscription(1 /* subscriptionId */, callbackIntent);

Para obtener una lista completa de EuiccManager ejemplos y APIs de código, ver eUICC API .

Errores solucionables

Hay algunos casos en los que el sistema no puede completar la operación de eSIM pero el usuario puede resolver el error. Por ejemplo, downloadSubscription puede fallar si los metadatos perfil indica que se requiere un código de confirmación portador. O switchToSubscription puede fallar si la aplicación portadora tiene privilegios de transporte sobre el perfil de destino (es decir, portadora dueño del perfil), pero no tiene privilegios de transporte sobre el perfil actualmente habilitado, y por lo tanto se requiere el consentimiento del usuario.

Para estos casos, devolución de llamada de la persona que llama se le llama con EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR . La devolución de llamada Intent contiene extras internos de forma que cuando la persona que llama lo pasa a EuiccManager#startResolutionActivity , la resolución puede ser solicitada a través de la LUI. Usando el código de confirmación, por ejemplo, de nuevo, EuiccManager#startResolutionActivity activa una pantalla LUI que permite al usuario ingresar un código de confirmación; una vez introducido el código, se reanuda la operación de descarga. Este enfoque proporciona a la aplicación del operador un control total sobre cuándo se muestra la interfaz de usuario, pero le da a LPA / LUI un método extensible para agregar un nuevo manejo de problemas recuperables por el usuario en el futuro sin necesidad de que cambien las aplicaciones cliente.

Android 9 define estos errores que se pueden resolver en EuiccService , que el LUI debe manejar:

/**
 * 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";

Privilegios de transportista

Si usted es un portador de desarrollar su propia aplicación que llama portadora EuiccManager a los perfiles de descarga en un dispositivo, su perfil debe incluir reglas de privilegios de transporte correspondientes a la aplicación de soporte en los metadatos. Esto se debe a que los perfiles de suscripción que pertenecen a diferentes operadores pueden coexistir en la eUICC de un dispositivo, y cada aplicación de operador solo debe poder acceder a los perfiles que pertenecen a ese operador. Por ejemplo, el operador A no debería poder descargar, habilitar o deshabilitar un perfil propiedad del operador B.

Para garantizar que un perfil solo sea accesible para su propietario, Android utiliza un mecanismo para otorgar privilegios especiales a la aplicación del propietario del perfil (es decir, la aplicación del operador). Los certificados de las cargas de la plataforma Android almacenados en el archivo del perfil de regla de acceso (ARF) y otorga permiso a las aplicaciones firmadas por estos certificados para realizar llamadas a EuiccManager API. El proceso de alto nivel se describe a continuación:

  1. El operador firma el APK de la aplicación del operador; la apksigner herramienta concede el certificado de clave pública para el APK.
  2. El operador / SM-DP + prepara un perfil y sus metadatos, que incluyen un ARF que contiene:

    1. Firma (SHA-1 o SHA-256) del certificado de clave pública de la aplicación del operador (obligatorio)
    2. Nombre del paquete de la aplicación del operador (opcional)
  3. Carrier intentos aplicación lleve a cabo una operación eUICC través EuiccManager API.

  4. La plataforma Android verifica que el hash SHA-1 o SHA-256 del certificado de la aplicación de la persona que llama coincida con la firma del certificado obtenido del ARF del perfil de destino. Si el nombre del paquete de la aplicación del operador está incluido en el ARF, también debe coincidir con el nombre del paquete de la aplicación de la persona que llama.

  5. Después de verificar la firma y el nombre del paquete (si se incluye), el privilegio de operador se otorga a la aplicación de la persona que llama sobre el perfil de destino.

Debido a que los metadatos del perfil pueden estar disponibles fuera del perfil en sí (para que LPA pueda recuperar los metadatos del perfil de SM-DP + antes de que se descargue el perfil, o de ISD-R cuando el perfil está deshabilitado), debe contener las mismas reglas de privilegios de operador. como en el perfil.

El eUICC OS y SM-DP + deben ser compatibles con una etiqueta de propiedad BF76 en los metadatos perfil. El contenido de la etiqueta debe ser las mismas reglas de privilegio portadora tal como son devueltas por el applet regla de acceso (ARA) definido en privilegios UICC Carrier :

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
    }
}

Para más detalles sobre la firma aplicación, consulte Firme su aplicación . Para información sobre los privilegios de transporte, consulte privilegios UICC Carrier .

Hacer una aplicación LPA

Puede implementar su propia LPA, que debe estar conectada con las API de Euicc de Android. Las siguientes secciones brindan una breve descripción general de cómo crear una aplicación LPA e integrarla con el sistema Android.

Requisitos de hardware / módem

El sistema operativo LPA y eSIM en el chip eUICC deben admitir al menos GSMA RSP (aprovisionamiento remoto de SIM) v2.0 o v2.2. También debe planificar el uso de servidores SM-DP + y SM-DS que tengan una versión RSP coincidente. Para la arquitectura detallada RSP, ver GSMA SGP.21 RSP Architecture Specification .

Además, para integrarse con las API eUICC en Android 9, el módem del dispositivo debe enviar capacidades de terminal con el soporte para capacidades eUICC codificadas (administración de perfiles locales y descarga de perfiles). También necesita implementar los siguientes métodos:

  • IRadio v1.1 HAL: setSimPower
  • IRadio v1.2 HAL: getIccCardStatus

  • IRadioConfig HAL v1.0: getSimSlotsStatus

El módem debe reconocer la eSIM con el perfil de inicio predeterminado habilitado como una SIM válida y mantener la SIM encendida.

Para los dispositivos que ejecutan Android 10, se debe definir una matriz de ID de ranura eUICC no extraíble. Por ejemplo, ver 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>

Para obtener una lista completa de los requisitos de módem, consulte Requisitos del módem para Esim apoyo .

EuiccService

Una LPA consta de dos componentes separados (ambos pueden implementarse en el mismo APK): el backend de LPA y la UI o LUI de LPA.

Para implementar el backend LPA, debe extender EuiccService y declarar este servicio en el archivo de manifiesto. El servicio debe exigir al android.permission.BIND_EUICC_SERVICE permiso del sistema para asegurar que sólo el sistema puede unirse a ella. El servicio deberá incluir también un filtro de intención con el android.service.euicc.EuiccService acción. La prioridad del filtro de intención debe establecerse en un valor distinto de cero en caso de que haya varias implementaciones presentes en el dispositivo. Por ejemplo:

<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, el marco de Android determina el LPA activo e interactúa con él según sea necesario para admitir las API eUICC de Android. PackageManager es consultado para todas las aplicaciones con el android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS permiso, que especifica un servicio para el android.service.euicc.EuiccService acción. Se selecciona el servicio con mayor prioridad. Si no se encuentra ningún servicio, la compatibilidad con LPA está deshabilitada.

Para implementar la LUI, debe proporcionar una actividad para las siguientes acciones:

  • android.service.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS
  • android.service.euicc.action.PROVISION_EMBEDDED_SUBSCRIPTION

Al igual que con el servicio, cada actividad debe exigir al android.permission.BIND_EUICC_SERVICE permiso del sistema. Cada uno debe tener un filtro intención con la acción apropiada, la android.service.euicc.category.EUICC_UI categoría, y una prioridad diferente de cero. Una lógica similar se utiliza para recoger las implementaciones de estas actividades como recoger con la implementación de EuiccService . Por ejemplo:

<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>

Esto implica que la interfaz de usuario de la aplicación de estas pantallas puede venir de un APK diferente a la que implementa EuiccService . Si tener una sola o múltiples APK APK (por ejemplo, uno que implementa EuiccService y uno que ofrece actividades LUI) es una opción de diseño.

EuiccCardManager

EuiccCardManager es la interfaz para la comunicación con el chip Esim. Proporciona funciones ES10 (como se describe en la especificación GSMA RSP) y maneja los comandos de solicitud / respuesta de APDU de bajo nivel, así como el análisis ASN.1. EuiccCardManager es una API del sistema y se puede llamar solamente por aplicaciones del sistema privilegiado.

Aplicaciones de operador, LPA y API de Euicc

Figura 2. Tanto aplicación portador y el uso LPA Euicc APIs

Las API de operación a través perfil EuiccCardManager requieren la persona que llama a ser un LPA. Esto es reforzado por el marco de Android. Esto significa que la persona que llama debe extenderse EuiccService y ser declarada en el archivo de manifiesto, como se describe en las secciones anteriores.

Al igual que en EuiccManager , para utilizar el EuiccCardManager API, el LPA deben obtener primero la instancia de EuiccCardManager través Context#getSystemService :

EuiccCardManager cardMgr = (EuiccCardManager) context.getSystemService(Context.EUICC_CARD_SERVICE);

Luego, para obtener todos los perfiles en la 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 se une a EuiccCardController (que se ejecuta en el proceso de teléfono) a través de una interfaz AIDL, y cada EuiccCardManager método recibe su devolución de llamada desde el proceso de teléfono a través de una interfaz de AIDL diferente, dedicado. Cuando se utiliza EuiccCardManager APIs, la persona que llama (LPA) debe proporcionar un Executor objeto a través del cual se invoca la devolución de llamada. Este Executor objeto puede funcionar con un solo hilo o en un grupo de subprocesos de su elección.

La mayoría de EuiccCardManager API tienen el mismo patrón de uso. Por ejemplo, para cargar un paquete de perfil enlazado en la eUICC:

...
cardMgr.loadBoundProfilePackage(eid, boundProfilePackage,
        AsyncTask.THREAD_POOL_EXECUTOR, callback);

Para cambiar a un perfil diferente con un ICCID determinado:

...
cardMgr.switchToProfile(eid, iccid, true /* refresh */,
        AsyncTask.THREAD_POOL_EXECUTOR, callback);

Para obtener la dirección SM-DP + predeterminada del chip eUICC:

...
cardMgr.requestDefaultSmdpAddress(eid, AsyncTask.THREAD_POOL_EXECUTOR,
        callback);

Para recuperar una lista de notificaciones de los eventos de notificación dados:

...
cardMgr.listNotifications(eid,
        EuiccNotification.Event.INSTALL
              | EuiccNotification.Event.DELETE /* events */,
        AsyncTask.THREAD_POOL_EXECUTOR, callback);

Activar un perfil eSIM a través de una aplicación de operador

En dispositivos con Android 9 o superior, puede usar una aplicación de operador para activar la eSIM y descargar perfiles. La aplicación de soporte puede descargar perfiles llamando downloadSubscription directamente o proporcionando un código de activación a la LPA.

Cuando una aplicación se descarga un perfil portador llamando downloadSubscription , las hace cumplir llamada que la aplicación se pueden administrar el perfil a través de un BF76 etiqueta de metadatos que codifica reglas de privilegio soporte para el perfil. Si un perfil no tiene un BF76 etiqueta o si su BF76 etiqueta no coincide con la firma de la aplicación portador de la llamada, se rechaza la descarga.

La siguiente sección describe la activación de una eSIM a través de una aplicación de operador utilizando un código de activación.

Activar eSIM usando un código de activación

Cuando se usa un código de activación para activar un perfil de eSIM, la LPA obtiene un código de activación de la aplicación del operador y descarga el perfil. La LPA puede iniciar este flujo y la LPA puede controlar todo el flujo de la IU, lo que significa que no se muestra la IU de la aplicación del operador. Este enfoque no pasa por el BF76 verificación de etiquetas, y los operadores de red no es necesario para poner en práctica la totalidad de Esim activación de la interfaz de usuario de flujo que incluye la descarga de un perfil Esim y tratamiento de errores.

Definición del servicio de aprovisionamiento eUICC del operador

El LPA y aplicación portador se comunican a través de dos AIDL interfaces: ICarrierEuiccProvisioningService y IGetActivationCodeCallback . La aplicación debe implementar un portador ICarrierEuiccProvisioningService interfaz y exponerlo en su declaración manifiesta . El LPA debe unirse a ICarrierEuiccProvisioningService e implementar IGetActivationCodeCallback . Para obtener más información acerca de cómo implementar y exponer una interfaz AIDL, consulte la interfaz Definición y AIDL .

Para definir las interfaces AIDL, cree los siguientes archivos AIDL para las aplicaciones LPA y del operador.

  • 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();
    }
    

Ejemplo de implementación de LPA

Para enlazar con la aplicación de soporte ICarrierEuiccProvisioningService implementación, el LPA debe copiar tanto ICarrierEuiccProvisioningService.aidl y IGetActivationCodeCallback.aidl a su proyecto y poner en práctica ServiceConnection .

@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
    mCarrierProvisioningService = ICarrierEuiccProvisioningService.Stub.asInterface(iBinder);
}

Después de unirse a la aplicación de soporte ICarrierEuiccProvisioningService aplicación, las llamadas LPA ya sea getActivationCode o getActivationCodeForEid para obtener el código de activación de la aplicación portador pasando la aplicación de la IGetActivationCodeCallback clase trozo.

La diferencia entre getActivationCode y getActivationCodeForEid es que getActivationCodeForEid permite un portador comprobar la validez de un perfil se unen a la identificación electrónica del dispositivo antes de que el proceso de descarga se inicia.

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
    }
}

Implementación de ejemplo para la aplicación del operador

Para el LPA se unen a la aplicación de soporte, la aplicación transportista debe copiar tanto ICarrierEuiccProvisioningService.aidl y IGetActivationCodeCallback.aidl a su proyecto y declarar la ICarrierEuiccProvisioningService servicio en el AndroidManifest.xml archivo. El servicio debe exigir al android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS permiso del sistema para asegurar que sólo la LPA, una aplicación de sistema de privilegio, puede unirse a ella. El servicio deberá incluir también un filtro de intención con el android.service.euicc.action.BIND_CARRIER_PROVISIONING_SERVICE acción.

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>

Para implementar el servicio portador de aplicación AIDL, crear un servicio, ampliar el Stub de clase y poner en práctica las getActivationCode y getActivationCodeForEid métodos. Luego, la LPA puede llamar a cualquiera de los métodos para obtener el código de activación del perfil. La aplicación portador debe responder llamando IGetActivationCodeCallback#onSuccess con el código de activación si el código se fue a buscar desde el servidor de la compañía con éxito. Si no tiene éxito, la aplicación de soporte debe responder 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);
            }
      }
}

Inicio de la interfaz de usuario de la aplicación del operador en el flujo de activación de LPA

En dispositivos con Android 11 y superior, LPA puede iniciar la interfaz de usuario de una aplicación de operador. Esto es útil ya que una aplicación de operador puede requerir información adicional del usuario antes de proporcionar un código de activación a la LPA. Por ejemplo, los operadores pueden requerir que los usuarios inicien sesión para activar sus números de teléfono o realizar otros servicios de transferencia.

Este es el proceso para iniciar la interfaz de usuario de una aplicación de operador en la LPA:

  1. Los lanzamientos de LPA flujo de activación de la aplicación portadora mediante el envío de la android.service.euicc.action.START_CARRIER_ACTIVATION intención de paquete app soporte que contiene la acción. (El receptor de aplicación portador debe ser protegida en la declaración de manifiesto con android:permission="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS" para evitar recibir intentos de aplicaciones no-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);
    
  2. La aplicación del operador hace su trabajo usando su propia interfaz de usuario. Por ejemplo, iniciar sesión con el usuario o enviar solicitudes HTTP al backend del operador.

  3. Las aplicaciones de soporte responde a la LPA llamando setResult(int, Intent) y finish() .

    1. Si la aplicación de soporte responde con RESULT_OK , el LPA continúa el flujo de activación. Si la aplicación de soporte determina que el usuario debe escanear un código QR en lugar de dejar que el LPA bind servicio de la aplicación de soporte, las responde app portador a la LPA usando setResult(int, Intent) con RESULT_OK y un Intent ejemplo que contiene el extra boolean android.telephony.euicc.extra.USE_QR_SCANNER establece en true . El LPA a continuación, busca el extra y lanza el escáner QR en lugar de la unión de la aplicación portadora ICarrierEuiccProvisioningService aplicación.
    2. Si la aplicación se bloquea portador o responde con RESULT_CANCELED (este es el código de respuesta predeterminado), el LPA cancela el flujo de la activación Esim.
    3. Si la aplicación de soporte responde con algo que no sea RESULT_OK o RESULT_CANCELED , los LPA lo trata como un error.

    Por razones de seguridad, el LPA no debe aceptar directamente un código de activación suministrado en el resultado de la intención de asegurar que las personas que llaman no-LPA no se puede obtener un código de activación de la aplicación portador.

Lanzamiento del flujo de activación de LPA en una aplicación de operador

A partir de Android 11, las aplicaciones del operador pueden usar las API de eUICC para iniciar una LUI para la activación de eSIM. Este método muestra la IU del flujo de activación de eSIM de LPA para activar el perfil de eSIM. Luego, la LPA envía una transmisión cuando finaliza la activación del perfil eSIM.

  1. El LPA debe declarar una actividad que incluye un filtro de intención con el android.service.euicc.action.START_EUICC_ACTIVATION acción. La prioridad del filtro de intención debe establecerse en un valor distinto de cero en caso de que haya varias implementaciones presentes en el dispositivo. Por ejemplo:

    <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>
    
  2. La aplicación del operador hace su trabajo usando su propia interfaz de usuario. Por ejemplo, iniciar sesión con el usuario o enviar solicitudes HTTP al backend del operador.

  3. En este punto, la aplicación de soporte debe estar preparado para suministrar un código de activación a través de su ICarrierEuiccProvisioningService aplicación. El portador lanza una aplicación del LPA llamando startActivityForResult(Intent, int) con el android.telephony.euicc.action.START_EUICC_ACTIVATION acción. El LPA también comprueba el booleano adicional android.telephony.euicc.extra.USE_QR_SCANNER . Si el valor es true , los lanzamientos de LPA escáner QR que permiten al usuario escaneo del código QR perfil.

  4. En el lado LPA, se une a LPA de la aplicación portadora ICarrierEuiccProvisioningService aplicación a buscar el código de activación y descarga el perfil correspondiente. La LPA muestra todos los elementos de la interfaz de usuario necesarios durante la descarga, como una pantalla de carga.

  5. Cuando el flujo de la activación de LPA es completa, el LPA responde a la aplicación de soporte con un código de resultado, que las asas de aplicaciones portador en onActivityResult(int, int, Intent) .

    1. Si el LPA tiene éxito en la descarga del nuevo perfil Esim, responde con RESULT_OK .
    2. Si el usuario cancela la activación perfil Esim en el LPA, responde con RESULT_CANCELED .
    3. Si el LPA responde con algo que no sea RESULT_OK o RESULT_CANCELED , la aplicación trata portadores esto como un error.

    Por razones de seguridad, el LPA no acepta un código de activación directamente en la suministra la intención de asegurar que las personas que llaman no-LPA no puede obtener el código de activación de la aplicación portador.

Soporta múltiples eSIM

Para los dispositivos con Android 10 o superior, los EuiccManager soportes de clase dispositivos con múltiples IEN-EM. Los dispositivos con un solo Esim que se actualiza a Android 10 no requieren ninguna modificación en la aplicación LPA como la plataforma asocia automáticamente la EuiccManager instancia con el eUICC defecto. El eUICC predeterminado está determinado por la plataforma para dispositivos con radio HAL versión 1.2 o superior y por la LPA para dispositivos con radio HAL versiones inferiores a 1.2.

Requisitos

Para admitir múltiples eSIM, el dispositivo debe tener más de una eUICC, que puede ser una eUICC incorporada o una ranura SIM física donde se pueden insertar eUICC extraíbles.

Se requiere la versión 1.2 o superior de Radio HAL para admitir múltiples eSIM. Se recomiendan Radio HAL versión 1.4 y RadioConfig HAL versión 1.2.

Implementación

Para soportar múltiples IEN-EM (incluyendo eUICCs extraíbles o SIMs programables), el LPA debe implementar EuiccService , que recibe la ID de ranura correspondiente a la ID de la tarjeta de llamadas-proporcionado.

El non_removable_euicc_slots recurso especificado en arrays.xml es una matriz de enteros que representan los identificadores de ranuras de eUICCs incorporado de un dispositivo. Debe especificar este recurso para permitir que la plataforma determine si una eUICC insertada es extraíble o no.

Aplicación de operador para dispositivos con múltiples eSIM

Al hacer una aplicación de soporte para un dispositivo con múltiples IEN-EM, utilice la createForCardId método en EuiccManager para crear un EuiccManager objeto que se fijó a una ID de tarjeta dada. La identificación de la tarjeta es un valor entero que identifica de forma única una UICC o una eUICC en el dispositivo.

Para obtener el identificador de la tarjeta de eUICC predeterminado del dispositivo, utilice el getCardIdForDefaultEuicc método en el TelephonyManager . Este método devuelve UNSUPPORTED_CARD_ID si la versión HAL de radio es inferior a 1,2 y vuelve UNINITIALIZED_CARD_ID si el dispositivo no ha leído el eUICC.

También puede obtener ID de tarjeta de getUiccCardsInfo y getUiccSlotsInfo (sistema API) en TelephonyManager y getCardId en SubscriptionInfo .

Cuando un EuiccManager objeto ha sido instanciado con un ID de tarjeta específica, todas las operaciones se dirigen a la eUICC con ese ID de tarjeta. Si el eUICC vuelve inalcanzable (por ejemplo, cuando se apaga o se retira) EuiccManager ya no funciona.

Puede utilizar los siguientes ejemplos de código para crear una aplicación de operador.

Ejemplo 1: Obtener suscripción activa y cree una instancia 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);

Ejemplo 2: iterar a través de UICC y instantiate EuiccManager para un eUICC extraíble

// 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);
}

Validación

AOSP no viene con una implementación de LPA y no se espera que tenga una LPA disponible en todas las compilaciones de Android (no todos los teléfonos admiten eSIM). Por esta razón, no existen casos de prueba CTS de un extremo a otro. Sin embargo, los casos de prueba básicos están disponibles en AOSP para garantizar que las API eUICC expuestas sean válidas en las compilaciones de Android.

Usted debe asegurarse de que las compilaciones pasar los siguientes casos de prueba CTS (por API públicas): plataforma / / cts / pruebas / exámenes / Telefonía / corriente / src / android / Telefonía / euicc / cts .

Los operadores que implementen una aplicación de operador deben pasar por sus ciclos de control de calidad internos normales para asegurarse de que todas las funciones implementadas funcionen como se espera. Como mínimo, la aplicación del operador debería poder enumerar todos los perfiles de suscripción que pertenecen al mismo operador, descargar e instalar un perfil, activar un servicio en el perfil, cambiar entre perfiles y eliminar perfiles.

Si está creando su propio LPA, debería pasar por pruebas mucho más rigurosas. Debe trabajar con su proveedor de módem, chip eUICC o proveedor de sistema operativo eSIM, proveedores de SM-DP + y operadores para resolver problemas y garantizar la interoperabilidad de su LPA dentro de la arquitectura RSP. Es inevitable una buena cantidad de pruebas manuales. Para una mejor cobertura de la prueba, se debe seguir el plan de pruebas SGP.23 RSP GSMA .