O Google tem o compromisso de promover a igualdade racial para as comunidades negras. Saiba como.

Implementando eSIM

A tecnologia SIM incorporada (eSIM ou eUICC) permite que os usuários móveis baixem um perfil de operadora e ativem o serviço de uma operadora sem ter um cartão SIM físico. É uma especificação global conduzida pela GSMA que permite o provisionamento remoto de SIM (RSP) de qualquer dispositivo móvel. A partir do Android 9, a estrutura do Android fornece APIs padrão para acessar o eSIM e gerenciar perfis de assinatura no eSIM. Essas APIs eUICC permitir que terceiros para desenvolver seus próprios aplicativos transportadora e assistentes perfil locais (APLs) em dispositivos Android ESim habilitados.

O LPA é um aplicativo de sistema autônomo que deve ser incluído na imagem de construção do Android. A gestão dos perfis no eSIM é geralmente feita pelo LPA, uma vez que serve de ponte entre o SM-DP + (serviço remoto que prepara, armazena e entrega pacotes de perfis aos dispositivos) e o chip eUICC. O LPA APK pode incluir opcionalmente um componente de IU, chamado LPA IU ou LUI, para fornecer um local central para o usuário final gerenciar todos os perfis de assinatura incorporados. A estrutura do Android descobre e se conecta automaticamente ao melhor LPA disponível e roteia todas as operações eUICC por meio de uma instância de LPA.

Arquitetura de provisionamento remoto simplificado de SIM (RSP)

Arquitetura Figura 1. Simplificado RSP

Operadores de redes móveis interessado em criar um aplicativo transportador deve olhar para as APIs em EuiccManager , que fornece operações de gestão de perfil de alto nível, tais como downloadSubscription() , switchToSubscription() , e deleteSubscription() .

Se você é um dispositivo OEM interessado em criar seu próprio aplicativo sistema de LPA, você deve estender EuiccService para o quadro Android para se conectar aos seus serviços de LPA. Além disso, você deve usar as APIs em EuiccCardManager , que fornecem funções ES10x com base no GSMA RSP v2.0. Estas funções são usadas para emitir comandos para o chip eUICC, tais como prepareDownload() , loadBoundProfilePackage() , retrieveNotificationList() , e resetMemory() .

As APIs EuiccManager exigir um aplicativo LPA adequadamente implementado com a função e o chamador de EuiccCardManager APIs deve ser um LPA. Isso é imposto pela estrutura do Android.

Dispositivos com Android 10 ou superior podem suportar dispositivos com múltiplos eSIMs. Para mais informações, consulte Suportando múltiplos ESI .

Criação de um aplicativo de operadora

As APIs eUICC no Android 9 possibilitam que as operadoras de rede móvel criem aplicativos com a marca da operadora para gerenciar seus perfis diretamente. Isso inclui o download e a exclusão de perfis de assinatura de propriedade da operadora, bem como a mudança para um perfil de propriedade de uma operadora.

EuiccManager

EuiccManager é o principal ponto de entrada para aplicativos para interagir com o LPA. Isso inclui aplicativos da operadora que baixam, excluem e mudam para assinaturas pertencentes à operadora. Isto também inclui o aplicativo sistema de Lui, que fornece um local / UI central para gerenciar todas as assinaturas incorporadas, e pode ser um aplicativo separado daquele que fornece o EuiccService .

Para usar as APIs públicas, um aplicativo de suporte deve primeiro obter a instância do EuiccManager através Context#getSystemService :

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

Você deve verificar se o eSIM é compatível com o dispositivo antes de realizar qualquer operação de eSIM. EuiccManager#isEnabled() geralmente devolve true se o android.hardware.telephony.euicc característica é definida e um pacote de LPA está presente.

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

Para obter informações sobre o hardware eUICC e a versão do eSIM OS:

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

Muitas APIs, como downloadSubscription() e switchToSubscription() , o uso PendingIntent retornos de chamada, pois podem demorar alguns segundos ou mesmo minutos para ser concluído. PendingIntent é enviado com um código de resultado no EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_ espaço, que fornece códigos de erro definido pelo quadro, bem como um código de resultado detalhada arbitrária propagado a partir do LPA como EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE , permitindo a aplicação transportadora para rastrear para Registo / propósitos de depuração. O PendingIntent callback deve ser BroadcastReceiver .

