Wdróż kartę eSIM

Wbudowana technologia karty SIM (eSIM lub eUICC) pozwala użytkownikom pobrać profil operatora i aktywować usługę operatora bez fizycznej karty SIM. To globalna specyfikacja opracowana przez GSMA, która umożliwia zdalnej obsługi administracyjnej karty SIM (RSP) dowolnego urządzenia mobilnego. Pierwsze kroki z Androidem 9, platforma Androida udostępnia standardowe interfejsy API dostęp do karty eSIM i zarządzanie profilami subskrypcji na karcie eSIM. Wspólnoty eUICC interfejsy API umożliwiają innym firmom tworzenie własnych aplikacji operatora i profilu lokalnego. na urządzeniach z Androidem obsługujących eSIM.

Jest to samodzielna aplikacja systemowa, którą należy uwzględnić Obraz kompilacji Androida. Zarządzanie profilami karty eSIM zwykle zajmuje się LPA, ponieważ jest ona pomostem między SM-DP+ (usługą zdalną, przygotowuje, przechowuje i dostarcza pakiety profili na urządzenia) oraz układ eUICC. Plik APK LPA może opcjonalnie zawierać komponent UI – LPA UI lub LUI, to centralne miejsce, w którym użytkownik może zarządzać wszystkimi osadzonymi subskrypcjami profili. Platforma Androida automatycznie wykrywa najlepsze aplikacje i łączy się z nimi i przekierowuje wszystkie operacje eUICC przez instancję LPA.

Uproszczona architektura zdalnego udostępniania kart SIM (RSP)

Rysunek 1. Uproszczona architektura RSP

Operatorzy sieci komórkowych chcący utworzyć aplikację operatora, powinni zapoznać się z interfejsów API EuiccManager, który umożliwia ogólne działania związane z zarządzaniem profilami, downloadSubscription(), switchToSubscription() i deleteSubscription().

Jeśli jesteś producentem urządzenia OEM i chcesz utworzyć własną aplikację systemową LPA, musisz przedłużać EuiccService dla platformy Androida do łączenia się z usługami LPA. Dodatkowo należy używać interfejsów API EuiccCardManager, które udostępniają funkcje ES10x oparte na GSMA RSP 2.0. Te funkcje służą do wydawania poleceń do układu eUICC, takich jak: prepareDownload(), loadBoundProfilePackage(), retrieveNotificationList() i resetMemory().

Interfejsy API w EuiccManager wymaga poprawnie wdrożonej aplikacji LPA i elementu wywołującego EuiccCardManager Interfejsy API muszą mieć format LPA. Jest to wymuszane przez platformę Androida.

Obsługują urządzenia z Androidem 10 lub nowszym urządzeń z wieloma kartami eSIM. Więcej informacji: Obsługa wielu kart eSIM.

Utwórz aplikację operatora

Interfejsy API eUICC w Androidzie 9 umożliwiają aby operatorzy sieci komórkowych tworzyli własne aplikacje do zarządzania bezpośrednio profilu firmy. Obejmuje to pobieranie i usuwanie profili subskrypcji należący do operatora, oraz przejście na profil należący do operatora.

EuiccManager

EuiccManager to główny punkt wejścia aplikacji do interakcji z LPA. Obejmuje to aplikacje operatora, które pobierają, usuwają i przełączają się na subskrypcji należących do operatora. Dotyczy to również aplikacji systemowej LUI, zapewnia centralną lokalizację/interfejs do zarządzania wszystkimi osadzonymi subskrypcjami; może być inną aplikacją niż ta, która udostępnia EuiccService.

Aby korzystać z publicznych interfejsów API, aplikacja operatora musi najpierw uzyskać instancję EuiccManager do Context#getSystemService:

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

Przed wykonaniem którejkolwiek czynności sprawdź, czy urządzenie jest obsługiwane. Operacje eSIM. EuiccManager#isEnabled() zwykle zwraca true, jeśli Zdefiniowano funkcję android.hardware.telephony.euicc, a pakiet LPA jest obecnie.

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

