eSIM'i uygulama

Yerleşik SIM (eSIM veya eUICC) teknolojisi, mobil kullanıcıların fiziksel SIM kart olmadan operatör profili indirmesine ve operatör hizmetini etkinleştirmesine olanak tanır. Bu, GSMA tarafından desteklenen ve herhangi bir mobil cihazda uzaktan SIM sağlama (RSP) özelliğini etkinleştiren küresel bir spesifikasyondur. Android 9'dan itibaren Android çerçevesi, eSIM'e erişmek 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) geliştirmesine 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. LPA, SM-DP+ (profil paketlerini hazırlayan, depolayan ve cihazlara teslim eden uzaktan hizmet) ile eUICC çipi arasında köprü görevi görür. LPA APK'sı, son kullanıcının tüm yerleştirilmiş abonelik profillerini yönetebileceği merkezi bir yer sağlamak için isteğe bağlı olarak LPA kullanıcı arayüzü veya LUI olarak adlandırılan bir kullanıcı arayüzü bileşeni içerebilir. Android çerçevesi, mevcut en iyi LPA'yı otomatik olarak keşfedip bu LPA'ya bağlanır ve tüm eUICC işlemlerini bir LPA örneği üzerinden yönlendirir.

Basitleştirilmiş uzaktan SIM temel hazırlığı (RSP) mimarisi

1. şekil. Basitleştirilmiş RSP mimarisi

Operatör uygulaması oluşturmak isteyen mobil şebeke operatörleri, EuiccManager içindeki API'lere göz atmalıdır. Bu API'ler, downloadSubscription(), switchToSubscription() ve deleteSubscription() gibi üst düzey profil yönetimi işlemleri sağlar.

Kendi LPA sistem uygulamanızı oluşturmak isteyen bir cihaz OEM'siyseniz LPA hizmetlerinize bağlanmak için Android çerçevesini genişletmeniz EuiccService gerekir. Ayrıca, GSMA RSP v2.0'a dayalı ES10x işlevleri sağlayan EuiccCardManager bölümündeki API'leri kullanmanız gerekir. Bu işlevler, eUICC çipine komut göndermek için kullanılır. Örneğin, prepareDownload(), loadBoundProfilePackage(), retrieveNotificationList() ve resetMemory().

EuiccManager API'lerinin çalışması için düzgün şekilde uygulanmış bir LPA uygulaması gerekir ve EuiccCardManager API'lerinin arayanı bir LPA olmalıdır. Bu sınır, Android çerçevesi tarafından uygulanır.

Android 10 veya sonraki sürümlerin yüklü olduğu cihazlar, birden fazla eSIM'in bulunduğu cihazları destekleyebilir. Daha fazla bilgi için Birden fazla eSIM'i destekleme başlıklı makaleyi inceleyin.

Operatör uygulaması oluşturma

Android 9'daki eUICC API'leri, mobil şebeke 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ş yapılması da dahildir.

EuiccManager

EuiccManager, uygulamaların LPA ile etkileşim kurması için ana giriş noktasıdır. Buna, operatörün sahip olduğu abonelikleri indiren, silen ve bu aboneliklere geçen operatör uygulamaları dahildir. Bu, tüm yerleştirilmiş aboneliklerin yönetimi için merkezi bir konum/kullanıcı arayüzü sağlayan ve EuiccService'ı sağlayan uygulamadan ayrı bir uygulama olabilen LUI sistem uygulamasını da içerir.

Herkese açık API'leri kullanmak için operatör uygulamasının önce Context#getSystemService aracılığıyla EuiccManager örneğini alması gerekir:

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

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

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

eUICC donanımı ve eSIM işletim sistemi sürümü hakkında bilgi edinmek 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 bir sonuç koduyla birlikte gönderilir. Bu alan, çerçeve tarafından tanımlanan hata kodlarının yanı sıra LPA'dan EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE olarak yayılan rastgele bir ayrıntılı sonuç kodu sağlar. Böylece operatör uygulaması, günlük kaydı/hata ayıklama amacıyla izleme yapabilir. PendingIntent geri çağırma BroadcastReceiver olmalıdır.

Belirli bir indirilebilir aboneliği (etkinleştirme kodu veya QR koduyla oluşturulmuş) indirmek için:

// 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 içinde 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ğini kullanarak 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'leri başlıklı makaleyi inceleyin.

Çözülebilir hatalar