Para baixar uma determinada subscrição para download (criado a partir de um código de ativação ou um 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 mudar para uma assinatura com o ID de assinatura:

// 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 obter uma lista completa de EuiccManager exemplos APIs e de código, consulte eUICC APIs .

Erros resolvíveis

Existem alguns casos em que o sistema não consegue concluir a operação eSIM, mas o erro pode ser resolvido pelo usuário. Por exemplo, downloadSubscription pode falhar se o perfil de metadados que indica um código de confirmação de suporte é necessária. Ou switchToSubscription pode falhar se o aplicativo transportadora tem privilégios transportadora sobre o perfil de destino (ou seja, portador possui o perfil), mas não tem privilégios transportadora sobre o perfil actualmente activado, e, portanto, é necessário o consentimento do usuário.

Para esses casos, retorno de chamada do chamador é chamado com EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR . O callback Intent contém extras internos de tal forma que quando o chamador passa para EuiccManager#startResolutionActivity , a resolução pode ser solicitado através do LUI. Usando o código de confirmação por exemplo, novamente, EuiccManager#startResolutionActivity desencadeia uma tela LUI que permite que o usuário insira um código de confirmação; depois que o código é inserido, a operação de download é retomada. Essa abordagem fornece ao aplicativo da operadora controle total sobre quando a IU é exibida, mas fornece ao LPA / LUI um método extensível para adicionar novo tratamento de problemas recuperáveis ​​pelo usuário no futuro, sem a necessidade de alterações nos aplicativos cliente.

Android 9 define esses erros resolvível em EuiccService , que o LUI deve lidar com:

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

Privilégios da operadora

Se você é um portador de desenvolver seu próprio aplicativo transportadora que chama EuiccManager aos perfis de download para um dispositivo, seu perfil deve incluir regras de privilégio transportadora que corresponde ao seu aplicativo transportadora nos metadados. Isso ocorre porque os perfis de assinatura pertencentes a diferentes operadoras podem coexistir no eUICC de um dispositivo, e cada aplicativo de operadora deve ter permissão para acessar apenas os perfis pertencentes a essa operadora. Por exemplo, a operadora A não deve ser capaz de baixar, habilitar ou desabilitar um perfil de propriedade da operadora B.

Para garantir que um perfil seja acessível apenas para seu proprietário, o Android usa um mecanismo para conceder privilégios especiais ao aplicativo do proprietário do perfil (ou seja, aplicativo da operadora). A plataforma cargas Android certificados armazenados no arquivo do perfil de regra de acesso (ARF) e concede permissão para aplicativos assinados por estes certificados para fazer chamadas para EuiccManager APIs. O processo de alto nível é descrito abaixo:

  1. O operador assina o APK do aplicativo da operadora; o apksigner ferramenta atribui o certificado de chave pública-a APK.
  2. O Operator / SM-DP + prepara um perfil e seus metadados, que incluem um ARF que contém:

    1. Assinatura (SHA-1 ou SHA-256) do certificado de chave pública do aplicativo da operadora (obrigatório)
    2. Nome do pacote do aplicativo da operadora (opcional)
  3. Portador tentativas de aplicativos para executar uma operação eUICC via EuiccManager API.

  4. A plataforma Android verifica se o hash SHA-1 ou SHA-256 do certificado do aplicativo do chamador corresponde à assinatura do certificado obtido do ARF do perfil de destino. Se o nome do pacote do aplicativo da operadora estiver incluído no ARF, ele também deve corresponder ao nome do pacote do aplicativo do chamador.

  5. Depois que a assinatura e o nome do pacote (se incluído) forem verificados, o privilégio de operadora é concedido ao aplicativo do chamador sobre o perfil de destino.

Como os metadados do perfil podem estar disponíveis fora do próprio perfil (para que o LPA possa recuperar os metadados do perfil do SM-DP + antes do download do perfil, ou do ISD-R quando o perfil está desativado), ele deve conter as mesmas regras de privilégio de operadora como no perfil.

O eUICC OS e SM-DP + deve apoiar uma tag proprietária BF76 nos metadados perfil. O conteúdo tag devem ser as mesmas regras de privilégio transportadora como retornado pelo applet regra de acesso (ARA) definido na Privilégios UICC Transportadora :

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 mais detalhes sobre assinatura de aplicativos, ver Assine seu aplicativo . Para mais detalhes sobre privilégios transportadora, consulte Privilégios UICC portador .

Criação de um aplicativo LPA

Você pode implementar seu próprio LPA, que deve ser conectado às APIs Euicc do Android. As seções a seguir fornecem uma breve visão geral de como fazer um aplicativo LPA e integrá-lo ao sistema Android.

Requisitos de hardware / modem

O LPA e o eSIM OS no chip eUICC devem suportar pelo menos GSMA RSP (Remote SIM Provisioning) v2.0 ou v2.2. Você também deve planejar o uso de servidores SM-DP + e SM-DS que tenham uma versão de RSP correspondente. Para arquitetura detalhada RSP, consulte GSMA SGP.21 RSP Architecture Specification .

Além disso, para se integrar com as APIs eUICC no Android 9, o modem do dispositivo deve enviar recursos de terminal com suporte para recursos eUICC codificados (gerenciamento de perfil local e download de perfil). Ele também precisa implementar os seguintes métodos:

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

  • IRadioConfig HAL v1.0: getSimSlotsStatus

O modem deve reconhecer o eSIM com o perfil de inicialização padrão habilitado como um SIM válido e manter o SIM ligado.

Para dispositivos que executam o Android 10, um array de ID de slot eUICC não removível deve ser definido. Por exemplo, veja 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 obter uma lista completa dos requisitos de modem, consulte Requisitos de modem de Apoio ESim .

EuiccService

Um LPA consiste em dois componentes separados (podem ser implementados no mesmo APK): o back-end do LPA e a IU do LPA ou LUI.

Para implementar o backend LPA, você deve estender EuiccService e declarar este serviço em seu arquivo de manifesto. O serviço deve requerer a android.permission.BIND_EUICC_SERVICE permissão sistema para garantir que apenas o sistema pode ligar a ele. O serviço também deve incluir um filtro de intenções com o android.service.euicc.EuiccService ação. A prioridade do filtro de intenção deve ser definida como um valor diferente de zero, caso várias implementações estejam presentes no dispositivo. Por exemplo:

<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, a estrutura do Android determina o LPA ativo e interage com ele conforme necessário para oferecer suporte às APIs eUICC do Android. PackageManager é consultado para todas as aplicações com o android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS permissão, que especifica um serviço para o android.service.euicc.EuiccService ação. O serviço com a prioridade mais alta é selecionado. Se nenhum serviço for encontrado, o suporte LPA é desabilitado.

Para implementar o LUI, você deve fornecer uma atividade para as seguintes ações:

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

Tal como acontece com o serviço, cada atividade deve exigir a android.permission.BIND_EUICC_SERVICE permissão sistema. Cada um deve ter um filtro de intenção com a ação apropriada, o android.service.euicc.category.EUICC_UI categoria, e uma prioridade diferente de zero. Lógica similar é usado para escolher as implementações para essas atividades como com escolher a implementação de EuiccService . Por exemplo:

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

Isto implica que a UI implementação destas telas pode vir de um APK diferente do que implementos EuiccService . Quer ter um único APK ou múltiplas APKs (por exemplo, uma que implementa EuiccService e que oferece atividades Lui) é uma escolha design.

EuiccCardManager

EuiccCardManager é a interface para a comunicação com o chip ESim. Ele fornece funções ES10 (conforme descrito na especificação GSMA RSP) e lida com os comandos de solicitação / resposta de APDU de baixo nível, bem como análise ASN.1. EuiccCardManager é uma API do sistema e pode ser chamado apenas por aplicativos privilegiada pelo sistema.

Aplicativos de operadora, LPA e APIs Euicc

Figura 2. Ambos app transportador e a utilização do LPA Euicc APIs

As APIs operação perfil através EuiccCardManager requerem o chamador ser um LPA. Isso é imposto pela estrutura do Android. Isto significa que o chamador deve estender EuiccService e ser declarado em seu arquivo de manifesto, como descrito nas seções anteriores.

Semelhante ao EuiccManager , para usar o EuiccCardManager APIs, o LPA deve primeiro obter a instância do EuiccCardManager através Context#getSystemService :

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

Então, para obter todos os perfis no 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 liga-se a EuiccCardController (que é executado no processo de telefone) através de uma interface AIDL, e cada EuiccCardManager método recebe o seu retorno a partir do processo de telefone através de uma interface AIDL diferente, dedicado. Quando se utiliza EuiccCardManager APIs, o chamador (LPA) deve fornecer um Executor objecto, através do qual a chamada de retorno é invocada. Este Executor objeto pode ser executado em um único segmento ou em um pool de threads de sua escolha.

A maioria dos EuiccCardManager APIs têm o mesmo padrão de uso. Por exemplo, para carregar um pacote de perfil vinculado no eUICC:

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

Para mudar para um perfil diferente com um determinado ICCID:

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

Para obter o endereço SM-DP + padrão do chip eUICC:

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

Para recuperar uma lista de notificações dos eventos de notificação fornecidos:

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

Ativando um perfil eSIM por meio de um aplicativo de operadora

Em dispositivos com Android 9 ou superior, você pode usar um aplicativo da operadora para ativar o eSIM e baixar perfis. O aplicativo transportadora pode baixar perfis chamando downloadSubscription diretamente ou fornecendo um código de ativação para o LPA.

Quando um aplicativo transportadora transfere um perfil chamando downloadSubscription , os Enforces chamada que o aplicativo pode gerenciar o perfil através de um BF76 tag de metadados que codifica as regras de privilégio transportadora para o perfil. Se um perfil não tem um BF76 tag ou se sua BF76 tag não corresponder a assinatura do aplicativo transportadora chamando, o download é rejeitada.

A seção abaixo descreve a ativação de um eSIM por meio de um aplicativo da operadora usando um código de ativação.

Ativando o eSIM usando um código de ativação

Ao usar um código de ativação para ativar um perfil eSIM, o LPA busca um código de ativação no aplicativo da operadora e baixa o perfil. Este fluxo pode ser iniciado pelo LPA e o LPA pode controlar todo o fluxo da IU, o que significa que nenhuma IU do aplicativo da operadora é mostrada. Esta abordagem ignora o BF76 verificação tag, e os operadores de rede não precisa implementar a toda ESim activação UI fluir incluindo download de um perfil ESim e tratamento de erros.

Definindo o serviço de provisionamento eUICC da operadora

O LPA e aplicativo transportadora comunicar através de dois AIDL interfaces: ICarrierEuiccProvisioningService e IGetActivationCodeCallback . O aplicativo transportador deve implementar um ICarrierEuiccProvisioningService interface e expô-la em sua declaração manifesto . O LPA deve ligar-se a ICarrierEuiccProvisioningService e implementar IGetActivationCodeCallback . Para mais informações sobre como implementar e expor uma interface AIDL, consulte interface de Definição e AIDL .

Para definir as interfaces AIDL, crie os seguintes arquivos AIDL para os aplicativos LPA e de operadora.

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

Exemplo de implementação de LPA

Para se ligam a do aplicativo transportadora ICarrierEuiccProvisioningService implementação, o LPA deve copiar tanto ICarrierEuiccProvisioningService.aidl e IGetActivationCodeCallback.aidl ao seu projeto e implementar ServiceConnection .

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

Após a ligação ao app transportadora ICarrierEuiccProvisioningService implementação, as chamadas LPA quer getActivationCode ou getActivationCodeForEid para obter o código de ativação do aplicativo transportadora passando a implementação do IGetActivationCodeCallback classe stub.

A diferença entre getActivationCode e getActivationCodeForEid é que getActivationCodeForEid permite que um veículo de pré-ligação para um perfil de EID do dispositivo antes de o processo de início da transferência.

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

Implementação de exemplo para aplicativo de operadora

Para o LPA para se ligar ao aplicativo de suporte, o aplicativo de suporte deve copiar tanto ICarrierEuiccProvisioningService.aidl e IGetActivationCodeCallback.aidl ao seu projeto e declarar a ICarrierEuiccProvisioningService serviço no AndroidManifest.xml arquivo. O serviço deve requerer a android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS permissão sistema para garantir que apenas o LPA, um aplicativo privilegiado ao sistema, pode ligar-se a ele. O serviço também deve incluir um filtro de intenções com o android.service.euicc.action.BIND_CARRIER_PROVISIONING_SERVICE ação.

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 o serviço aplicativo transportadora AIDL, criar um serviço, estender o Stub classe e implementar as getActivationCode e getActivationCodeForEid métodos. O LPA pode então chamar qualquer um dos métodos para buscar o código de ativação do perfil. O aplicativo transportador deve responder chamando IGetActivationCodeCallback#onSuccess com o código de ativação se o código foi obtido a partir do servidor da operadora com sucesso. Se não tiver êxito, o aplicativo transportadora deve responder com 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);
            }
      }
}