Aby uzyskać informacje o sprzęcie eUICC i wersji systemu operacyjnego eSIM:

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

Wiele interfejsów API, takich jak downloadSubscription() i switchToSubscription(), korzysta z PendingIntent wywołań zwrotnych, ponieważ ich wykonanie może potrwać od sekund lub nawet minut. Funkcja PendingIntent jest wysyłana z kodem wyniku w tagu EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_ miejsca, które zapewnia kody błędów zdefiniowane przez platformę, a także dowolny szczegółowy kod wyniku jest rozpowszechniany z LPA jako EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, dzięki czemu aplikacji operatora, aby śledzić ją na potrzeby logowania/debugowania. PendingIntent wywołanie zwrotne musi mieć wartość BroadcastReceiver.

Aby pobrać subskrypcję do pobrania (utworzoną za pomocą kod aktywacyjny lub kod 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);

Zdefiniuj uprawnienie i używaj go w AndroidManifest.xml:

    <permission android:protectionLevel="signature" android:name="com.your.company.lpa.permission.BROADCAST" />
    <uses-permission android:name="com.your.company.lpa.permission.BROADCAST"/>

Aby przejść na subskrypcję o podanym identyfikatorze:

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

Pełną listę interfejsów API EuiccManager i przykładów kodu znajdziesz w Interfejsy API eUICC.

Błędy możliwe do naprawienia

W niektórych przypadkach system nie może ukończyć operacji eSIM ale użytkownik może naprawić błąd. Na przykład: downloadSubscription może się nie powieść, jeśli metadane profilu wskazują, że kod potwierdzenia operatora jest wymagane. Lub switchToSubscription może się nie udać, jeśli aplikacja operatora ma operatora uprawnienia do profilu docelowego (czyli operator jest właścicielem profilu), ale nie ma uprawnień operatora w obecnie włączonym profilu, wymagana jest zgoda użytkownika.

W takich przypadkach wywołanie zwrotne rozmówcy jest wykonywane z EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR Wywołanie zwrotne Intent zawiera dodatkowe elementy, takie jak wewnętrzne, które są dostępne, gdy rozmówca przekazuje je do: EuiccManager#startResolutionActivity, można zażądać rozwiązania tego problemu za pośrednictwem LUI. Używanie kodu potwierdzenia dla EuiccManager#startResolutionActivity wyświetla ekran LUI, na którym użytkownik może wpisać kod potwierdzenia; po wpisaniu kodu pobieranie zostanie wznowione. To podejście zapewnia aplikacji operatora pełną kontrolę nad tym, kiedy wyświetla się interfejs, ale daje LPA/LUI – rozszerzalna metoda dodawania nowej metody obsługi rozwiązania problemów bez konieczności wprowadzania zmian w aplikacjach klienckich.

Android 9 definiuje te możliwe do rozwiązania błędy w EuiccService, który powinien obsługiwać LUI:

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

Uprawnienia operatora

Jeśli jesteś operatorem, który opracowuje własną aplikację operatora, która dzwoni pod numer EuiccManager aby pobrać profile na urządzenie, profil powinien zawierać informacje o operatorze reguł uprawnień odpowiadających aplikacji operatora w metadanych. To jest bo profile subskrypcji należące do różnych operatorów mogą współistnieć eUICC urządzenia, a każda aplikacja operatora powinna mieć dostęp tylko do należących do tego operatora. Na przykład przewoźnik A nie powinien mieć możliwości pobierać, włączać lub wyłączać profil należący do operatora B.