Sistemin eSIM işlemini tamamlayamadığı ancak kullanıcının hatayı çözebileceği bazı durumlar vardır. Örneğin, downloadSubscription profil meta verileri operatör onay kodu gerektiğini belirtiyorsa başarısız olabilir. Veya switchToSubscription, operatör uygulamasının hedef profil üzerinde operatör ayrıcalıkları varsa (yani profilin sahibi operatörse) ancak şu anda etkin olan profil üzerinde operatör ayrıcalıkları yoksa ve bu nedenle kullanıcı izni gerekiyorsa başarısız olabilir.

Bu tür durumlarda, arayanın geri araması EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR ile yapılır. Geri arama Intent, arayan kişi EuiccManager#startResolutionActivity'a ilettiğinde LUI üzerinden çözüm istenebilecek şekilde dahili ekstralar içerir. Örneğin, onay kodunu tekrar kullanmak EuiccManager#startResolutionActivity kullanıcının onay kodu girmesine olanak tanıyan bir LUI ekranını tetikler. Kod girildikten sonra indirme işlemi devam eder. 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'ya, istemci uygulamalarının değiştirilmesine gerek kalmadan gelecekte kullanıcı tarafından düzeltilebilen sorunların yeni işlenmesini eklemek için genişletilebilir bir yöntem sunar.

Android 9, LUI'nin işlemesi gereken bu çözülebilir hataları EuiccService içinde 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ı

Cihaza profil indirmek için EuiccManager işlevini çağıran kendi operatör uygulamanızı geliştiren bir operatörseniz profiliniz, meta verilerde operatör uygulamanıza karşılık gelen operatör ayrıcalığı kurallarını içermelidir. Bunun nedeni, farklı operatörlere ait abonelik profillerinin bir cihazın eUICC'sinde birlikte bulunabilmesi ve her operatör uygulamasına yalnızca o operatöre ait profillere erişim izni verilmesi gerektiğidir. Örneğin, A operatörü, B operatörüne ait bir profili indirememeli, etkinleştirememeli veya devre dışı bırakamamalıdır.

Android, bir profile yalnızca sahibi tarafından erişilebilmesini sağlamak için profil sahibinin uygulamasına (ör. operatör uygulaması) özel ayrıcalıklar veren bir mekanizma kullanır. Android platformu, profildeki erişim kuralı dosyasında (ARF) depolanan sertifikaları yükler ve bu sertifikalarla imzalanan uygulamalara EuiccManager API'lerine çağrı yapma izni verir. Genel süreç aşağıda açıklanmıştır:

  1. Operatör, operatör uygulaması APK'sını imzalar. apksigner aracı, herkese açık anahtar sertifikasını APK'ya ekler.
  2. Operatör/SM-DP+, aşağıdakileri içeren bir ARF'nin yer aldığı bir profil ve meta verilerini hazırlar:

    1. Operatör uygulamasının ortak anahtar sertifikasının imzası (SHA-1 veya SHA-256) (zorunlu)
    2. Operatör uygulamasının paket adı (şiddetle önerilir)
  3. Operatör uygulaması, EuiccManager API'si ile 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şip eşleşmediğini doğrular. Operatör uygulamasının paket adı ARF'ye dahil edilmişse arayan uygulamasının paket adıyla da eşleşmelidir.

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

Profil meta verileri, profilin kendisi dışında da kullanılabilir (böylece LPA, profil indirilmeden önce SM-DP+'dan veya profil devre dışı bırakıldığında ISD-R'den profil meta verilerini alabilir). Bu nedenle, profil meta verileri profildekiyle aynı operatör ayrıcalığı kurallarını içermelidir.

eUICC OS ve SM-DP+, profil meta verilerinde tescilli bir etiketi BF76 desteklemelidir. Etiket içeriği, UICC Kargo Şirketi Ayrıcalıkları'nda tanımlanan erişim kuralı uygulaması (ARA) tarafından döndürülen kargo şirketi ayrıcalığı 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 bilgi için Uygulamanızı imzalama başlıklı makaleyi inceleyin. Operatör ayrıcalıkları hakkında bilgi için UICC Operatör Ayrıcalıkları başlıklı makaleyi inceleyin.

Yerel profil asistanı uygulaması oluşturma

Cihaz üreticileri, Android Euicc API'lerine bağlanması gereken kendi yerel profil asistanlarını (LPA) uygulayabilir. Aşağıdaki bölümlerde, LPA uygulaması oluşturma ve Android sistemine entegre etme hakkında kısa bir genel bakış sunulmaktadır.

Donanım/modem gereksinimleri

