eSIM uygulayın

Yerleşik SIM (eSIM veya eUICC) teknolojisi, mobil kullanıcıların fiziksel SIM kartı olmadan operatör profili indirmesine ve operatörün hizmetini etkinleştirmesine olanak tanır. GSMA tarafından yönetilen ve herhangi bir mobil cihazda uzaktan SIM sağlama (RSP) özelliğini etkinleştiren küresel bir spesifikasyondur. Android 9 sürümünden itibaren Android çerçevesi, eSIM'de eSIM'e erişmek ve 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ştirmelerini sağlar.

LPA, Android derleme resmine dahil edilmesi gereken bağımsız bir sistem uygulamasıdır. SM-DP+ (profil paketlerini hazırlayan, depolayan ve cihazlara yayınlayan uzak hizmet) ile eUICC çipi arasında köprü görevi gördüğü için eSIM'deki profillerin yönetimi genellikle LPA tarafından yapılır. LPA APK'sı isteğe bağlı olarak, son kullanıcının tüm yerleşik abonelik profillerini tek bir yerden yönetebileceği bir LPA kullanıcı arayüzü veya LUI adlı kullanıcı arayüzü bileşeni içerebilir. Android çerçevesi, mevcut en iyi LPA'yı otomatik olarak bulup 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

Şekil 1. Basitleştirilmiş RSP mimarisi

Operatör uygulaması oluşturmak isteyen mobil ağ operatörleri, downloadSubscription(), switchToSubscription() ve deleteSubscription() gibi üst düzey profil yönetimi işlemleri sağlayan EuiccManager API'lerini incelemelidir.

Kendi LPA sistem uygulamanızı oluşturmak isteyen bir cihaz OEM'siyseniz Android çerçevesinin LPA hizmetlerinize bağlanması için EuiccService uzatmanız gerekir. Buna ek olarak, GSMA RSP v2.0'a dayalı ES10x işlevleri sağlayan EuiccCardManager içindeki API'leri kullanmanız gerekir. Bu işlevler eUICC çipine prepareDownload(), loadBoundProfilePackage(), retrieveNotificationList() ve resetMemory() gibi komutlar yayınlamak için kullanılır.

EuiccManager'teki API'lerin çalışması için doğru şekilde uygulanmış bir LPA uygulaması gerekir. EuiccCardManager API'leri çağıran kişinin de LPA olması gerekir. Bu, Android çerçevesi tarafından zorunlu kılınmıştır.

Android 10 veya sonraki sürümleri çalıştıran cihazlar, birden fazla eSIM'e sahip cihazları destekleyebilir. Daha fazla bilgi için Birden fazla eSIM desteği başlıklı makaleyi inceleyin.

Operatör uygulaması oluşturma

Android 9'daki eUICC API'leri, mobil ağ operatörlerinin profillerini doğrudan yönetmek için operatör markalı uygulamalar oluşturmasını sağlar. Buna, operatöre ait abonelik profillerini indirme ve silmenin yanı sıra bir operatöre ait profile geçiş de dahildir.

EuiccManager

EuiccManager, uygulamaların LPA ile etkileşime geçmesi için ana giriş noktasıdır. Operatörün sahibi olduğu abonelikleri indiren, silen ve bunlara geçen operatör uygulamaları da buna dahildir. Buna, tüm yerleşik aboneliklerin yönetimi için merkezi bir konum/kullanıcı arayüzü sağlayan ve EuiccService sağlayan uygulamadan ayrı bir uygulama olabilecek LUI sistem uygulaması da dahildir.

Herkese açık API'leri kullanmak için operatör uygulamalarının öncelikle Context#getSystemService üzerinden EuiccManager örneğini alması gerekir:

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

Herhangi bir eSIM işlemi gerçekleştirmeden önce cihazda eSIM'in desteklenip desteklenmediğini kontrol etmeniz gerekir. android.hardware.telephony.euicc özelliği tanımlanmışsa ve bir LPA paketi varsa EuiccManager#isEnabled() 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ği için PendingIntent geri çağırmalarını kullanır. PendingIntent, EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_ alanında bir sonuç koduyla gönderilir. Bu kod, çerçeve tanımlı hata kodlarının yanı sıra LPA'dan EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE olarak dağıtılan rastgele ayrıntılı bir sonuç kodu sağlar. Bu sayede operatör uygulaması, günlük kaydı/hata ayıklama amacıyla izleme yapabilir. PendingIntent callback'i BroadcastReceiver olmalıdır.