Aby mieć pewność, że profil jest dostępny tylko dla właściciela, Android używa mechanizmu do: przyznać specjalne uprawnienia aplikacji właściciela profilu (czyli aplikacji operatora). Platforma Android wczytuje certyfikaty zapisane w pliku reguł dostępu profilu (ARF) i przyznaje aplikacjom podpisanym tym certyfikatom uprawnienia do wykonywania połączeń do EuiccManager interfejsów API. Ogólny proces opisano poniżej:

  1. operator podpisuje pakiet APK aplikacji operatora; apksigner dołącza certyfikat klucza publicznego do pliku APK.
  2. Operator/SM-DP+ przygotowuje profil i jego metadane, które zawierają formularz ARF zawierające:

    1. Podpis (SHA-1 lub SHA-256) certyfikatu klucza publicznego aplikacji operatora (wymagane)
    2. Nazwa pakietu aplikacji operatora (zdecydowanie zalecana)
  3. Aplikacja operatora próbuje wykonać operację eUICC za pomocą interfejsu API EuiccManager.

  4. Platforma Androida weryfikuje hasz SHA-1 lub SHA-256 identyfikatora aplikacji wywołującej certyfikat jest zgodny z podpisem certyfikatu uzyskanego z ARF profilu docelowego. Jeśli nazwa pakietu aplikacji operatora jest uwzględniona w ARF, musi też odpowiadać nazwie pakietu aplikacji wywołującej.

  5. Po zweryfikowaniu podpisu i nazwy pakietu (jeśli jest włączona) uprawnienia operatora są przyznawane aplikacji wywołującej w profilu docelowym.

Metadane profilu mogą być dostępne poza samym profilem (dzięki czemu LPA może pobrać metadane profilu z SM-DP+, zanim profil zostanie lub z ISD-R, gdy profil jest wyłączony), powinien zawierać parametr te same reguły uprawnień operatora co w profilu.

Systemy eUICC OS i SM-DP+ muszą obsługiwać w profilu zastrzeżony tag BF76 metadanych. Treść tagu powinna być taka sama jak reguły uprawnień operatora co zwrócona za pomocą apletu reguły dostępu (ARA) zdefiniowanego w Uprawnienia operatora 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
    }
}

Więcej informacji o podpisywaniu aplikacji znajdziesz tutaj: Podpisywanie aplikacji. Szczegółowe informacje o uprawnieniach operatora znajdziesz w tych artykułach: Uprawnienia operatora UICC.

Tworzenie aplikacji asystującej profilu lokalnego

Producenci urządzeń mogą wdrożyć własny lokalny asystent profilu (LPA). które musi się wciągnąć dzięki interfejsom API Androida Euicc. W sekcjach poniżej znajdziesz krótkie omówienie tych zasad: tworząc aplikację LPA i integrując ją z systemem Android.

Wymagania dotyczące sprzętu/modemu

LPA i system operacyjny eSIM w układzie eUICC muszą obsługiwać co najmniej GSMA RSP (zdalną) obsługi administracyjnej karty SIM) v2.0 lub 2.2. Należy też rozważyć korzystanie z SM-DP+ i SM-DS z pasującą wersją RSP. Szczegółową architekturę RSP znajdziesz w artykule Specyfikacja architektury RSP GSMA SGP.21.

Dodatkowo integracja z interfejsami API eUICC na Androidzie 9, modem urządzenia powinien wysyłać informacje o funkcjach terminala z obsługą kodowanych funkcji eUICC (zarządzanie lokalnymi profilami pobieranie profilu). Musi też wdrożyć te metody:

  • IRadio HAL wer. 1.1: setSimPower
  • IRadio HAL w wersji 1.2: getIccCardStatus

  • IRadioConfig HAL w wersji 1.0: getSimSlotsStatus

  • IRadioConfig AIDL w wersji 1.0: getAllowedCarriers

    LPA Google musi znać stan blokady operatora, aby umożliwić pobieranie lub przenoszenie kart eSIM tylko w przypadku dozwolonego operatora. W przeciwnym razie użytkownik może pobrać i przenieść kartę SIM, a potem się zorientować, że urządzenie jest zablokowane w sieci operatora.

    • Dostawcy i producenci OEM muszą wdrożyć interfejs IRadioSim.getAllowedCarriers()HAL API.

    • Dostawca RIL / modem dostawcy powinni podać stan blokady i identyfikator operatora, na którym urządzenie jest zablokowane, w ramach interfejsu API IRadioSimResponse.getAllowedCarriersResponse()HAL.

