eSIM'i uygulama

Gömülü SIM (eSIM veya eUICC) teknolojisi, mobil kullanıcıların bir operatör profili indirmesine ve fiziksel bir SIM kartı olmadan bir operatörün hizmetini etkinleştirmesine olanak tanır. Herhangi bir mobil cihazın uzaktan SIM provizyonunu (RSP) mümkün kılan, GSMA tarafından yönlendirilen global bir spesifikasyondur. Android 9'dan itibaren Android çerçevesi, eSIM'e erişim ve eSIM'deki abonelik profillerini yönetmek için standart API'ler sağlar. Bu eUICC API'leri, üçüncü tarafların eSIM özellikli Android cihazlarda kendi operatör uygulamalarını ve yerel profil yardımcılarını (LPA'lar) geliştirmelerine olanak tanır.

LPA, Android derleme görüntüsüne dahil edilmesi gereken bağımsız bir sistem uygulamasıdır. eSIM'deki profillerin yönetimi genellikle LPA tarafından yapılır; çünkü SM-DP+ (profil paketlerini hazırlayan, saklayan ve cihazlara dağıtan uzak hizmet) ile eUICC çipi arasında bir köprü görevi görür. LPA APK, son kullanıcıya tüm yerleşik abonelik profillerini yönetebilmesi için merkezi bir yer sağlamak üzere isteğe bağlı olarak LPA UI veya LUI adı verilen bir UI bileşeni içerebilir. Android çerçevesi, mevcut en iyi LPA'yı otomatik olarak keşfedip ona bağlanır ve tüm eUICC işlemlerini bir LPA örneği aracılığıyla yönlendirir.

Basitleştirilmiş Uzaktan SIM Hazırlama (RSP) mimarisi

Şekil 1. Basitleştirilmiş RSP mimarisi

Operatör uygulaması oluşturmakla ilgilenen mobil ağ operatörleri, downloadSubscription() , switchToSubscription() ve deleteSubscription() gibi üst düzey profil yönetimi işlemlerini sağlayan EuiccManager API'lere bakmalıdır.

Kendi LPA sistem uygulamanızı oluşturmakla ilgilenen bir cihaz OEM'iyseniz, LPA hizmetlerinize bağlanmak için EuiccService for Android çerçevesini genişletmeniz gerekir. Ayrıca, EuiccCardManager GSMA RSP v2.0'ı temel alan ES10x işlevlerini sağlayan API'leri kullanmalısınız. Bu işlevler, eUICC çipine, prepareDownload() , loadBoundProfilePackage() , retrieveNotificationList() ve resetMemory() gibi komutlar vermek için kullanılır.

EuiccManager API'lerin çalışması için düzgün şekilde uygulanmış bir LPA uygulaması gerekir ve EuiccCardManager API'lerini çağıran kişinin bir LPA olması gerekir. Bu, Android çerçevesi tarafından uygulanır.

Android 10 veya üstünü çalıştıran cihazlar, birden fazla eSIM'e sahip cihazları destekleyebilir. Daha fazla bilgi için bkz. Birden fazla eSIM'i destekleme .

Operatör uygulaması yapma

Android 9'daki eUICC API'leri, mobil ağ operatörlerinin profillerini doğrudan yönetmek için operatör markalı uygulamalar oluşturmasına olanak tanır. Buna, operatöre ait abonelik profillerinin indirilmesi ve silinmesinin yanı sıra, operatöre ait bir profile geçiş de dahildir.

Euicc Yöneticisi

EuiccManager , uygulamaların LPA ile etkileşime girmesi için ana giriş noktasıdır. Buna, operatörün sahip olduğu abonelikleri indiren, silen ve bu aboneliklere geçiş yapan operatör uygulamaları da dahildir. Bu aynı zamanda tüm yerleşik aboneliklerin yönetilmesi için merkezi bir konum/kullanıcı arayüzü sağlayan LUI sistem uygulamasını da içerir ve EuiccService sağlayan uygulamadan ayrı bir uygulama olabilir.

Genel API'leri kullanmak için, bir operatör uygulamasının öncelikle EuiccManager örneğini Context#getSystemService aracılığıyla edinmesi gerekir:

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