Belirli bir indirilebilir aboneliği (etkinleştirme kodu veya QR koduyla oluşturulan) 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'te tanımlayıp 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'leri bölümüne bakın.

Çözümü olan hatalar

Sistemin eSIM işlemini tamamlayamadığı bazı durumlar vardır, ancak bu hata kullanıcı tarafından çözülebilir. Örneğin, profil meta verileri operatör onay kodu gerektiğini gösteriyorsa downloadSubscription başarısız olabilir. Veya operatör uygulaması hedef profil üzerinde operatör ayrıcalıklarına sahipse (yani operatör profilin sahibiyse) ancak şu anda etkin olan profil üzerinde operatör ayrıcalıklarına sahip değilse ve bu nedenle kullanıcı izni gerekiyorsa switchToSubscription başarısız olabilir.

Bu tür durumlarda, arayanın geri çağırma işlevi EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR ile çağrılır. Geri aramaIntent, arayan kişi EuiccManager#startResolutionActivity'ye iletdiğinde LUI aracılığıyla çözümün istenebilmesi için dahili ekstralar içerir. Örneğin, onay kodunu tekrar kullanmak için EuiccManager#startResolutionActivity simgesine dokunduğunuzda kullanıcının onay kodu girmesine olanak tanıyan bir LUI ekranı tetiklenir. 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 üzerinde tam kontrol sağlar ancak LPA/LUI'ye, gelecekte istemci uygulamalarının değiştirilmesine gerek kalmadan kullanıcı tarafından kurtarılabilir yeni sorunların ele alınması için genişletilebilir bir yöntem sunar.

Android 9, LUI'nin ele alması gereken EuiccService içinde çö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ı

Bir cihaza profil indirmek için EuiccManager çağrısı yapan kendi operatör uygulamanızı geliştiren bir operatörseniz profilinizde, meta verilerde operatör uygulamanıza karşılık gelen operatör ayrıcalığı kuralları yer almalıdır. Bunun nedeni, farklı operatörlere ait abonelik profillerinin bir cihazın eUICC'sinde birlikte bulunabilmesi ve her operatör uygulamasının yalnızca ilgili operatöre ait profillere erişmesine izin verilmesidir. Örneğin, A operatörü B operatörüne ait bir profili indiremez, etkinleştiremez veya devre dışı bırakamaz.

Android, bir profile yalnızca sahibinin erişebilmesini sağlamak için profil sahibinin uygulamasına (yani operatör uygulamasına) özel ayrıcalıklar tanıyan bir mekanizma kullanır. Android platformu, profilin erişim kuralı dosyasında (ARF) depolanan sertifikaları yükler ve bu sertifikalar tarafından imzalanan uygulamalara EuiccManager API'lerine çağrı yapma izni verir. Genel hatlarıyla 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+, bir profil ve meta verilerini hazırlar. Bu meta veriler, aşağıdakileri içeren bir ARF içerir:

    1. Operatör uygulamasının ortak anahtar sertifikasının imzası (SHA-1 veya SHA-256) (zorunlu)
    2. Kargo şirketinin paket adı (kesinlikle önerilir)
  3. Operatör uygulaması, EuiccManager API ile 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 uygulamanın paket adıyla da eşleşmelidir.

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

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

eUICC OS ve SM-DP+, profil meta verilerinde özel bir etiketi BF76 desteklemelidir. Etiket içeriği, UICC Operatör Ayrıcalıkları bölümünde tanımlanan erişim kuralı applet'i (ARA) tarafından döndürülen operatör 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 daha fazla 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ğlı olmaları gereken kendi yerel profil asistanlarını (LPA) kullanabilir. Aşağıdaki bölümlerde, LPA uygulaması oluşturmaya ve Android sistemiyle entegre etmeye ilişkin kısa bir genel bakış sunulmaktadır.

Donanım/modem gereksinimleri

eUICC çipindeki LPA ve eSIM OS, en az GSMA RSP (Remote SIM Provisioning) v2.0 veya v2.2 sürümünü desteklemelidir. Ayrıca, eşleşen bir RSP sürümüne sahip SM-DP+ ve SM-DS sunucuları kullanmayı da planlamanız gerekir. Ayrıntılı RSP mimarisi için GSMA SGP.21 RSP Mimari Spesifikasyonu'na bakın.