Modem powinien rozpoznać kartę eSIM z domyślnym profilem rozruchowym włączonym jako ważnej karty SIM i zostaw włączoną kartę SIM.

W przypadku urządzeń z Androidem 10 nieusunięty identyfikator eUICC musi być zdefiniowana tablica identyfikatora boksu. Na przykład zobacz 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>

Pełną listę wymagań modemu znajdziesz w artykule Wymagania dotyczące modemu na potrzeby obsługi eSIM

Usługa EuiccService

LPA składa się z 2 osobnych komponentów (można je zaimplementować w tym samym APK): backend LPA oraz interfejs LPA lub LPA.

Aby wdrożyć backend LPA, musisz rozszerzyć EuiccService i zadeklaruj tę usługę w pliku manifestu. Usługa musi wymagać atrybutu android.permission.BIND_EUICC_SERVICE, aby zapewnić, że tylko który system może z nim powiązać. Usługa musi też zawierać filtr intencji z parametrem działanie android.service.euicc.EuiccService. Priorytet intencji ustaw na wartość inną niż zero, jeśli jest wiele implementacji. na urządzeniu. Na przykład:

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

Wewnętrznie platforma Androida określa aktywną LPA i wchodzi w interakcje z w razie potrzeby do obsługi interfejsów API eUICC na Androida. Zapytanie o usługę PackageManager wszystkie aplikacje z uprawnieniami android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS, Która określa usługę dla działania android.service.euicc.EuiccService. Wybrana jest usługa o najwyższym priorytecie. Jeśli nie zostanie znaleziona usługa, LPA obsługa jest wyłączona.

Aby wdrożyć LUI, musisz podać działanie obejmujące te działania:

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

Tak jak w przypadku usługi, każde działanie musi wymagać wywołania android.permission.BIND_EUICC_SERVICE uprawnienie systemowe. Każdy powinien mieć filtr intencji z odpowiednim działaniem, android.service.euicc.category.EUICC_UI o priorytecie innym niż zero. Podobna logika jest stosowana przy wyborze implementacji dla tych działań, wyboru implementacji EuiccService Na przykład:

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

Oznacza to, że interfejs implementujący te ekrany może pochodzić z różnych pakietu APK niż ten, który obsługuje EuiccService od tego, czy masz pojedynczy plik APK, czy wiele plików APK (np. taki, który implementuje EuiccService i usługa LUI) to wybór podczas projektowania.

Menedżer kart EuiccCard

EuiccCardManager to interfejs do komunikacji z układem eSIM. it udostępnia funkcje ES10 (opisane w specyfikacji RSP GSMA) i obsługuje niskopoziomowych poleceń żądania/odpowiedzi APDU oraz analizy ASN.1. EuiccCardManager to systemowy interfejs API i może być wywoływany tylko przez system z podwyższonymi uprawnieniami aplikacji.

Aplikacje operatora, interfejsy API LPA i Euicc

Rysunek 2. Aplikacje operatora i LPA używają interfejsów API Euicc

Interfejsy API do obsługi profilu w EuiccCardManager wymagają, aby element wywołujący był ustaw LPA. Jest to wymuszane przez platformę Androida. Oznacza to, że rozmówca musi rozszerzenia EuiccService i muszą zostać zadeklarowane w pliku manifestu, zgodnie z opisem w poprzednich sekcji.

Podobnie jak w przypadku EuiccManager, aby można było korzystać z interfejsów API EuiccCardManager, LPA musi najpierw uzyskaj wystąpienie EuiccCardManager przez Context#getSystemService:

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