Herhangi bir eSIM işlemi yapmadan önce cihazda eSIM'in desteklenip desteklenmediğini kontrol etmelisiniz. EuiccManager#isEnabled() android.hardware.telephony.euicc özelliği tanımlanmışsa ve bir LPA paketi mevcutsa genellikle true döndürür.

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

eUICC donanımı ve eSIM İşletim Sistemi sürümü hakkında bilgi almak için:

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

downloadSubscription() ve switchToSubscription() gibi birçok API, tamamlanması saniyeler, hatta dakikalar sürebileceğinden PendingIntent geri çağırmalarını kullanır. PendingIntent EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_ alanında, çerçeve tanımlı hata kodlarının yanı sıra LPA'dan EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE olarak yayılan isteğe bağlı ayrıntılı bir sonuç kodu sağlayan bir sonuç koduyla birlikte gönderilir ve taşıyıcı uygulamanın günlük kaydı/hata ayıklama amacıyla izleme yapmasına olanak tanır. PendingIntent geri çağrısı BroadcastReceiver olmalıdır.

Belirli bir indirilebilir aboneliği indirmek için (bir etkinleştirme kodundan veya QR kodundan oluşturulan):

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

İzni AndroidManifest.xml dosyasında tanımlayın ve kullanın:

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

Abonelik kimliği verilen bir aboneliğe geçmek için:

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

EuiccManager API'lerinin ve kod örneklerinin tam listesi için eUICC API'lerine bakın.

Çözülebilir hatalar

Sistemin eSIM işlemini tamamlayamadığı ancak hatanın kullanıcı tarafından çözülebildiği bazı durumlar vardır. Örneğin, profil meta verileri operatör onay kodunun gerekli olduğunu belirtirse downloadSubscription başarısız olabilir. Veya operatör uygulamasının hedef profil üzerinde operatör ayrıcalıkları varsa (yani operatör profilin sahibiyse) ancak şu anda etkin olan profil üzerinde operatör ayrıcalıkları yoksa switchToSubscription başarısız olabilir ve bu nedenle kullanıcının onayı gerekir.

Bu durumlarda arayanın geri araması EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR ile çağrılır. Geri çağırma Intent arayan kişi onu EuiccManager#startResolutionActivity ilettiğinde, LUI aracılığıyla çözüm istenebilecek şekilde dahili ekstralar içerir. Örneğin onay kodunu tekrar kullanarak EuiccManager#startResolutionActivity , kullanıcının bir onay kodu girmesine olanak tanıyan bir LUI ekranını tetikler; Kod girildikten sonra indirme işlemine devam edilir. Bu yaklaşım, operatör uygulamasına kullanıcı arayüzünün ne zaman gösterileceği konusunda tam kontrol sağlar, ancak LPA/LUI'ye, istemci uygulamalarının değişmesine gerek kalmadan gelecekte kullanıcı tarafından kurtarılabilecek sorunların yeni bir şekilde ele alınması için genişletilebilir bir yöntem sağlar.

Android 9, LUI'nin işlemesi gereken EuiccService dosyasındaki bu çözülebilir hataları tanımlar:

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

Operatör ayrıcalıkları

Profilleri bir cihaza indirmek için EuiccManager çağıran kendi operatör uygulamanızı geliştiren bir operatörseniz, profilinizin meta verilerde operatör uygulamanıza karşılık gelen operatör ayrıcalık kurallarını içermesi gerekir. Bunun nedeni, farklı operatörlere ait abonelik profillerinin bir cihazın eUICC'sinde bir arada bulunabilmesi ve her operatör uygulamasının yalnızca o operatörün sahip olduğu profillere erişmesine izin verilmesi gerektiğidir. Örneğin, operatör A, operatör B'ye ait bir profili indirememeli, etkinleştirememeli veya devre dışı bırakamamalıdır.