Ayrıca, Android 9'daki eUICC API'leriyle entegrasyon için cihaz modemi, eUICC özelliklerinin kodlanmış desteğiyle (yerel profil yönetimi ve profil indirme) terminal özelliklerini göndermelidir. Ayrıca aşağıdaki yöntemleri de uygulaması gerekir:

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

  • IRadioConfig HAL 1.0 sürümü: getSimSlotsStatus

  • IRadioConfig AIDL v1.0: getAllowedCarriers

    Google LPA'nın, yalnızca izin verilen operatör için eSIM indirme veya aktarma işlemine izin verebilmek amacıyla operatör kilidi durumunu bilmesi gerekir. Aksi takdirde kullanıcılar bir SIM kartı indirip aktardıktan sonra cihazın farklı bir operatöre kilitli olduğunu fark edebilir.

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

    • Tedarikçi firma RIL / Modem, IRadioSimResponse.getAllowedCarriersResponse() HAL API'si kapsamında cihazın kilitli olduğu operatörün kilit durumunu ve operatör kimliğini doldurur.

Modem, varsayılan önyükleme profili etkinken eSIM'i geçerli bir SIM olarak tanır ve SIM'in açık kalmasını sağlar.

Android 10 çalıştıran cihazlar için kaldırılamayan eUICC alanı kimlik dizisi tanımlanmalıdır. Örneğin, arrays.xml adresine 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 Modern Gereksinimleri bölümüne bakın.

EuiccService

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 sınıfını genişletmeniz ve bu hizmeti manifest dosyanızda tanımlamanız gerekir. Hizmetin, yalnızca sistemin kendisine bağlanabilmesini sağlamak için android.permission.BIND_EUICC_SERVICE sistem izni alması gerekir. Hizmette android.service.euicc.EuiccService işlemini içeren bir intent filtresi de bulunmalıdır. Cihazda birden fazla uygulama varsa intent filtresinin önceliği sıfır olmayan bir değere ayarlanmalıdır. Örnek:

<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 bununla etkileşime geçer. 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. Hizmet bulunamazsa LPA desteği devre dışı bırakılır.

LUI'yi uygulamak için aşağıdaki işlemler için 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 gereklidir. Her birinin, uygun işlemi, android.service.euicc.category.EUICC_UI kategorisini ve sıfır olmayan bir önceliği içeren bir intent filtresi olmalıdır. Bu etkinliklerin uygulamalarını seçerken, EuiccService uygulamasının seçilmesiyle benzer bir mantık kullanılır. Örnek:

<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'i uygulayan kullanıcı arayüzünden farklı bir APK'dan gelebileceği anlamına gelir. Tek bir APK'ya veya birden fazla APK'ya (örneğin, EuiccService uygulayan bir APK ve LUI etkinlikleri sağlayan bir) sahip olma, tasarım seçimidir.

EuiccCardManager

EuiccCardManager, eSIM çipiyle iletişim kurma arayüzüdür. ES10 işlevleri (GSMA RSP spesifikasyonunda açıklandığı şekilde) sağlar ve düşük düzey APDU istek/yanıt komutlarının yanı sıra ASN.1 ayrıştırmasını işler. EuiccCardManager bir sistem API'sidir ve yalnızca sistem ayrıcalıklarına sahip 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ır

EuiccCardManager üzerinden profil işlemi API'leri, arayanın LPA olmasını gerektirir. Bu, Android çerçevesi tarafından zorunlu kılınmıştır. Bu, arayanın önceki bölümlerde açıklandığı gibi EuiccService'ü genişletmesi ve manifest dosyanızda tanımlanması gerektiği anlamına gelir.

EuiccManager'e benzer şekilde, EuiccCardManager API'lerini kullanmak için LPA'nızın öncelikle Context#getSystemService üzerinden 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);

EuiccCardManager dahili olarak bir AIDL arayüzü aracılığıyla EuiccCardController öğesine (telefon işleminde çalışan) bağlanır ve her EuiccCardManager yöntemi, farklı ve özel bir AIDL arayüzü aracılığıyla telefon işleminden geri çağırmayı alır. EuiccCardManager API'leri kullanılırken arayan (LPA), geri aramanın çağrıldığı bir Executor nesnesi sağlamalı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 aynı kullanım modeline sahip. Örneğin, eUICC'ye bir 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);