Następnie, aby wyświetlić wszystkie profile w 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);

Wewnętrznie kod EuiccCardManager wiąże się z zasadą EuiccCardController (która jest uruchamiana w proces telefoniczny) za pomocą interfejsu AIDL, a każda metoda EuiccCardManager otrzymuje wywołanie zwrotne z procesu telefonicznego przez inny, dedykowany protokół AIDL za pomocą prostego interfejsu online. Przy korzystaniu z interfejsów API EuiccCardManager obiekt wywołujący (LPA) musi podać Executor. obiekt, za pomocą którego wywoływane jest wywołanie zwrotne. Ten obiekt Executor może działać w pojedynczym wątku lub w wybranej puli wątków.

Większość interfejsów API EuiccCardManager ma ten sam wzorzec użycia. Aby na przykład wczytać powiązany pakiet profilu z eUICC:

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

Aby przełączyć się na inny profil z podanym identyfikatorem ICCID:

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

Aby uzyskać domyślny adres SM-DP+ z układu eUICC:

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

Aby pobrać listę powiadomień o określonych zdarzeniach:

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

Aktywowanie profilu eSIM w aplikacji operatora

Na urządzeniach z Androidem 9 lub nowszym do aktywowania możesz użyć aplikacji operatora eSIM i pobierz profile. Aplikacja operatora może pobierać profile przez połączenia downloadSubscription bezpośrednio lub podając kod aktywacyjny do LPA.

Gdy aplikacja operatora pobiera profil, dzwoniąc downloadSubscription, wywołanie wymusza na aplikacji zarządzanie profilem za pomocą interfejsu BF76 tag metadanych koduje reguły uprawnień operatora profil. Jeśli profil nie zawiera tagu BF76 lub jego tag BF76 nie zgodne z podpisem aplikacji operatora, pobieranie zostanie odrzucone.

W sekcji poniżej dowiesz się, jak aktywować eSIM za pomocą aplikacji operatora za pomocą kod aktywacyjny.

Aktywuj kartę eSIM za pomocą kodu aktywacyjnego

Gdy do aktywowania profilu eSIM używasz kodu aktywacyjnego, LPA pobiera dane kod aktywacyjny od pobierz aplikację operatora i pobierz profil. Ten proces może zainicjować LPA. a reklama LPA może kontrolować cały interfejs, co oznacza, że żaden wyświetlane. Ta metoda pomija sprawdzanie tagu BF76, a operatorzy sieci nie muszą wdrożyć cały proces aktywacji eSIM, w tym pobrać Profil eSIM i obsługa błędów.

Definiowanie usługi obsługi administracyjnej eUICC operatora

Aplikacja LPA i aplikacja operatora komunikują się za pomocą AIDL, interfejsy: ICarrierEuiccProvisioningService i IGetActivationCodeCallback. Operator aplikacja musi implementować interfejs ICarrierEuiccProvisioningService oraz nie ujawniać go manifestuj deklarację. LPA musi powiązać z ICarrierEuiccProvisioningService i zaimplementować IGetActivationCodeCallback Więcej informacji na temat wdrażania lub udostępnienie interfejsu AIDL, patrz Definiowanie interfejsu AIDL.

Aby zdefiniować interfejsy AIDL, utwórz następujące pliki AIDL zarówno w przypadku reklam lokalnych, jak i aplikacji operatora.

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

Przykładowa implementacja reklam lokalnych

Aby powiązać z implementacją ICarrierEuiccProvisioningService aplikacji operatora: LPA musi kopiować zarówno ICarrierEuiccProvisioningService.aidl, jak i IGetActivationCodeCallback.aidl do projektu i zaimplementuj go ServiceConnection

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

Po powiązaniu z ICarrierEuiccProvisioningService w aplikacji operatora implementacji, LPA wywołuje getActivationCode lub getActivationCodeForEid, aby otrzymać kod aktywacyjny od aplikacji operatora do przebieg implementacji klasy atmosfery IGetActivationCodeCallback.