Iniciando a interface do usuário do aplicativo da operadora no fluxo de ativação LPA

Em dispositivos que executam o Android 11 e superior, o LPA pode iniciar a IU do aplicativo da operadora. Isso é útil porque um aplicativo de operadora pode exigir informações adicionais do usuário antes de fornecer um código de ativação ao LPA. Por exemplo, as operadoras podem exigir que os usuários façam login para ativar seus números de telefone ou executar outros serviços de portabilidade.

Este é o processo para iniciar a IU de um aplicativo de operadora no LPA:

  1. Os lançamentos LPA fluxo activação da aplicação transportador enviando o android.service.euicc.action.START_CARRIER_ACTIVATION intenção para o pacote da aplicação transportador contendo a acção. (O receptor de aplicação de suporte deve ser protegido na declaração manifesto com android:permission="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS" para evitar receber intenções de aplicações não pertencentes à 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. O aplicativo da operadora faz seu trabalho usando sua própria IU. Por exemplo, fazer o login do usuário ou enviar solicitações HTTP para o back-end da operadora.

  3. Os responde aplicativos de operadora para os LPA chamando setResult(int, Intent) e finish() .

    1. Se a aplicação transportador responde com RESULT_OK , o LPA continua o fluxo de activação. Se o aplicativo transportadora determina que o usuário deve ler um código QR em vez de deixar o LPA ligam serviço do aplicativo do transportador, as responde de aplicativos operadora para o LPA usando setResult(int, Intent) com RESULT_OK e um Intent instância que contém o extra de boolean android.telephony.euicc.extra.USE_QR_SCANNER definida como true . O LPA seguida, verifica o extras e lança o varredor de QR em vez de ligação do aplicativo transportadora ICarrierEuiccProvisioningService implementação.
    2. Se as falhas da aplicação transportador ou responde com RESULT_CANCELED (este é o código de resposta padrão), o LPA cancela o fluxo de activação ESim.
    3. Se o aplicativo transportadora responde com outra coisa que não RESULT_OK ou RESULT_CANCELED , os deleites LPA-lo como um erro.

    Por razões de segurança, o LPA não deve aceitar diretamente um código de ativação fornecido no resultado intenção de assegurar que os chamadores não-LPA não pode obter um código de ativação do aplicativo transportadora.

Lançando o fluxo de ativação LPA em um aplicativo de operadora

A partir do Android 11, os aplicativos de operadora podem usar APIs eUICC para iniciar uma LUI para ativação de eSIM. Este método mostra a IU do fluxo de ativação do eSIM do LPA para ativar o perfil do eSIM. O LPA então envia uma transmissão quando a ativação do perfil eSIM termina.

  1. O LPA deve declarar uma actividade, incluindo um filtro de intenção com o android.service.euicc.action.START_EUICC_ACTIVATION acção. A prioridade do filtro de intenção deve ser definida como um valor diferente de zero, caso várias implementações estejam presentes no dispositivo. Por exemplo:

    <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. O aplicativo da operadora faz seu trabalho usando sua própria IU. Por exemplo, fazer o login do usuário ou enviar solicitações HTTP para o back-end da operadora.

  3. Neste ponto, a aplicação de suporte deve estar pronto para fornecer um código de activação através da sua ICarrierEuiccProvisioningService implementação. A transportadora lançamentos de aplicativos do LPA chamando startActivityForResult(Intent, int) com o android.telephony.euicc.action.START_EUICC_ACTIVATION ação. O LPA também verifica a boolean adicional android.telephony.euicc.extra.USE_QR_SCANNER . Se o valor for true , os lançamentos de LPA O scanner QR para permitir que o usuário de digitalização do código QR perfil.

  4. No lado do LPA, as amarras do LPA para o transportador da aplicação ICarrierEuiccProvisioningService execução para obter o código de activação e baixar o perfil correspondente. O LPA exibe todos os elementos de IU necessários durante o download, como uma tela de carregamento.

  5. Quando o fluxo de activação de LPA está completa, o LPA responde à aplicação de suporte com um código de resultado, que as alças de aplicações transportador em onActivityResult(int, int, Intent) .

    1. Se o LPA consegue fazer o download do novo perfil ESim, ele responde com RESULT_OK .
    2. Se o utilizador cancela a activação perfil ESim no LPA, ele responde com RESULT_CANCELED .
    3. Se o LPA responde com outra coisa que não RESULT_OK ou RESULT_CANCELED , o aplicativo transportadora trata como um erro.

    Por razões de segurança, o LPA não aceita um código de ativação diretamente na fornecido intenção de assegurar que os chamadores não-LPA não pode obter o código de ativação do aplicativo transportadora.

Compatível com vários eSIMs

Para dispositivos que executam o Android 10 ou superior, os EuiccManager dispositivos suporta a classe com vários ESI. Dispositivos com um único ESim que são a atualização para Android 10 não requerem qualquer modificação à implementação LPA como a plataforma associa automaticamente o EuiccManager instância com o eUICC padrão. O eUICC padrão é determinado pela plataforma para dispositivos com rádio HAL versão 1.2 ou superior e pelo LPA para dispositivos com rádio HAL versões inferiores a 1.2.

Requisitos

Para suportar vários eSIMs, o dispositivo deve ter mais de um eUICC, que pode ser um eUICC embutido ou um slot SIM físico onde os eUICCs removíveis podem ser inseridos.

O rádio HAL versão 1.2 ou superior é necessário para oferecer suporte a vários eSIMs. Radio HAL versão 1.4 e RadioConfig HAL versão 1.2 são recomendados.

Implementação

Para suportar vários ESIMS (incluindo eUICCs removíveis ou SIMs programáveis), o LPA deve implementar EuiccService , que recebe a ranhura ID correspondente ao ID do cartão fornecido pelo chamador.

O non_removable_euicc_slots recurso especificado na arrays.xml é um array de inteiros que representam os IDs de slots de eUICCs built-in de um dispositivo. Você deve especificar este recurso para permitir que a plataforma determine se um eUICC inserido é removível ou não.

Aplicativo da operadora para dispositivo com vários eSIMs

Ao fazer um aplicativo transportadora para um dispositivo com vários ESI, utilize o createForCardId método em EuiccManager para criar um EuiccManager objeto que é preso a um determinado ID card. O ID do cartão é um valor inteiro que identifica exclusivamente um UICC ou eUICC no dispositivo.

Para obter o ID cartão para eUICC padrão do dispositivo, utilize o getCardIdForDefaultEuicc método em TelephonyManager . Este método retorna UNSUPPORTED_CARD_ID se a versão de rádio HAL é inferior a 1,2 e retorna UNINITIALIZED_CARD_ID se o dispositivo não leu o eUICC.

Você também pode obter IDs de cartões de getUiccCardsInfo e getUiccSlotsInfo (sistema API) em TelephonyManager e getCardId em SubscriptionInfo .

Quando um EuiccManager objeto foi instanciado com um ID cartão específico, todas as operações são direcionados para o eUICC com esse ID card. Se o eUICC se torna inacessível (por exemplo, quando ele está desligado ou removido) EuiccManager não funciona mais.

Você pode usar os seguintes exemplos de código para criar um aplicativo de operadora.

Exemplo 1: Obter assinatura activo e instanciar 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);