Bir profile yalnızca sahibinin erişebildiğinden emin olmak için Android, profil sahibinin uygulamasına (yani operatör uygulamasına) özel ayrıcalıklar veren bir mekanizma kullanır. Android platformu, profilin erişim kuralı dosyasında (ARF) saklanan sertifikaları yükler ve bu sertifikalar tarafından imzalanan uygulamalara EuiccManager API'lerine çağrı yapma izni verir. Üst düzey süreç aşağıda açıklanmıştır:

  1. Operatör, taşıyıcı uygulaması APK'sını imzalar; apksigner aracı genel anahtar sertifikasını APK'ya ekler.
  2. Operatör/SM-DP+, aşağıdakileri içeren bir ARF içeren bir profil ve onun meta verilerini hazırlar:

    1. Operatör uygulamasının genel anahtar sertifikasının imzası (SHA-1 veya SHA-256) (gerekli)
    2. Operatör uygulamasının paket adı (kesinlikle tavsiye edilir)
  3. Carrier uygulaması, EuiccManager API'si aracılığıyla bir eUICC işlemi gerçekleştirmeye çalışır.

  4. Android platformu, arayan uygulamanın sertifikasının SHA-1 veya SHA-256 karmasının, hedef profilin ARF'sinden alınan sertifikanın imzasıyla eşleştiğini doğrular. Operatör uygulamasının paket adı ARF'ye dahilse arayan uygulamanın paket adıyla da eşleşmelidir.

  5. İmza ve paket adı (varsa) doğrulandıktan sonra, arayan uygulamaya hedef profil üzerinden operatör ayrıcalığı verilir.

Profil meta verileri profilin dışında da mevcut olabildiği için (böylece LPA, profil meta verilerini profil indirilmeden önce SM-DP+'dan veya profil devre dışı bırakıldığında ISD-R'den alabilir), aynı taşıyıcı ayrıcalık kurallarını içermelidir. profildeki gibi.

eUICC OS ve SM-DP+, profil meta verilerinde özel bir BF76 etiketini desteklemelidir. Etiket içeriği, UICC Taşıyıcı Ayrıcalıkları'nda tanımlanan erişim kuralı uygulaması (ARA) tarafından döndürülen taşıyıcı ayrıcalık kurallarıyla aynı olmalıdır:

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

Uygulama imzalama hakkında daha fazla ayrıntı için bkz. Uygulamanızı imzalama . Operatör ayrıcalıklarıyla ilgili ayrıntılar için bkz. UICC Operatör Ayrıcalıkları .

Yerel profil asistanı uygulaması yapma

Cihaz üreticileri, Android Euicc API'lerine bağlanması gereken kendi yerel profil yardımcılarını (LPA) uygulayabilirler. Aşağıdaki bölümlerde LPA uygulaması oluşturmaya ve onu Android sistemiyle entegre etmeye ilişkin kısa bir genel bakış verilmektedir.

Donanım/modem gereksinimleri

eUICC çipindeki LPA ve eSIM işletim sistemi en azından GSMA RSP (Uzak SIM Hazırlama) v2.0 veya v2.2'yi desteklemelidir. Ayrıca eşleşen bir RSP sürümüne sahip SM-DP+ ve SM-DS sunucularını kullanmayı da planlamanız gerekir. Ayrıntılı RSP mimarisi için bkz. GSMA SGP.21 RSP Mimari Spesifikasyonu .

Ek olarak, Android 9'daki eUICC API'leriyle entegre olmak için cihaz modeminin, kodlanmış eUICC yetenekleri desteğiyle (yerel profil yönetimi ve profil indirme) terminal yetenekleri göndermesi gerekir. Ayrıca aşağıdaki yöntemleri de uygulaması gerekir:

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

  • IRadioConfig HAL v1.0: getSimSlotsStatus

  • IRadioConfig AIDL v1.0: getAllowedCarriers

    Yalnızca izin verilen operatör için eSIM'in indirilmesine veya aktarılmasına izin verebilmesi için Google LPA'nın operatör kilit durumunu bilmesi gerekir. Aksi halde kullanıcılar SIM'i indirip aktarabilir ve daha sonra cihazın operatörünün farklı bir operatöre kilitlendiğini fark edebilir.

    • Satıcıların veya OEM'lerin IRadioSim.getAllowedCarriers()HAL API'sini uygulaması gerekir.

    • Satıcı RIL / Modem, IRadioSimResponse.getAllowedCarriersResponse()HAL API'sinin bir parçası olarak cihazın kilitlendiği taşıyıcının kilit durumunu ve taşıyıcı kimliğini dolduracaktır.