Różnica między getActivationCode a getActivationCodeForEid jest taka, getActivationCodeForEid umożliwia operatorowi wstępne powiązanie profilu z identyfikator EID przed rozpoczęciem procesu pobierania.

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

Przykładowa implementacja w przypadku aplikacji operatora

Aby umowa LPA została powiązana z aplikacją operatora, aplikacja operatora musi skopiować obie ICarrierEuiccProvisioningService.aidl i IGetActivationCodeCallback.aidl do w projekcie i zadeklaruj usługę ICarrierEuiccProvisioningService w AndroidManifest.xml. Usługa musi wymagać atrybutu android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS uprawnienie systemowe, aby zapewnić które może z nim powiązać tylko LPA, aplikacja z uprawnieniami dostępu do systemu. Usługa musi dołącz też filtr intencji z parametrem Działanie 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>
    

Aby wdrożyć usługę aplikacji operatora AIDL, utwórz usługę, rozszerz Stub i zaimplementuj getActivationCode oraz getActivationCodeForEid . LPA może następnie wywołać dowolną z tych metod, aby pobrać aktywację profilu. w kodzie. Aplikacja operatora powinna odpowiedzieć, dzwoniąc do niej IGetActivationCodeCallback#onSuccess podaj kod aktywacyjny, jeśli został został pobrany z serwera operatora. W przypadku niepowodzenia aplikacja operatora powinien przesłać odpowiedź 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);
              }
          }
    }
    

Uruchom interfejs aplikacji operatora w ramach procesu aktywacji reklam lokalnych

Na urządzeniach z Androidem 11 lub nowszym aplikacja LPA może uruchom interfejs aplikacji operatora. Jest to przydatne, ponieważ aplikacja operatora może wymagać dodatkowych informacji użytkownika przed podaniem kodu aktywacyjnego do LPA. Operatorzy mogą na przykład: wymagać od użytkowników zalogowania się w celu aktywacji numeru telefonu lub wykonania innego przenoszenia usług Google.

Procedura uruchamiania interfejsu aplikacji operatora w aplikacji operatora LPA:

  1. LPA uruchamia proces aktywacji aplikacji operatora, wysyłając Intencję android.service.euicc.action.START_CARRIER_ACTIVATION do pakietu aplikacji operatora, który zawiera działanie. (Odbiorca aplikacji operatora musi być chroniony w deklaracji w pliku manifestu za pomocą parametru android:permission="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS" do unikaj otrzymywania intencji z aplikacji niepochodzących z reklam spersonalizowanych).

    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. Aplikacja operatora używa własnego interfejsu użytkownika. Na przykład logowanie lub wysyłając żądania HTTP do backendu operatora.

  3. Aplikacja operatora odpowiada na LPA, wywołując setResult(int, Intent) i finish().

    1. Jeśli aplikacja operatora w odpowiedzi przesyła komunikat RESULT_OK, platforma LPA kontynuuje proces aktywacji. Jeśli aplikacja operatora ustali, że użytkownik powinien zeskanować kod QR, zamiast pozwolić LPA na powiązanie operatora usługi, aplikacja operatora odpowiada na LPA za pomocą setResult(int, Intent) z RESULT_OK i instancją Intent zawierające dodatkowe wartości logiczne Ustawiono wartość android.telephony.euicc.extra.USE_QR_SCANNER dla: true. Ustawa LPA zaznacz je i uruchamia skaner kodów QR zamiast wiązania implementacji ICarrierEuiccProvisioningService w aplikacji operatora.
    2. Jeśli aplikacja operatora ulegnie awarii lub odpowie, wysyłając wiadomość RESULT_CANCELED (to jest domyślny kod odpowiedzi), LPA anuluje eSIM. proces aktywacji.
    3. Jeśli aplikacja operatora zareaguje, podając coś innego niż RESULT_OK lub RESULT_CANCELED, LPA traktuje to jako błąd.

    Ze względów bezpieczeństwa LPA nie powinna bezpośrednio akceptować kod aktywacyjny podany w intencji wyniku, aby zapewnić, że kod inny niż LPA dzwoniący nie mogą otrzymać kodu aktywacyjnego z aplikacji operatora