Exemplo 2: Itere através UICCs e instanciar EuiccManager para um eUICC removível

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

Validação

O AOSP não vem com uma implementação de LPA e não se espera que você tenha um LPA disponível em todas as compilações do Android (nem todo telefone suporta eSIM). Por esse motivo, não há casos de teste CTS ponta a ponta. No entanto, casos de teste básicos estão disponíveis no AOSP para garantir que as APIs eUICC expostas sejam válidas em compilações Android.

Você deve se certificar de que as compilações passar os seguintes casos de teste CTS (para APIs públicas): / Plataforma / cts / testes / exames / telefonia / current / src / android / telefonia / euicc / cts .

Operadoras que implementam um aplicativo de operadora devem passar por seus ciclos internos normais de garantia de qualidade para garantir que todos os recursos implementados estejam funcionando conforme o esperado. No mínimo, o aplicativo da operadora deve ser capaz de listar todos os perfis de assinatura pertencentes à mesma operadora, baixar e instalar um perfil, ativar um serviço no perfil, alternar entre perfis e excluir perfis.

Se você estiver fazendo seu próprio LPA, deverá passar por testes muito mais rigorosos. Você deve trabalhar com seu fornecedor de modem, chip eUICC ou fornecedor de sistema operacional eSIM, fornecedores de SM-DP + e operadoras para resolver problemas e garantir a interoperabilidade de seu LPA dentro da arquitetura RSP. Uma boa quantidade de testes manuais é inevitável. Para melhor cobertura de teste, você deve seguir o plano de teste SGP.23 RSP GSMA .