eUICC çipindeki LPA ve eSIM işletim sistemi en az GSMA RSP (Uzaktan SIM Sağlama) 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ı planlamalısınız. Ayrıntılı RSP mimarisi için GSMA SGP.21 RSP Architecture Specification'a (GSMA SGP.21 RSP Mimari Spesifikasyonu) bakın.

Ayrıca, Android 9'daki eUICC API'leriyle entegrasyon için cihaz modeminin, eUICC özelliklerinin kodlanmış (yerel profil yönetimi ve profil indirme) desteğiyle birlikte terminal özelliklerini 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

    Google LPA, yalnızca izin verilen operatör için eSIM indirilmesine veya aktarılmasına izin verebilmek amacıyla operatör kilidi durumunu bilmelidir. Aksi takdirde kullanıcılar bir SIM'i indirip aktarabilir ve daha sonra cihazın farklı bir operatöre kilitli olduğunu fark edebilir.

    • Tedarikçiler veya OEM'ler, IRadioSim.getAllowedCarriers() HAL API'yi uygulamalıdır.

    • Satıcı RIL / Modem, IRadioSimResponse.getAllowedCarriersResponse() HAL API'sinin bir parçası olarak cihazın kilitli olduğu operatörün kilit durumunu ve carrierId'sini doldurmalıdır.

Modem, varsayılan başlatma profili etkinleştirilmiş eSIM'i geçerli bir SIM olarak tanımalı ve SIM gücünü açık tutmalıdır.

Android 10 çalıştıran cihazlarda çıkarılamayan bir eUICC yuvası kimliği dizisi tanımlanmalıdır. Örneğin, arrays.xml konusuna 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 eSIM Desteği için Modem Gereksinimleri başlıklı makaleyi inceleyin.

EuiccService

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

LPA arka ucunu uygulamak için EuiccService uzantısını kullanmanız ve bu hizmeti manifest dosyanızda bildirmeniz gerekir. Hizmetin, yalnızca sistemin bağlanabilmesini sağlamak için android.permission.BIND_EUICC_SERVICE sistem iznini istemesi gerekir. Hizmet, android.service.euicc.EuiccService işlemiyle bir intent filtresi de içermelidir. Cihazda birden fazla uygulama varsa amaç filtresinin önceliği sıfır olmayan 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ğinde bu LPA ile etkileşime girer. PackageManager, android.service.euicc.EuiccService işlemi için bir hizmet belirten android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS iznine sahip tüm uygulamalar için sorgulanır. En yüksek önceliğe sahip hizmet seçilir. Herhangi bir hizmet bulunamazsa LPA desteği devre dışı bırakılır.

LUI'yi uygulamak için aşağıdaki işlemlerle ilgili 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 etkinlik için android.permission.BIND_EUICC_SERVICE sistem izni gerekir. Her birinde uygun işlem, android.service.euicc.category.EUICC_UI kategorisi ve sıfır olmayan bir öncelik içeren bir amaç filtresi olmalıdır. Bu etkinlikler için uygulamaları seçerken EuiccService uygulaması seçilirken kullanılan mantıkla benzer bir 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'yi uygulayan APK'dan farklı bir APK'dan gelebileceği anlamına gelir. Tek bir APK mı yoksa birden fazla APK (örneğin, EuiccService uygulayan bir APK ve LUI etkinlikleri sağlayan bir APK) mı kullanılacağı bir tasarım tercihidir.

EuiccCardManager

EuiccCardManager, eSIM çipiyle iletişim kurmak için kullanılan arayüzdür. GSMA RSP spesifikasyonunda açıklandığı gibi ES10 işlevleri sağlar ve düşük seviyeli APDU isteği/yanıt komutlarının yanı sıra ASN.1 ayrıştırmasını da işler. EuiccCardManager bir sistem API'sidir ve yalnızca sistem ayrıcalıklı uygulamalar tarafından çağrılabilir.

Operatör uygulamaları, LPA ve Euicc API&#39;leri

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

EuiccCardManager aracılığıyla profil işlemi API'lerinin kullanılabilmesi için arayanın LPA olması gerekir. Bu sınır, Android çerçevesi tarafından uygulanır. Bu nedenle, arayanın önceki bölümlerde açıklandığı gibi EuiccService uzantısını kullanması ve manifest dosyanızda bildirilmesi gerekir.