Uruchom proces aktywacji LPA w aplikacji operatora

Począwszy od Androida 11 aplikacje operatorów mogą używać interfejsów API eUICC aby uruchomić LUI dla eSIM aktywacji. Ta metoda wyświetla interfejs aktywacji eSIM w aplikacji LPA do profilu eSIM. LPA wysyła komunikat, gdy profil eSIM aktywacja zostanie zakończona.

  1. LPA musi zadeklarować działanie obejmujące filtr intencji z parametrem Działanie android.service.euicc.action.START_EUICC_ACTIVATION. Priorytet filtra intencji należy ustawić na wartość inną niż 0, w przypadku gdy wielokrotne są obecne na urządzeniu. Na przykład:

    <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. Aplikacja operatora używa własnego interfejsu użytkownika. Na przykład logowanie lub wysyłając żądania HTTP do backendu operatora.

  3. Teraz aplikacja operatora musi być gotowa do aktywacji dzięki implementacji ICarrierEuiccProvisioningService. aplikacja operatora uruchamia LPA, wywołując startActivityForResult(Intent, int) z android.telephony.euicc.action.START_EUICC_ACTIVATION działania. LPA sprawdza też dodatkową wartość logiczną android.telephony.euicc.extra.USE_QR_SCANNER Jeśli wartość to true, LPA uruchamia skaner kodów QR, aby umożliwić użytkownikowi zeskanowanie kodu QR profilu.

  4. Po stronie LPA ta jednostka łączy się z Implementacja ICarrierEuiccProvisioningService do pobrania aktywacji kod i pobierz odpowiedni profil. W LPA widoczne są wszystkie elementów interfejsu podczas pobierania, takich jak ekran wczytywania.

  5. Po zakończeniu procesu aktywacji reklam lokalnych zespół LPA zareaguje aplikacji operatora z kodem wyniku obsługiwanego przez aplikację operatora onActivityResult(int, int, Intent)

    1. Jeśli LPA pobierze nowy profil eSIM, odpowiada, wpisując RESULT_OK.
    2. Jeśli użytkownik anuluje aktywację profilu eSIM w ramach LPA, odpowiada, wpisując RESULT_CANCELED.
    3. Jeśli LPA udziela odpowiedzi innej niż RESULT_OK lub RESULT_CANCELED, aplikacja operatora potraktuje to jako błąd.

    Ze względów bezpieczeństwa LPA nie akceptuje kodu aktywacyjnego bezpośrednio w danej intencji, aby uniemożliwić użytkownikom spoza LPA kod aktywacyjny z aplikacji operatora.

Obsługuj wiele kart eSIM

Na urządzeniach z Androidem 10 lub nowszym parametr EuiccManager zajęcia obsługuje urządzenia z kilkoma kartami eSIM. Urządzenia z pojedynczą kartą eSIM, które są uaktualniane do Android 10 nie wymagają wprowadzania żadnych zmian w implementacji LPA. automatycznie wiąże instancję EuiccManager z domyślną wartością eUICC. domyślna wersja eUICC jest określana przez platformę w przypadku urządzeń z radiem w wersji HAL wersji 1.2 lub nowszej oraz przez LPA w przypadku urządzeń z radiem w wersji HAL starszej niż 1.2.

Wymagania

Aby można było obsługiwać wiele kart eSIM, urządzenie musi mieć więcej niż 1 eUICC, która może może to być wbudowany gniazdo eUICC lub fizyczne gniazdo SIM, w którym można wyjmować karty eUICC. wstawione.

Do obsługi wielu kart eSIM wymagany jest radio HAL w wersji 1.2 lub nowszej. Radio HAL zalecane są wersje 1.4 i RadioConfig HAL w wersji 1.2.