Modem, geçerli bir SIM olarak varsayılan önyükleme profili etkinleştirilmiş eSIM'i tanımalı ve SIM'i açık tutmalıdır.

Android 10 çalıştıran cihazlar için kaldırılamaz bir eUICC yuva kimliği dizisi tanımlanmalıdır. Örneğin arrays.xml bakın.

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

Modem gereksinimlerinin tam listesi için bkz. eSIM Desteği için Modem Gereksinimleri .

EuiccService

Bir LPA iki ayrı bileşenden oluşur (her ikisi de aynı APK'da uygulanabilir): LPA arka ucu ve LPA kullanıcı arayüzü veya LUI.

LPA arka ucunu uygulamak için EuiccService genişletmeniz ve bu hizmeti bildirim dosyanızda bildirmeniz gerekir. Hizmetin, yalnızca sistemin kendisine bağlanabilmesini sağlamak için android.permission.BIND_EUICC_SERVICE sistem iznini gerektirmesi gerekir. Hizmet ayrıca android.service.euicc.EuiccService eylemini içeren bir amaç filtresi içermelidir. Cihazda birden fazla uygulamanın mevcut olması durumunda amaç filtresinin önceliği sıfırdan farklı bir değere ayarlanmalıdır. Örneğin:

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

Android çerçevesi dahili olarak etkin LPA'yı belirler ve Android eUICC API'lerini desteklemek için gerektiği şekilde onunla etkileşime girer. PackageManager android.service.euicc.EuiccService eylemi için bir hizmeti belirten android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS iznine sahip tüm uygulamalar için sorgulanır. En yüksek önceliğe sahip hizmet seçilir. Hiçbir hizmet bulunamazsa LPA desteği devre dışı bırakılır.

LUI'yi uygulamak için aşağıdaki eylemlere yönelik bir etkinlik sağlamanız gerekir:

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

Hizmette olduğu gibi, her etkinliğin android.permission.BIND_EUICC_SERVICE sistem iznini gerektirmesi gerekir. Her birinin uygun eyleme, android.service.euicc.category.EUICC_UI kategorisine ve sıfırdan farklı bir önceliğe sahip bir amaç filtresi olması gerekir. Bu faaliyetlere yönelik uygulamaları seçmek için EuiccService uygulamasının seçilmesiyle benzer mantık kullanılır. Örneğin:

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

Bu, bu ekranları uygulayan kullanıcı arayüzünün, EuiccService uygulayan APK'dan farklı bir APK'dan gelebileceği anlamına gelir. Tek bir APK'ya mı yoksa birden fazla APK'ya mı (örneğin, EuiccService uygulayan ve LUI etkinlikleri sağlayan bir APK) sahip olmak bir tasarım tercihidir.

EuiccCardManager'ı

EuiccCardManager , eSIM çipiyle iletişim kurmaya yönelik arayüzdür. ES10 işlevlerini sağlar (GSMA RSP spesifikasyonunda açıklandığı gibi) ve ASN.1 ayrıştırmasının yanı sıra düşük seviyeli APDU istek/yanıt komutlarını da yönetir. EuiccCardManager bir sistem API'sidir ve yalnızca sistem ayrıcalıklı uygulamalar tarafından çağrılabilir.

Taşıyıcı uygulamaları, LPA ve Euicc API'leri

Şekil 2. Hem operatör uygulaması hem de LPA, Euicc API'lerini kullanıyor

EuiccCardManager aracılığıyla profil işlemi API'leri arayanın LPA olmasını gerektirir. Bu, Android çerçevesi tarafından uygulanır. Bu, önceki bölümlerde açıklandığı gibi arayanın EuiccService genişletmesi ve bildirim dosyanızda bildirilmesi gerektiği anlamına gelir.

EuiccManager benzer şekilde, EuiccCardManager API'lerini kullanmak için LPA'nızın öncelikle Context#getSystemService aracılığıyla EuiccCardManager örneğini edinmesi gerekir:

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

Ardından, eUICC'deki tüm profilleri almak için:

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

Dahili olarak EuiccCardManager , bir AIDL arayüzü aracılığıyla EuiccCardController (telefon işleminde çalışan) bağlanır ve her EuiccCardManager yöntemi, geri çağrısını farklı, özel bir AIDL arayüzü aracılığıyla telefon işleminden alır. EuiccCardManager API'lerini kullanırken arayan kişinin (LPA), geri aramanın çağrılacağı bir Executor nesnesi sağlaması gerekir. Bu Executor nesnesi, tek bir iş parçacığı üzerinde veya seçtiğiniz bir iş parçacığı havuzunda çalışabilir.

Çoğu EuiccCardManager API'si aynı kullanım düzenine sahiptir. Örneğin, bağlı bir profil paketini eUICC'ye yüklemek için:

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

Belirli bir ICCID ile farklı bir profile geçmek için:

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

eUICC çipinden varsayılan SM-DP+ adresini almak için:

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

Belirtilen bildirim olaylarına ilişkin bildirimlerin listesini almak için:

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

Operatör uygulaması aracılığıyla eSIM profilini etkinleştirme

Android 9 veya sonraki sürümleri çalıştıran cihazlarda eSIM'i etkinleştirmek ve profilleri indirmek için bir operatör uygulaması kullanabilirsiniz. Operatör uygulaması, doğrudan downloadSubscription arayarak veya LPA'ya bir etkinleştirme kodu sağlayarak profilleri indirebilir.

Bir operatör uygulaması downloadSubscription öğesini çağırarak bir profili indirdiğinde, çağrı, uygulamanın profil için operatör ayrıcalığı kurallarını kodlayan bir BF76 meta veri etiketi aracılığıyla profili yönetebilmesini zorunlu kılar. Bir profilde BF76 etiketi yoksa veya BF76 etiketi arayan operatörün uygulamasının imzasıyla eşleşmiyorsa indirme işlemi reddedilir.

Aşağıdaki bölümde, etkinleştirme kodu kullanılarak bir operatör uygulaması aracılığıyla eSIM'in etkinleştirilmesi açıklanmaktadır.

Etkinleştirme kodu kullanarak eSIM'i etkinleştirme

Bir eSIM profilini etkinleştirmek için etkinleştirme kodu kullanıldığında LPA, operatör uygulamasından bir etkinleştirme kodu alır ve profili indirir. Bu akış, LPA tarafından başlatılabilir ve LPA, tüm kullanıcı arayüzü akışını kontrol edebilir; bu, herhangi bir taşıyıcı uygulama kullanıcı arayüzünün gösterilmeyeceği anlamına gelir. Bu yaklaşım, BF76 etiket kontrolünü atlar ve ağ operatörlerinin, eSIM profili indirme ve hata işleme dahil olmak üzere eSIM etkinleştirme kullanıcı arayüzü akışının tamamını uygulamasına gerek kalmaz.

Operatör eUICC sağlama hizmetini tanımlama

LPA ve taşıyıcı uygulaması iki AIDL arabirimi aracılığıyla iletişim kurar: ICarrierEuiccProvisioningService ve IGetActivationCodeCallback . Taşıyıcı uygulaması bir ICarrierEuiccProvisioningService arayüzünü uygulamalı ve bunu bildirim bildiriminde göstermelidir. LPA, ICarrierEuiccProvisioningService bağlanmalı ve IGetActivationCodeCallback uygulamalıdır. Bir AIDL arayüzünün nasıl uygulanacağı ve kullanıma sunulacağı hakkında daha fazla bilgi için bkz . Tanımlama ve AIDL arayüzü .

AIDL arayüzlerini tanımlamak için hem LPA hem de operatör uygulamaları için aşağıdaki AIDL dosyalarını oluşturun.

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

Örnek LPA uygulaması

Operatör uygulamasının ICarrierEuiccProvisioningService uygulamasına bağlanmak için LPA'nın hem ICarrierEuiccProvisioningService.aidl hem de IGetActivationCodeCallback.aidl projenize kopyalaması ve ServiceConnection uygulamasını uygulaması gerekir.

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

Taşıyıcı uygulamanın ICarrierEuiccProvisioningService uygulamasına bağlandıktan sonra LPA, IGetActivationCodeCallback saplama sınıfının uygulanmasını geçerek taşıyıcı uygulamasından etkinleştirme kodunu almak için getActivationCode veya getActivationCodeForEid çağrılarını yapar.

getActivationCode ve getActivationCodeForEid arasındaki fark, getActivationCodeForEid indirme işlemi başlamadan önce bir operatörün bir profili cihazın EID'sine önceden bağlamasına izin vermesidir.

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

Operatör uygulaması için örnek uygulama

LPA'nın taşıyıcı uygulamaya bağlanması için, taşıyıcı uygulamanın hem ICarrierEuiccProvisioningService.aidl hem de IGetActivationCodeCallback.aidl projenize kopyalaması ve ICarrierEuiccProvisioningService hizmetini AndroidManifest.xml dosyasında bildirmesi gerekir. Hizmetin, yalnızca sistem ayrıcalıklı bir uygulama olan LPA'nın kendisine bağlanabilmesini sağlamak için android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS sistem iznini gerektirmesi gerekir. Hizmet ayrıca android.service.euicc.action.BIND_CARRIER_PROVISIONING_SERVICE eylemini içeren bir amaç filtresi içermelidir.

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

AIDL taşıyıcı uygulama hizmetini uygulamak için bir hizmet oluşturun, Stub sınıfını genişletin ve getActivationCode ile getActivationCodeForEid yöntemlerini uygulayın. LPA daha sonra profil etkinleştirme kodunu almak için iki yöntemden birini çağırabilir. Kod operatörün sunucusundan başarıyla alındıysa operatör uygulaması, etkinleştirme koduyla birlikte IGetActivationCodeCallback#onSuccess arayarak yanıt vermelidir. Başarısız olursa operatör uygulamasının IGetActivationCodeCallback#onFailure ile yanıt vermesi gerekir.

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

LPA etkinleştirme akışında operatör uygulaması kullanıcı arayüzünü başlatma

Android 11 ve sonraki sürümleri çalıştıran cihazlarda LPA, bir operatör uygulamasının kullanıcı arayüzünü başlatabilir. Bu, bir operatör uygulamasının LPA'ya bir etkinleştirme kodu sağlamadan önce kullanıcıdan ek bilgi gerektirebileceği için kullanışlıdır. Örneğin, operatörler kullanıcıların telefon numaralarını etkinleştirmek veya diğer taşıma hizmetlerini gerçekleştirmek için oturum açmalarını gerektirebilir.

Bu, LPA'da bir operatör uygulamasının kullanıcı arayüzünü başlatma işlemidir:

  1. LPA, eylemi içeren operatör uygulama paketine android.service.euicc.action.START_CARRIER_ACTIVATION amacını göndererek operatör uygulamasının etkinleştirme akışını başlatır. (LPA dışı uygulamalardan niyet almayı önlemek için, taşıyıcı uygulama alıcısının manifest beyanında android:permission="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS" ile korunması gerekir.)

    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. Taşıyıcı uygulaması işini kendi kullanıcı arayüzünü kullanarak yapar. Örneğin, kullanıcının oturum açması veya operatörün arka ucuna HTTP isteklerinin gönderilmesi.

  3. Operatör uygulaması LPA'ya setResult(int, Intent) ve finish() öğesini çağırarak yanıt verir.

    1. Operatör uygulaması RESULT_OK ile yanıt verirse LPA etkinleştirme akışına devam eder. Operatör uygulaması, LPA'nın operatör uygulamasının hizmetine bağlanmasına izin vermek yerine kullanıcının bir QR kodunu taraması gerektiğini belirlerse, operatör uygulaması LPA'ya RESULT_OK ile setResult(int, Intent) ve boolean ekstra android içeren bir Intent örneğini kullanarak yanıt verir android.telephony.euicc.extra.USE_QR_SCANNER true olarak ayarlandı. LPA daha sonra ekstrayı kontrol eder ve taşıyıcı uygulamasının ICarrierEuiccProvisioningService uygulamasını bağlamak yerine QR tarayıcıyı başlatır.
    2. Operatör uygulaması kilitlenirse veya RESULT_CANCELED ile yanıt verirse (bu, varsayılan yanıt kodudur), LPA, eSIM etkinleştirme akışını iptal eder.
    3. Operatör uygulaması RESULT_OK veya RESULT_CANCELED dışında bir yanıt verirse LPA bunu bir hata olarak değerlendirir.

    Güvenlik nedeniyle, LPA dışı arayanların operatör uygulamasından etkinleştirme kodu alamamasını sağlamak amacıyla LPA, sonuçta sağlanan etkinleştirme kodunu doğrudan kabul etmemelidir .

Bir operatör uygulamasında LPA etkinleştirme akışını başlatma

Android 11'den itibaren operatör uygulamaları, eSIM etkinleştirmesine yönelik bir LUI başlatmak için eUICC API'lerini kullanabilir. Bu yöntem, eSIM profilini etkinleştirmek için LPA'nın eSIM etkinleştirme akışı kullanıcı arayüzünü ortaya çıkarır. LPA, eSIM profili aktivasyonu tamamlandığında bir yayın gönderir.

  1. LPA, android.service.euicc.action.START_EUICC_ACTIVATION eylemiyle amaç filtresi içeren bir etkinlik bildirmelidir. Cihazda birden fazla uygulamanın mevcut olması durumunda amaç filtresinin önceliği sıfırdan farklı bir değere ayarlanmalıdır. Örneğin:

    <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. Taşıyıcı uygulaması işini kendi kullanıcı arayüzünü kullanarak yapar. Örneğin, kullanıcının oturum açması veya operatörün arka ucuna HTTP isteklerinin gönderilmesi.

  3. Bu noktada, operatör uygulamasının ICarrierEuiccProvisioningService uygulaması aracılığıyla bir etkinleştirme kodu sağlamaya hazır olması gerekir. Operatör uygulaması, android.telephony.euicc.action.START_EUICC_ACTIVATION eylemiyle startActivityForResult(Intent, int) çağırarak LPA'yı başlatır. LPA aynı zamanda ekstra android.telephony.euicc.extra.USE_QR_SCANNER boolean değerini de kontrol eder. Değer true LPA, kullanıcının profil QR kodunu taramasına izin vermek için QR tarayıcıyı başlatır.

  4. LPA tarafında LPA, etkinleştirme kodunu almak ve ilgili profili indirmek için operatör uygulamasının ICarrierEuiccProvisioningService uygulamasına bağlanır. LPA, indirme sırasında yükleme ekranı gibi gerekli tüm kullanıcı arayüzü öğelerini görüntüler.

  5. LPA etkinleştirme akışı tamamlandığında LPA, operatör uygulamasına, operatör uygulamasının onActivityResult(int, int, Intent) içinde işlediği bir sonuç koduyla yanıt verir.

    1. LPA yeni eSIM profilini indirmeyi başarırsa RESULT_OK ile yanıt verir.
    2. Kullanıcı LPA'da eSIM profili aktivasyonunu iptal ederse RESULT_CANCELED ile yanıt verir.
    3. LPA, RESULT_OK veya RESULT_CANCELED dışında bir yanıt verirse operatör uygulaması bunu bir hata olarak değerlendirir.

    Güvenlik nedenleriyle LPA, LPA olmayan arayanların operatör uygulamasından etkinleştirme kodunu alamamasını sağlamak için sağlanan amaç kapsamında bir etkinleştirme kodunu doğrudan kabul etmez .

Birden fazla eSIM'i destekleme

Android 10 veya üstünü çalıştıran cihazlar için EuiccManager sınıfı, birden fazla eSIM'e sahip cihazları destekler. Platform, EuiccManager örneğini varsayılan eUICC ile otomatik olarak ilişkilendirdiğinden, Android 10'a yükseltilen tek eSIM'li cihazlar, LPA uygulamasında herhangi bir değişiklik gerektirmez. Varsayılan eUICC, radyo HAL sürümü 1.2 veya daha yüksek olan cihazlar için platform tarafından ve radyo HAL sürümü 1.2'den düşük olan cihazlar için LPA tarafından belirlenir.

Gereksinimler

Birden fazla eSIM'i desteklemek için cihazın birden fazla eUICC'ye sahip olması gerekir; bu eUICC, yerleşik bir eUICC veya çıkarılabilir eUICC'lerin takılabildiği fiziksel bir SIM yuvası olabilir.

Birden fazla eSIM'i desteklemek için Radyo HAL sürüm 1.2 veya üzeri gereklidir. Radio HAL sürüm 1.4 ve RadioConfig HAL sürüm 1.2 önerilir.

Uygulama

Birden fazla eSIM'i (çıkarılabilir eUICC'ler veya programlanabilir SIM'ler dahil) desteklemek için LPA'nın, arayanın sağladığı kart kimliğine karşılık gelen yuva kimliğini alan EuiccService uygulamasını uygulaması gerekir.

arrays.xml dosyasında belirtilen non_removable_euicc_slots kaynağı, bir aygıtın yerleşik eUICC'lerinin yuva kimliklerini temsil eden bir tamsayı dizisidir. Platformun, eklenen eUICC'nin çıkarılabilir olup olmadığını belirlemesine izin vermek için bu kaynağı belirtmeniz gerekir.

Birden fazla eSIM'li cihaz için operatör uygulaması

Birden fazla eSIM'e sahip bir cihaz için operatör uygulaması oluştururken, belirli bir kart kimliğine sabitlenen bir EuiccManager nesnesi oluşturmak için EuiccManager createForCardId yöntemini kullanın. Kart kimliği, cihazdaki bir UICC'yi veya eUICC'yi benzersiz şekilde tanımlayan bir tamsayı değeridir.

Cihazın varsayılan eUICC'sine ilişkin kart kimliğini almak için TelephonyManager getCardIdForDefaultEuicc yöntemini kullanın. Bu yöntem, radyo HAL sürümü 1.2'den düşükse UNSUPPORTED_CARD_ID değerini döndürür ve aygıt eUICC'yi okumadıysa UNINITIALIZED_CARD_ID değerini döndürür.

Ayrıca kart kimliklerini TelephonyManager getUiccCardsInfo ve getUiccSlotsInfo (sistem API'si) ve SubscriptionInfo getCardId alabilirsiniz.

Bir EuiccManager nesnesi belirli bir kart kimliğiyle başlatıldığında, tüm işlemler bu kart kimliğiyle eUICC'ye yönlendirilir. eUICC'ye erişilemez hale gelirse (örneğin kapatıldığında veya kaldırıldığında) EuiccManager artık çalışmaz.

Operatör uygulaması oluşturmak için aşağıdaki kod örneklerini kullanabilirsiniz.

Örnek 1: Etkin aboneliği alın ve EuiccManager başlatın

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

Örnek 2: UICC'leri yineleyin ve çıkarılabilir bir eUICC için EuiccManager başlatın

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

Doğrulama

AOSP bir LPA uygulamasıyla birlikte gelmez ve tüm Android yapılarında bir LPA'nın bulunması beklenmez (her telefon eSIM'i desteklemez). Bu nedenle uçtan uca CTS test senaryoları bulunmamaktadır. Ancak, açığa çıkan eUICC API'lerinin Android sürümlerinde geçerli olduğundan emin olmak için AOSP'de temel test senaryoları mevcuttur.

Yapıların aşağıdaki CTS test senaryolarını (genel API'ler için) geçtiğinden emin olmalısınız: /platform/cts/tests/tests/telephony/current/src/android/telephony/euicc/cts .

Bir taşıyıcı uygulamasını uygulayan taşıyıcılar, uygulanan tüm özelliklerin beklendiği gibi çalıştığından emin olmak için normal şirket içi kalite güvence döngülerinden geçmelidir. Operatör uygulaması en azından aynı operatörün sahip olduğu tüm abonelik profillerini listeleyebilmeli, bir profil indirip yükleyebilmeli, profilde bir hizmeti etkinleştirebilmeli, profiller arasında geçiş yapabilmeli ve profilleri silebilmelidir.

Kendi LPA'nızı yapıyorsanız çok daha sıkı testlerden geçmelisiniz. Sorunları çözmek ve LPA'nızın RSP mimarisi içinde birlikte çalışabilirliğini sağlamak için modem satıcınız, eUICC yongası veya eSIM OS satıcınız, SM-DP+ sağlayıcılarınız ve operatörlerinizle birlikte çalışmalısınız. Yeterli miktarda manuel test kaçınılmazdır. En iyi test kapsamı için GSMA SGP.23 RSP Test Planını izlemelisiniz.