EuiccManager'ya benzer şekilde, EuiccCardManager API'lerini kullanmak için LPA'nızın öncelikle Context#getSystemService aracılığıyla EuiccCardManager örneğini alması 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'ye (telefon işleminde çalışır) bağlanır ve her EuiccCardManager yöntemi, geri çağırmasını telefon işleminden farklı ve özel bir AIDL arayüzü aracılığıyla alır. EuiccCardManager API'leri kullanılırken geri aramanın çağrıldığı bir Executor nesnesi sağlanmalıdır. Bu Executor nesnesi, tek bir iş parçacığında veya seçtiğiniz bir iş parçacığı havuzunda çalışabilir.

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

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

Belirli bir ICCID'ye sahip 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);

Belirli bildirim etkinliklerinin bildirim 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ümlerin yüklü olduğu cihazlarda eSIM'i etkinleştirmek ve profilleri indirmek için operatör uygulamasını kullanabilirsiniz. Operatör uygulaması, profilleri doğrudan downloadSubscription çağrısı yaparak veya LPA'ya etkinleştirme kodu sağlayarak indirebilir.

Bir operatör uygulaması downloadSubscription çağrısı yaparak bir profil indirdiğinde, çağrı, uygulamanın profili BF76 meta veri etiketi aracılığıyla yönetebilmesini zorunlu kılar. Bu etiket, profil için operatör ayrıcalığı kurallarını kodlar. Bir profilde BF76 etiketi yoksa veya BF76 etiketi, arama yapan operatör uygulamasının imzasıyla eşleşmiyorsa indirme işlemi reddedilir.

Aşağıdaki bölümde, etkinleştirme kodu kullanarak operatör uygulaması üzerinden eSIM'in nasıl etkinleştirileceği açıklanmaktadır.

Etkinleştirme kodunu kullanarak eSIM'i etkinleştirme

eSIM profilini etkinleştirmek için etkinleştirme kodu kullanıldığında LPA, operatör uygulamasından etkinleştirme kodu alır ve profili indirir. Bu akış, LPA tarafından başlatılabilir ve LPA, kullanıcı arayüzü akışının tamamını kontrol edebilir. Bu nedenle, operatör uygulaması kullanıcı arayüzü gösterilmez. Bu yaklaşım, BF76 etiketi 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ı gerekmez.

Operatör eUICC sağlama hizmetini tanımlama

LPA ve operatör uygulaması, iki AIDL arayüzü üzerinden iletişim kurar: ICarrierEuiccProvisioningService ve IGetActivationCodeCallback. Operatör uygulaması, ICarrierEuiccProvisioningService arayüzünü uygulamalı ve manifest beyanında kullanıma sunmalıdır. LPA, ICarrierEuiccProvisioningService ile bağlanmalı ve IGetActivationCodeCallback'yi uygulamalıdır. AIDL arayüzünü uygulama ve kullanıma sunma hakkında daha fazla bilgi için AIDL arayüzü tanımlama başlıklı makaleyi inceleyin.

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 öğelerini projenize kopyalaması ve ServiceConnection öğesini uygulaması gerekir.

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

Operatör uygulamasının ICarrierEuiccProvisioningService uygulamasına bağlandıktan sonra LPA, IGetActivationCodeCallback saplama sınıfının uygulamasını ileterek operatör uygulamasından etkinleştirme kodunu almak için getActivationCode veya getActivationCodeForEid yöntemini çağırır.

getActivationCode ile getActivationCodeForEid arasındaki fark, getActivationCodeForEid'nin indirme işlemi başlamadan önce 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 operatör uygulamasına bağlanması için operatör uygulaması hem ICarrierEuiccProvisioningService.aidl hem de IGetActivationCodeCallback.aidl öğesini projenize kopyalamalı ve ICarrierEuiccProvisioningService hizmetini AndroidManifest.xml dosyasında bildirmelidir. Hizmetin, yalnızca LPA'nın (sistem ayrıcalıklı bir uygulama) bağlanabilmesini sağlamak için android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS sistem iznini gerektirmesi gerekir. Hizmet, android.service.euicc.action.BIND_CARRIER_PROVISIONING_SERVICE işlemiyle bir amaç filtresi de 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 operatör uygulaması hizmetini uygulamak için bir hizmet oluşturun, Stub sınıfını genişletin ve getActivationCode ile getActivationCodeForEid yöntemlerini uygulayın. LPA, profil etkinleştirme kodunu getirmek için bu yöntemlerden birini çağırabilir. Kod, operatörün sunucusundan başarıyla alındıysa operatör uygulaması, etkinleştirme koduyla IGetActivationCodeCallback#onSuccess işlevini çağırarak yanıt vermelidir. Başarısız olursa operatör uygulaması IGetActivationCodeCallback#onFailure ile yanıt vermelidir.

  • 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ümlerin yüklü olduğu cihazlarda LPA, operatör uygulamasının kullanıcı arayüzünü başlatabilir. Bu, operatör uygulaması, LPA'ya etkinleştirme kodu sağlamadan önce kullanıcıdan ek bilgi isteyebileceği için faydalı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 giriş yapmasını isteyebilir.