Belirtilen bildirim etkinlikleriyle ilgili bildirim listesini almak için:

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

Operatör uygulaması üzerinden eSIM profili 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 numaralı telefonu arayarak veya LPA'ya etkinleştirme kodu sağlayarak profilleri indirebilir.

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

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

Etkinleştirme kodunu 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, kullanıcı arayüzü akışının tamamını kontrol edebilir. Diğer bir deyişle, hiçbir operatör uygulamasının 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 temel hazırlığı hizmetini tanımlama

LPA ve operatör uygulaması iki AIDL arayüzü üzerinden iletişim kurar: ICarrierEuiccProvisioningService ve IGetActivationCodeCallback. Operatör uygulaması, bir ICarrierEuiccProvisioningService arayüzü uygulamalı ve bunu manifest beyanında göstermelidir. LPA, ICarrierEuiccProvisioningService'e bağlanmalı ve IGetActivationCodeCallback'ü uygulamalıdır. AIDL arayüzünü uygulama ve gösterme hakkında daha fazla bilgi için AIDL arayüzünü 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 kopyalayıp ServiceConnection'ı uygulaması gerekir.

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

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

getActivationCode ile getActivationCodeForEid arasındaki fark, getActivationCodeForEid'ün operatörlerin indirme işlemi başlamadan önce bir profili cihazın EID'sine önceden bağlamasına olanak tanımasıdır.

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ğlanabilmesi için operatör uygulamasının hem ICarrierEuiccProvisioningService.aidl hem de IGetActivationCodeCallback.aidl dosyasını projenize kopyalaması ve AndroidManifest.xml dosyasında ICarrierEuiccProvisioningService hizmetini tanımlaması 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 işlemini içeren bir intent 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. Ardından LPA, profil etkinleştirme kodunu almak için bu iki yöntemden birini çağırabilir. Operatör uygulaması, kod operatörün sunucusundan başarıyla getirildiyse etkinleştirme koduyla IGetActivationCodeCallback#onSuccess'ü arayarak 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şlat

Android 11 ve sonraki sürümleri çalıştıran cihazlarda LPA, operatör uygulamasının kullanıcı arayüzünü başlatabilir. Operatör uygulaması, LPA'ya etkinleştirme kodu göndermeden önce kullanıcıdan ek bilgi isteyebilir. Bu nedenle bu özellik faydalıdır. Örneğin, operatörler telefon numaralarını etkinleştirmek veya diğer numara taşıma hizmetlerini gerçekleştirmek için kullanıcıların giriş yapmasını zorunlu tutabilir.