Implementacja

Aby obsługiwać wiele kart eSIM (w tym wymienne karty eUICC lub programowalne karty SIM), LPA musi zaimplementować EuiccService, który otrzymuje identyfikator przedziału odpowiadający identyfikatorowi karty podanemu przez dzwoniącego.

non_removable_euicc_slots zasób określony w arrays.xml to tablica liczb całkowitych, które reprezentują identyfikatory przedziałów wbudowanego urządzenia eUICC. Musisz podać ten zasób, aby platforma mogła określić czy wstawionego eUICC można wyjąć.

Aplikacja operatora na urządzenie z wieloma kartami eSIM

Podczas tworzenia aplikacji operatora na urządzeniu z wieloma kartami eSIM użyj createForCardId w EuiccManager, aby utworzyć obiekt EuiccManager, który jest przypięty do podany identyfikator karty. Identyfikator karty to wartość całkowita, która jednoznacznie identyfikuje UICC. lub eUICC na urządzeniu.

Aby uzyskać identyfikator karty domyślnej eUICC na urządzeniu, użyj getCardIdForDefaultEuicc w metodzie TelephonyManager. Ta metoda zwraca UNSUPPORTED_CARD_ID jeśli wersja HAL radia jest niższa niż 1.2 i zwraca UNINITIALIZED_CARD_ID jeśli urządzenie nie odczytało eUICC.

Identyfikatory kart możesz też uzyskać w getUiccCardsInfo oraz getUiccSlotsInfo (systemowy interfejs API) w TelephonyManager oraz getCardId. w: SubscriptionInfo.

Po utworzeniu instancji obiektu EuiccManager z określonym identyfikatorem karty wszystkie są kierowane do eUICC z tym identyfikatorem karty. Jeśli eUICC zmieni się na nieosiągalny (np. gdy jest wyłączony lub usunięty) EuiccManager nie może trwać dłużej.

Aplikację operatora możesz utworzyć, korzystając z poniższych przykładów kodu.

Przykład 1. Uzyskanie aktywnej subskrypcji i utworzenie instancji 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);

Przykład 2: iteracja przez UICC i utworzenie instancji EuiccManager dla wymienna eUICC

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

Weryfikacja

AOSP nie obejmuje implementacji LPA i nie oczekujemy mieć LPA dostępną we wszystkich wersjach Androida (nie każdy telefon obsługuje eSIM); Dla: dlatego nie występują tu kompleksowe przypadki testowe. Podstawowe przypadki testowe są dostępne w AOSP, aby zapewnić ujawnione interfejsy API eUICC. są akceptowane w kompilacjach Androida.

Upewnij się, że kompilacje przeszły te testy CTS (dostępne publicznie API): /platform/cts/tests/tests/telephony/current/src/android/telephony/euicc/cts.

Operatorzy, którzy implementują aplikację operatora, powinni przejść przez proces standardowy zapewnianie jakości aby mieć pewność, że wszystkie wdrożone funkcje działają zgodnie z oczekiwaniami. Na aplikacja operatora powinna mieć możliwość wyświetlenia wszystkich profili subskrypcji. należące do tego samego operatora, pobierz i zainstaluj profil, aktywuj usługę w profilu, przełączać się między profilami i usuwać.

Jeśli tworzysz własną lokalną umowę o usługach cyfrowych, musisz przejść dużo bardziej rygorystycznych czynności. i testowania. Skontaktuj się z dostawcą modemu, układu eUICC lub dostawcy systemu operacyjnego eSIM. Dostawcy SM-DP+ oraz operatorzy, aby rozwiązać problemy i zapewnić interoperacyjność LPA w architekturze RSP. Duża ilość testów ręcznych nieuniknione. Aby uzyskać jak największy zasięg testu, postępuj zgodnie z Plan testów RSP GSMA SGP.23.