LPA'da operatör uygulaması kullanıcı arayüzünü başlatma süreci şu şekildedir:

  1. LPA, işlemi içeren operatör uygulaması paketine android.service.euicc.action.START_CARRIER_ACTIVATION intent'ini göndererek operatör uygulamasının etkinleştirme akışını başlatır. (Taşıyıcı uygulama alıcısı, LPA dışı uygulamalardan niyet alınmasını önlemek için manifest beyanında android:permission="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS" ile korunmalıdır.)

    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. Operatör uygulaması, kendi kullanıcı arayüzünü kullanarak çalışır. Örneğin, kullanıcının oturumunu açma veya operatörün arka ucuna HTTP istekleri gönderme.

  3. Operatör uygulaması, setResult(int, Intent) ve finish() numaralarını arayarak LPA'ya yanıt verir.

    1. Operatör uygulaması RESULT_OK ile yanıt verirse LPA, etkinleştirme akışına devam eder. Operatör uygulaması, kullanıcının LPA'nın operatör uygulamasının hizmetini bağlamasına izin vermek yerine bir QR kodu taraması gerektiğine karar verirse operatör uygulaması, setResult(int, Intent) ile RESULT_OK ve true olarak ayarlanmış android.telephony.euicc.extra.USE_QR_SCANNER boole ekstrasını içeren bir Intent örneği kullanarak LPA'ya yanıt verir. LPA, ekstraları kontrol eder ve operatör uygulamasının ICarrierEuiccProvisioningService uygulamasını bağlamak yerine QR tarayıcıyı başlatır.
    2. Operatör uygulaması çökerse veya RESULT_CANCELED ile yanıt verirse (varsayılan yanıt kodu budur) 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 hata olarak değerlendirir.

    Güvenlik nedeniyle, LPA, sonuç amaçlı olarak sağlanan etkinleştirme kodunu doğrudan kabul etmemelidir. Böylece LPA olmayan arayanların operatör uygulamasından etkinleştirme kodu alması engellenir.

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

Android 11'den itibaren operatör uygulamaları, eSIM etkinleştirme için LUI başlatmak üzere 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ü gösterir. Ardından LPA, eSIM profilinin etkinleştirilmesi tamamlandığında bir yayın gönderir.

  1. LPA, android.service.euicc.action.START_EUICC_ACTIVATION işlemini içeren bir intent filtresiyle birlikte bir etkinlik bildirmelidir. Cihazda birden fazla uygulama varsa amaç filtresinin önceliği sıfır olmayan 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. Operatör uygulaması, kendi kullanıcı arayüzünü kullanarak çalışır. Örneğin, kullanıcının oturumunu açma veya operatörün arka ucuna HTTP istekleri gönderme.

  3. Bu noktada, operatör uygulaması ICarrierEuiccProvisioningService uygulaması aracılığıyla etkinleştirme kodu sağlamaya hazır olmalıdır. Operatör uygulaması, startActivityForResult(Intent, int) ile android.telephony.euicc.action.START_EUICC_ACTIVATION işlemini çağırarak LPA'yı başlatır. LPA, boole türündeki extra android.telephony.euicc.extra.USE_QR_SCANNER değerini de kontrol eder. Değer true ise LPA, kullanıcının profil QR kodunu taramasına olanak tanımak için QR tarayıcıyı başlatır.

  4. LPA tarafında, LPA, etkinleştirme kodunu getirmek 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österir.

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

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

    Güvenlik nedeniyle, LPA etkinleştirme kodunu, LPA dışındaki arayanların operatör uygulamasından etkinleştirme kodunu alamaması için doğrudan sağlanan amaçta kabul etmez.

Birden fazla eSIM'i destekleme