Operatör uygulamasının kullanıcı arayüzünü LPA'da başlatma işlemi şu şekildedir:

  1. LPA, android.service.euicc.action.START_CARRIER_ACTIVATION amacını işlemi içeren operatör uygulaması paketine göndererek operatör uygulamasının etkinleştirme akışını başlatır. (Operatör uygulaması alıcısı, LPA olmayan uygulamalardan amaç almamak 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ıyı kaydetme veya operatörün arka ucuna HTTP istekleri gönderme.

  3. Operatör uygulaması, setResult(int, Intent) ve finish()'yi çağırarak 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ı, LPA'nın operatör uygulamasının hizmetini bağlamasına izin vermek yerine kullanıcının QR kodunu taraması gerektiğini belirlerse operatör uygulaması LPA'ya RESULT_OK ile setResult(int, Intent) ve ekstra boole içeren Intent örneğini true olarak ayarlanmış bir Intent kullanarak yanıt verir.android.telephony.euicc.extra.USE_QR_SCANNER Ardından LPA, operatör uygulamasının ICarrierEuiccProvisioningService uygulamasını bağlamak yerine ekstra özelliği kontrol eder ve QR tarayıcıyı başlatır.
    2. Operatör uygulaması kilitlenirse 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, LPA dışındaki arayanların operatör uygulamasından etkinleştirme kodu almasını önlemek için sonuç amacıyla sağlanan etkinleştirme kodunu doğrudan kabul etmemelidir.

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 amacıyla 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 profili etkinleştirme işlemi tamamlandığında bir yayın gönderir.

  1. LPA, android.service.euicc.action.START_EUICC_ACTIVATION işlemini içeren bir intent filtresi içeren bir etkinlik tanımlamalıdır. Cihazda birden fazla uygulama varsa intent filtresinin önceliği sıfır olmayan bir değere ayarlanmalıdır. Örnek:

    <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 giriş yapması veya operatörün arka ucuna HTTP istekleri gönderme.

  3. Operatör uygulamasının bu noktada 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 işlemiyle startActivityForResult(Intent, int)'ü çağırarak LPA'yı başlatır. LPA, boole ek 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 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 işlemi sırasında yükleme ekranı gibi tüm gerekli 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. Operatör uygulaması bu kodu onActivityResult(int, int, Intent) içinde işler.

    1. LPA, yeni eSIM profilini indirirse RESULT_OK ile yanıt verir.
    2. Kullanıcı LPA'da eSIM profili etkinleştirme işlemini 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.

    LPA olmayan arayanların operatör uygulamasından etkinleştirme kodu almasını önlemek için LPA, güvenlik nedeniyle doğrudan sağlanan intent'te etkinleştirme kodunu kabul etmez.

Birden fazla eSIM desteği

Android 10 veya sonraki sürümleri çalıştıran cihazlar için EuiccManager sınıfı, birden fazla eSIM'i olan cihazları destekler. Platform, EuiccManager örneğini varsayılan eUICC ile otomatik olarak ilişkilendirdiğinden, Android 10'a yükseltilen tek bir eSIM'i olan cihazlarda LPA uygulamasında herhangi bir değişiklik yapılması gerekmez. Varsayılan eUICC, radyo HAL sürümü 1.2 veya daha yeni olan cihazlar için platform tarafından, radyo HAL sürümü 1.2'den eski olan cihazlar için ise LPA tarafından belirlenir.

Şartlar

Birden fazla eSIM'i desteklemek için cihazda birden fazla eUICC olmalıdır. Bu eUICC, yerleşik bir eUICC veya çıkarılabilir eUICC'lerin takılabileceği fiziksel bir SIM yuvası olabilir.

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

Uygulama

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

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

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

Birden fazla eSIM'e sahip bir cihaz için operatör uygulaması oluştururken, belirli bir kart kimliğine sabitlenmiş bir EuiccManager nesnesi oluşturmak üzere EuiccManager'daki 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'daki getCardIdForDefaultEuicc yöntemini kullanın. Bu yöntem, radyo HAL sürümü 1.2'den düşükse UNSUPPORTED_CARD_ID, cihaz eUICC'yi okumadıysa UNINITIALIZED_CARD_ID döndürür.

Kart kimliklerini TelephonyManager'teki getUiccCardsInfo ve getUiccSlotsInfo (sistem API'si) ile SubscriptionInfo'teki getCardId üzerinden de 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 erişilemez hale gelirse (örneğin, devre dışı bırakı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.

1. Örnek: Etkin aboneliği alma ve EuiccManager örneğini örneklendirme

// 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 yineleme ve kaldırılabilir bir eUICC için EuiccManager örneğini oluşturma

// 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 sürümlerinde LPA'nın olması beklenmez (her telefon eSIM'i desteklemez). Bu nedenle, uçtan uca CTS test durumları yoktur. Bununla birlikte, açığa çıkan eUICC API'lerinin Android derlemelerinde geçerli olduğundan emin olmak için AOSP'de temel test durumları mevcuttur.

Derlemelerin aşağıdaki CTS test durumlarını (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ülerini tamamlamalıdır. Operatör uygulaması en azından aynı operatöre ait tüm abonelik profillerini listeleyebilir, profil indirip yükleyebilir, profilde bir hizmeti etkinleştirebilir, profiller arasında geçiş yapabilir ve profilleri silebilir olmalıdır.

Kendi LPA'nızı oluşturuyorsanız çok daha titiz bir test yapmanız gerekir. Sorunları çözmek ve LPA'nızın RSP mimarisi içinde birlikte çalışabilmesini sağlamak için modem tedarikçiniz, eUICC çipi veya eSIM OS tedarikçiniz, SM-DP+ tedarikçileri ve operatörlerinizle birlikte çalışmanız gerekir. Çok sayıda manuel test yapılması kaçınılmazdır. En iyi test kapsamı için GSMA SGP.23 RSP Test Planı'na uymanız gerekir.