Android 10 veya sonraki sürümlerin yüklü olduğu cihazlarda EuiccManager sınıfı, birden fazla eSIM'in bulunduğu cihazları destekler. Android 10'a yükseltme yapan tek eSIM'li cihazlarda, platform EuiccManager örneğini varsayılan eUICC ile otomatik olarak ilişkilendirdiğinden LPA uygulamasında herhangi bir değişiklik yapılması gerekmez. Radyo HAL sürümü 1.2 veya daha yeni olan cihazlarda varsayılan eUICC, platform tarafından; radyo HAL sürümü 1.2'den eski olan cihazlarda ise LPA tarafından belirlenir.

Şartlar

Cihazın birden fazla eSIM'i desteklemesi için birden fazla eUICC'si olması gerekir. Bu eUICC'ler, yerleşik eUICC veya çıkarılabilir eUICC'lerin takılabileceği fiziksel SIM yuvası olabilir.

Birden fazla eSIM'i desteklemek için Radio HAL 1.2 veya sonraki bir sürüm gerekir. Radyo HAL'nin 1.4 sürümü ve RadioConfig HAL'nin 1.2 sürümü önerilir.

Uygulama

Birden fazla eSIM'i (çıkarılabilir eUICC'ler veya programlanabilir SIM'ler dahil) desteklemek için LPA, EuiccService'yi uygulamalıdır. Bu işlev, arayan tarafından sağlanan kart kimliğine karşılık gelen yuva kimliğini alır.

non_removable_euicc_slots içinde belirtilen arrays.xml kaynağı, bir cihazın yerleşik eUICC'lerinin yuva kimliklerini temsil eden bir tam sayı dizisidir. Platformun, takılan eUICC'nin çıkarılabilir olup olmadığını belirlemesine izin vermek için bu kaynağı belirtmeniz gerekir.

Birden fazla eSIM'i olan cihazlar için operatör uygulaması

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

Cihazın varsayılan eUICC'sinin kart kimliğini almak için TelephonyManager içindeki getCardIdForDefaultEuicc yöntemini kullanın. Bu yöntem, radyo HAL sürümü 1.2'den düşükse UNSUPPORTED_CARD_ID, cihaz eUICC'yi okumamışsa UNINITIALIZED_CARD_ID değerini döndürür.

Kart kimliklerini getUiccCardsInfo ve getUiccSlotsInfo (sistem API'si) TelephonyManager'den ve getCardId SubscriptionInfo'dan da alabilirsiniz.

Bir EuiccManager nesnesi belirli bir kart kimliğiyle oluşturulduğunda tüm işlemler bu kart kimliğine sahip eUICC'ye yönlendirilir. eUICC'ye ulaşılamazsa (örneğin, kapatıldığında veya çıkarıldığında) EuiccManager artık çalışmaz.

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

1. örnek: Etkin abonelik alma ve EuiccManager oluşturma

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

2. örnek: UICC'leri yineleyin ve çıkarılabilir bir eUICC için EuiccManager öğesini oluşturun.

// 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'de LPA uygulaması bulunmaz ve tüm Android derlemelerinde LPA'nın kullanılabilir olması beklenmez (her telefon eSIM'i desteklemez). Bu nedenle, uçtan uca CTS test durumları yoktur. Ancak, kullanıma açık eUICC API'lerinin Android derlemelerinde geçerli olmasını sağlamak için AOSP'de temel test senaryoları mevcuttur.

Derlemelerin aşağıdaki CTS testlerini (Herkese açık API'ler için) geçtiğinden emin olmanız gerekir: /platform/cts/tests/tests/telephony/current/src/android/telephony/euicc/cts.

Operatör uygulaması uygulayan operatörler, uygulanan tüm özelliklerin beklendiği gibi çalıştığından emin olmak için normal şirket içi kalite güvencesi döngülerinden geçmelidir. Operatör uygulaması, en azından aynı operatöre ait tüm abonelik profillerini listeleyebilmeli, bir profili indirip yükleyebilmeli, profilde bir hizmeti etkinleştirebilmeli, profiller arasında geçiş yapabilmeli ve profilleri silebilmelidir.

Kendi LPA'nızı oluşturuyorsanız çok daha titiz bir test sürecinden geçmeniz gerekir. Sorunları çözmek ve LPA'nizin RSP mimarisi içinde birlikte çalışabilirliğini sağlamak için modem tedarikçiniz, eUICC çip veya eSIM OS tedarikçiniz, SM-DP+ tedarikçileriniz ve operatörlerinizle birlikte çalışmanız gerekir. Manuel testlerin önemli bir kısmı kaçınılmazdır. En iyi test kapsamı için GSMA SGP.23 RSP Test Planı'nı uygulamanız gerekir.