Menerapkan eSIM

Teknologi SIM tertanam (eSIM, atau eUICC) memungkinkan pengguna ponsel mengunduh profil operator dan mengaktifkan layanan operator tanpa memiliki kartu SIM fisik. Ini adalah spesifikasi global yang didorong oleh GSMA yang memungkinkan penyediaan SIM jarak jauh (RSP) pada perangkat seluler apa pun. Dimulai dengan Android 9, framework Android menyediakan API standar untuk mengakses eSIM dan mengelola profil langganan di eSIM. API eUICC ini memungkinkan pihak ketiga mengembangkan aplikasi operator dan asisten profil lokal (LPA) mereka sendiri di perangkat Android yang mendukung eSIM.

LPA adalah aplikasi sistem mandiri yang harus disertakan dalam image build Android. Pengelolaan profil di eSIM umumnya dilakukan oleh LPA, karena berfungsi sebagai jembatan antara SM-DP+ (layanan jarak jauh yang menyiapkan, menyimpan, dan mengirimkan paket profil ke perangkat) dan chip eUICC. APK LPA secara opsional dapat menyertakan komponen UI, yang disebut LPA UI atau LUI, untuk menyediakan tempat terpusat bagi pengguna akhir untuk mengelola semua profil langganan yang disematkan. Framework Android secara otomatis menemukan dan terhubung ke LPA terbaik yang tersedia, dan merutekan semua operasi eUICC melalui instance LPA.

Arsitektur Penyediaan SIM Jarak Jauh (RSP) yang disederhanakan

Gambar 1. Arsitektur RSP yang disederhanakan

Operator jaringan seluler yang tertarik untuk membuat aplikasi operator harus melihat API di EuiccManager , yang menyediakan operasi manajemen profil tingkat tinggi seperti downloadSubscription() , switchToSubscription() , dan deleteSubscription() .

Jika Anda adalah OEM perangkat yang tertarik untuk membuat aplikasi sistem LPA Anda sendiri, Anda harus memperluas EuiccService agar kerangka kerja Android dapat terhubung ke layanan LPA Anda. Selain itu, Anda harus menggunakan API di EuiccCardManager , yang menyediakan fungsi ES10x berdasarkan GSMA RSP v2.0. Fungsi-fungsi ini digunakan untuk mengeluarkan perintah ke chip eUICC, seperti prepareDownload() , loadBoundProfilePackage() , retrieveNotificationList() , dan resetMemory() .

API di EuiccManager memerlukan aplikasi LPA yang diimplementasikan dengan benar agar dapat berfungsi dan pemanggil API EuiccCardManager harus berupa LPA. Hal ini ditegakkan oleh kerangka Android.

Perangkat yang menjalankan Android 10 atau lebih tinggi dapat mendukung perangkat dengan beberapa eSIM. Untuk informasi lebih lanjut, lihat Mendukung beberapa eSIM .

Membuat aplikasi operator

API eUICC di Android 9 memungkinkan operator jaringan seluler membuat aplikasi bermerek operator untuk mengelola profil mereka secara langsung. Hal ini termasuk mengunduh dan menghapus profil langganan yang dimiliki oleh operator, serta beralih ke profil yang dimiliki oleh operator.

Manajer Euicc

EuiccManager adalah titik masuk utama bagi aplikasi untuk berinteraksi dengan LPA. Ini termasuk aplikasi operator yang mengunduh, menghapus, dan beralih ke langganan milik operator. Ini juga mencakup aplikasi sistem LUI, yang menyediakan lokasi/UI pusat untuk mengelola semua langganan yang disematkan, dan dapat menjadi aplikasi terpisah dari aplikasi yang menyediakan EuiccService .

Untuk menggunakan API publik, aplikasi operator harus terlebih dahulu mendapatkan instance EuiccManager melalui Context#getSystemService :

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

Anda harus memeriksa apakah eSIM didukung pada perangkat sebelum melakukan operasi eSIM apa pun. EuiccManager#isEnabled() umumnya mengembalikan true jika fitur android.hardware.telephony.euicc ditentukan dan ada paket LPA.

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

Untuk mendapatkan informasi tentang perangkat keras eUICC dan versi OS eSIM:

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

Banyak API, seperti downloadSubscription() dan switchToSubscription() , menggunakan callback PendingIntent karena penyelesaiannya mungkin memerlukan waktu beberapa detik atau bahkan beberapa menit. PendingIntent dikirim dengan kode hasil di ruang EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_ , yang menyediakan kode kesalahan yang ditentukan kerangka kerja, serta kode hasil terperinci arbitrer yang disebarkan dari LPA sebagai EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE , yang memungkinkan aplikasi operator melacak untuk tujuan logging/debugging. Callback PendingIntent harus BroadcastReceiver .

Untuk mengunduh langganan tertentu yang dapat diunduh (dibuat dari kode aktivasi atau kode QR):

// Register receiver.
static final String ACTION_DOWNLOAD_SUBSCRIPTION = "download_subscription";
static final String LPA_DECLARED_PERMISSION
    = "com.your.company.lpa.permission.BROADCAST";
BroadcastReceiver receiver =
        new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (!action.equals(intent.getAction())) {
                    return;
                }
                resultCode = getResultCode();
                detailedCode = intent.getIntExtra(
                    EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE,
                    0 /* defaultValue*/);

                // If the result code is a resolvable error, call startResolutionActivity
                if (resultCode == EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR) {
                    PendingIntent callbackIntent = PendingIntent.getBroadcast(
                        getContext(), 0 /* requestCode */, intent,
                        PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
                    mgr.startResolutionActivity(
                        activity,
                        0 /* requestCode */,
                        intent,
                        callbackIntent);
                }

                resultIntent = intent;
            }
        };
context.registerReceiver(receiver,
        new IntentFilter(ACTION_DOWNLOAD_SUBSCRIPTION),
        LPA_DECLARED_PERMISSION /* broadcastPermission*/,
        null /* handler */);

// Download subscription asynchronously.
DownloadableSubscription sub = DownloadableSubscription
        .forActivationCode(code /* encodedActivationCode*/);
Intent intent = new Intent(action).setPackage(context.getPackageName());
PendingIntent callbackIntent = PendingIntent.getBroadcast(
        getContext(), 0 /* requestCode */, intent,
        PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
mgr.downloadSubscription(sub, true /* switchAfterDownload */,
        callbackIntent);

Tentukan dan gunakan izin di AndroidManifest.xml :

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

Untuk beralih ke langganan dengan ID langganan:

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

Untuk daftar lengkap API EuiccManager dan contoh kode, lihat API eUICC .

Kesalahan yang dapat diatasi

Ada beberapa kasus di mana sistem tidak dapat menyelesaikan operasi eSIM tetapi kesalahannya dapat diatasi oleh pengguna. Misalnya, downloadSubscription mungkin gagal jika metadata profil menunjukkan bahwa kode konfirmasi operator diperlukan. Atau switchToSubscription mungkin gagal jika aplikasi operator memiliki hak istimewa operator atas profil tujuan (yaitu, operator memiliki profil tersebut) namun tidak memiliki hak istimewa operator atas profil yang saat ini diaktifkan, dan karenanya diperlukan persetujuan pengguna.

Untuk kasus ini, callback pemanggil dipanggil dengan EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR . Callback Intent berisi tambahan internal sehingga ketika pemanggil meneruskannya ke EuiccManager#startResolutionActivity , resolusi dapat diminta melalui LUI. Menggunakan kode konfirmasi misalnya lagi, EuiccManager#startResolutionActivity memicu layar LUI yang memungkinkan pengguna memasukkan kode konfirmasi; setelah kode dimasukkan, operasi pengunduhan dilanjutkan. Pendekatan ini memberikan aplikasi operator kontrol penuh atas kapan UI ditampilkan, namun memberikan LPA/LUI metode yang dapat diperluas untuk menambahkan penanganan baru atas masalah yang dapat dipulihkan pengguna di masa mendatang tanpa memerlukan perubahan pada aplikasi klien.

Android 9 mendefinisikan error yang dapat diatasi ini di EuiccService , yang harus ditangani LUI:

/**
 * Alert the user that this action will result in an active SIM being
 * deactivated. To implement the LUI triggered by the system, you need to define
 * this in AndroidManifest.xml.
 */
public static final String ACTION_RESOLVE_DEACTIVATE_SIM =
        "android.service.euicc.action.RESOLVE_DEACTIVATE_SIM";
/**
 * Alert the user about a download/switch being done for an app that doesn't
 * currently have carrier privileges.
 */
public static final String ACTION_RESOLVE_NO_PRIVILEGES =
        "android.service.euicc.action.RESOLVE_NO_PRIVILEGES";

/** Ask the user to resolve all the resolvable errors. */
public static final String ACTION_RESOLVE_RESOLVABLE_ERRORS =
        "android.service.euicc.action.RESOLVE_RESOLVABLE_ERRORS";

Hak istimewa operator

Jika Anda adalah operator yang mengembangkan aplikasi operator Anda sendiri yang memanggil EuiccManager untuk mengunduh profil ke perangkat, profil Anda harus menyertakan aturan hak istimewa operator yang sesuai dengan aplikasi operator Anda di metadata. Hal ini karena profil langganan milik operator yang berbeda dapat hidup berdampingan di eUICC perangkat, dan setiap aplikasi operator hanya diperbolehkan mengakses profil yang dimiliki oleh operator tersebut. Misalnya, operator A tidak boleh mengunduh, mengaktifkan, atau menonaktifkan profil yang dimiliki oleh operator B.

Untuk memastikan profil hanya dapat diakses oleh pemiliknya, Android menggunakan mekanisme untuk memberikan hak istimewa khusus kepada aplikasi pemilik profil (yaitu, aplikasi operator). Platform Android memuat sertifikat yang disimpan dalam file aturan akses (ARF) profil dan memberikan izin kepada aplikasi yang ditandatangani oleh sertifikat ini untuk melakukan panggilan ke API EuiccManager . Proses tingkat tinggi dijelaskan di bawah ini:

  1. Operator menandatangani APK aplikasi operator; alat apksigner melampirkan sertifikat kunci publik ke APK.
  2. Operator/SM-DP+ menyiapkan profil dan metadatanya, yang mencakup ARF yang berisi:

    1. Tanda tangan (SHA-1 atau SHA-256) dari sertifikat kunci publik aplikasi operator (wajib)
    2. Nama paket aplikasi operator (sangat disarankan)
  3. Aplikasi operator mencoba melakukan operasi eUICC melalui EuiccManager API.

  4. Platform Android memverifikasi hash SHA-1 atau SHA-256 dari sertifikat aplikasi pemanggil cocok dengan tanda tangan sertifikat yang diperoleh dari ARF profil target. Jika nama paket aplikasi operator disertakan dalam ARF, nama paket tersebut juga harus cocok dengan nama paket aplikasi pemanggil.

  5. Setelah tanda tangan dan nama paket (jika disertakan) diverifikasi, hak istimewa operator diberikan kepada aplikasi pemanggil melalui profil target.

Karena metadata profil dapat tersedia di luar profil itu sendiri (sehingga LPA dapat mengambil metadata profil dari SM-DP+ sebelum profil diunduh, atau dari ISD-R ketika profil dinonaktifkan), metadata tersebut harus berisi aturan hak istimewa operator yang sama seperti di profil.

OS eUICC dan SM-DP+ harus mendukung tag kepemilikan BF76 di metadata profil. Konten tag harus merupakan aturan hak istimewa operator yang sama seperti yang dikembalikan oleh applet aturan akses (ARA) yang ditentukan dalam Hak Istimewa Operator UICC :

RefArDo ::= [PRIVATE 2] SEQUENCE {  -- Tag E2
    refDo [PRIVATE 1] SEQUENCE {  -- Tag E1
        deviceAppIdRefDo [PRIVATE 1] OCTET STRING (SIZE(20|32)),  -- Tag C1
        pkgRefDo [PRIVATE 10] OCTET STRING (SIZE(0..127)) OPTIONAL  -- Tag CA
    },
    arDo [PRIVATE 3] SEQUENCE {  -- Tag E3
        permArDo [PRIVATE 27] OCTET STRING (SIZE(8))  -- Tag DB
    }
}

Untuk detail selengkapnya tentang penandatanganan aplikasi, lihat Menandatangani aplikasi Anda . Untuk detail tentang hak istimewa operator, lihat Hak Istimewa Operator UICC .

Membuat aplikasi asisten profil lokal

Produsen perangkat dapat mengimplementasikan asisten profil lokal (LPA) mereka sendiri, yang harus terhubung dengan Android Euicc API. Bagian berikut memberikan gambaran singkat tentang pembuatan aplikasi LPA dan mengintegrasikannya dengan sistem Android.

Persyaratan perangkat keras/modem

LPA dan OS eSIM pada chip eUICC harus mendukung setidaknya GSMA RSP (Remote SIM Provisioning) v2.0 atau v2.2. Anda juga harus merencanakan untuk menggunakan server SM-DP+ dan SM-DS yang memiliki versi RSP yang cocok. Untuk detail arsitektur RSP, lihat Spesifikasi Arsitektur RSP GSMA SGP.21 .

Selain itu, untuk berintegrasi dengan API eUICC di Android 9, modem perangkat harus mengirimkan kemampuan terminal dengan dukungan untuk kemampuan eUICC yang dikodekan (manajemen profil lokal dan download profil). Hal ini juga perlu menerapkan metode berikut:

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

  • IRadioConfig HAL v1.0: getSimSlotsStatus

  • IRadioConfig AIDL v1.0: getAllowedCarriers

    LPA Google perlu mengetahui status kunci operator sehingga dapat mengizinkan pengunduhan atau transfer eSIM hanya untuk operator yang diizinkan. Jika tidak, pengguna mungkin akan mengunduh dan mentransfer SIM dan kemudian menyadari bahwa perangkat tersebut dikunci oleh operator ke operator lain.

    • Vendor atau OEM harus mengimplementasikan API IRadioSim.getAllowedCarriers()HAL.

    • Vendor RIL/Modem akan mengisi status kunci dan operatorId operator tempat perangkat dikunci sebagai bagian dari API IRadioSimResponse.getAllowedCarriersResponse()HAL.

Modem harus mengenali eSIM dengan profil boot default diaktifkan sebagai SIM yang valid dan daya SIM tetap menyala.

Untuk perangkat yang menjalankan Android 10, rangkaian ID slot eUICC yang tidak dapat dilepas harus ditentukan. Misalnya, lihat arrays.xml .

<resources>
   <!-- Device-specific array of SIM slot indexes which are are embedded eUICCs.
        e.g. If a device has two physical slots with indexes 0, 1, and slot 1 is an
        eUICC, then the value of this array should be:
            <integer-array name="non_removable_euicc_slots">
                <item>1</item>
            </integer-array>
        If a device has three physical slots and slot 1 and 2 are eUICCs, then the value of
        this array should be:
            <integer-array name="non_removable_euicc_slots">
               <item>1</item>
               <item>2</item>
            </integer-array>
        This is used to differentiate between removable eUICCs and built in eUICCs, and should
        be set by OEMs for devices which use eUICCs. -->

   <integer-array name="non_removable_euicc_slots">
       <item>1</item>
   </integer-array>
</resources>

Untuk daftar lengkap persyaratan modem, lihat Persyaratan Modem untuk Dukungan eSIM .

Layanan Euicc

LPA terdiri dari dua komponen terpisah (keduanya dapat diimplementasikan dalam APK yang sama): backend LPA, dan LPA UI atau LUI.

Untuk mengimplementasikan backend LPA, Anda harus memperluas EuiccService dan mendeklarasikan layanan ini dalam file manifes Anda. Layanan ini harus memerlukan izin sistem android.permission.BIND_EUICC_SERVICE untuk memastikan bahwa hanya sistem yang dapat mengikatnya. Layanan ini juga harus menyertakan filter maksud dengan tindakan android.service.euicc.EuiccService . Prioritas filter maksud harus ditetapkan ke nilai bukan nol jika terdapat beberapa implementasi pada perangkat. Misalnya:

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

Secara internal, framework Android menentukan LPA aktif dan berinteraksi dengannya sesuai kebutuhan untuk mendukung API eUICC Android. PackageManager ditanyakan untuk semua aplikasi dengan izin android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS , yang menentukan layanan untuk tindakan android.service.euicc.EuiccService . Layanan dengan prioritas tertinggi dipilih. Jika tidak ada layanan yang ditemukan, dukungan LPA dinonaktifkan.

Untuk mengimplementasikan LUI, Anda harus menyediakan aktivitas untuk tindakan berikut:

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

Seperti halnya layanan, setiap aktivitas harus memerlukan izin sistem android.permission.BIND_EUICC_SERVICE . Masing-masing harus memiliki filter maksud dengan tindakan yang sesuai, kategori android.service.euicc.category.EUICC_UI , dan prioritas bukan nol. Logika serupa digunakan untuk memilih implementasi aktivitas ini seperti memilih implementasi EuiccService . Misalnya:

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

Artinya, UI yang mengimplementasikan layar ini bisa berasal dari APK yang berbeda dengan APK yang mengimplementasikan EuiccService . Apakah akan memiliki satu APK atau beberapa APK (misalnya, APK yang mengimplementasikan EuiccService dan APK yang menyediakan aktivitas LUI) merupakan pilihan desain.

EuiccCardManager

EuiccCardManager adalah antarmuka untuk berkomunikasi dengan chip eSIM. Ini menyediakan fungsi ES10 (seperti yang dijelaskan dalam spesifikasi GSMA RSP) dan menangani perintah permintaan/respons APDU tingkat rendah serta penguraian ASN.1. EuiccCardManager adalah API sistem dan hanya dapat dipanggil oleh aplikasi yang memiliki hak istimewa sistem.

Aplikasi operator, LPA, dan API Euicc

Gambar 2. Aplikasi operator dan LPA menggunakan API Euicc

API operasi profil melalui EuiccCardManager mengharuskan pemanggil menjadi LPA. Hal ini ditegakkan oleh kerangka Android. Ini berarti pemanggil harus memperluas EuiccService dan dideklarasikan dalam file manifes Anda, seperti yang dijelaskan di bagian sebelumnya.

Mirip dengan EuiccManager , untuk menggunakan API EuiccCardManager , LPA Anda harus terlebih dahulu mendapatkan instance EuiccCardManager melalui Context#getSystemService :

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

Kemudian, untuk mendapatkan semua profil di eUICC:

ResultCallback<EuiccProfileInfo[]> callback =
       new ResultCallback<EuiccProfileInfo[]>() {
           @Override
           public void onComplete(int resultCode,
                   EuiccProfileInfo[] result) {
               if (resultCode == EuiccCardManagerReflector.RESULT_OK) {
                   // handle result
               } else {
                   // handle error
               }
           }
       };

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

Secara internal, EuiccCardManager berikatan dengan EuiccCardController (yang berjalan dalam proses telepon) melalui antarmuka AIDL, dan setiap metode EuiccCardManager menerima panggilan baliknya dari proses telepon melalui antarmuka AIDL khusus yang berbeda. Saat menggunakan API EuiccCardManager , pemanggil (LPA) harus menyediakan objek Executor yang dapat digunakan untuk memanggil panggilan balik. Objek Executor ini dapat berjalan pada satu thread atau pada kumpulan thread pilihan Anda.

Kebanyakan API EuiccCardManager memiliki pola penggunaan yang sama. Misalnya, untuk memuat paket profil terikat ke eUICC:

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

Untuk beralih ke profil lain dengan ICCID tertentu:

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

Untuk mendapatkan alamat SM-DP+ default dari chip eUICC:

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

Untuk mengambil daftar notifikasi dari peristiwa notifikasi yang diberikan:

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

Mengaktifkan profil eSIM melalui aplikasi operator

Pada perangkat yang menjalankan Android 9 atau lebih tinggi, Anda dapat menggunakan aplikasi operator untuk mengaktifkan eSIM dan mendownload profil. Aplikasi operator dapat mengunduh profil dengan menelepon downloadSubscription secara langsung atau dengan memberikan kode aktivasi ke LPA.

Saat aplikasi operator mengunduh profil dengan memanggil downloadSubscription , panggilan tersebut memaksa aplikasi tersebut dapat mengelola profil melalui tag metadata BF76 yang mengkodekan aturan hak istimewa operator untuk profil tersebut. Jika profil tidak memiliki tag BF76 atau jika tag BF76 nya tidak cocok dengan tanda tangan aplikasi operator panggilan, pengunduhan akan ditolak.

Bagian di bawah ini menjelaskan cara mengaktifkan eSIM melalui aplikasi operator menggunakan kode aktivasi.

Mengaktifkan eSIM menggunakan kode aktivasi

Saat menggunakan kode aktivasi untuk mengaktifkan profil eSIM, LPA mengambil kode aktivasi dari aplikasi operator dan mengunduh profil tersebut. Alur ini dapat dimulai oleh LPA dan LPA dapat mengontrol seluruh alur UI, artinya tidak ada UI aplikasi operator yang ditampilkan. Pendekatan ini mengabaikan pemeriksaan tag BF76 , dan operator jaringan tidak perlu menerapkan seluruh alur UI aktivasi eSIM termasuk mengunduh profil eSIM dan penanganan kesalahan.

Mendefinisikan layanan provisi eUICC operator

Aplikasi LPA dan operator berkomunikasi melalui dua antarmuka AIDL : ICarrierEuiccProvisioningService dan IGetActivationCodeCallback . Aplikasi operator harus mengimplementasikan antarmuka ICarrierEuiccProvisioningService dan mengeksposnya dalam deklarasi manifesnya . LPA harus mengikat ICarrierEuiccProvisioningService dan mengimplementasikan IGetActivationCodeCallback . Untuk informasi selengkapnya tentang cara mengimplementasikan dan mengekspos antarmuka AIDL, lihat Mendefinisikan dan antarmuka AIDL .

Untuk menentukan antarmuka AIDL, buat file AIDL berikut untuk LPA dan aplikasi operator.

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

Contoh implementasi LPA

Untuk mengikat implementasi ICarrierEuiccProvisioningService aplikasi operator, LPA harus menyalin ICarrierEuiccProvisioningService.aidl dan IGetActivationCodeCallback.aidl ke proyek Anda dan mengimplementasikan ServiceConnection .

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

Setelah mengikat implementasi ICarrierEuiccProvisioningService aplikasi operator, LPA memanggil getActivationCode atau getActivationCodeForEid untuk mendapatkan kode aktivasi dari aplikasi operator dengan meneruskan implementasi kelas stub IGetActivationCodeCallback .

Perbedaan antara getActivationCode dan getActivationCodeForEid adalah getActivationCodeForEid memungkinkan operator untuk mengikat terlebih dahulu profil ke EID perangkat sebelum proses pengunduhan dimulai.

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

Contoh implementasi untuk aplikasi operator

Agar LPA dapat diikat ke aplikasi operator, aplikasi operator harus menyalin ICarrierEuiccProvisioningService.aidl dan IGetActivationCodeCallback.aidl ke proyek Anda dan mendeklarasikan layanan ICarrierEuiccProvisioningService di file AndroidManifest.xml . Layanan ini harus memerlukan izin sistem android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS untuk memastikan bahwa hanya LPA, aplikasi dengan hak istimewa sistem, yang dapat mengikatnya. Layanan ini juga harus menyertakan filter maksud dengan tindakan android.service.euicc.action.BIND_CARRIER_PROVISIONING_SERVICE .

  • AndroidManifest.xml

    <application>
      ...
      <service
          android:name=".CarrierEuiccProvisioningService"
          android:exported="true"
          android:permission="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS">
        <intent-filter>
          <action android:name="android.service.euicc.action.BIND_CARRIER_PROVISIONING_SERVICE"/>
        </intent-filter>
      </service>
      ...
    </application>
    

Untuk mengimplementasikan layanan aplikasi operator AIDL, buat layanan, perluas kelas Stub , dan implementasikan metode getActivationCode dan getActivationCodeForEid . LPA kemudian dapat memanggil metode mana pun untuk mengambil kode aktivasi profil. Aplikasi operator harus merespons dengan memanggil IGetActivationCodeCallback#onSuccess dengan kode aktivasi jika kode berhasil diambil dari server operator. Jika tidak berhasil, aplikasi operator harus merespons dengan IGetActivationCodeCallback#onFailure .

  • CarrierEuiccProvisioningService.java

    import android.service.euicc.ICarrierEuiccProvisioningService;
    import android.service.euicc.ICarrierEuiccProvisioningService.Stub;
    import android.service.euicc.IGetActivationCodeCallback;
    
    public class CarrierEuiccProvisioningService extends Service {
        private final ICarrierEuiccProvisioningService.Stub binder =
            new Stub() {
              @Override
              public void getActivationCode(IGetActivationCodeCallback callback) throws RemoteException {
                String activationCode = // do whatever work necessary to get an activation code (HTTP requests to carrier server, fetch from storage, etc.)
                callback.onSuccess(activationCode);
              }
    
              @Override
              public void getActivationCodeForEid(String eid, IGetActivationCodeCallback callback) throws RemoteException {
                String activationCode = // do whatever work necessary (HTTP requests, fetch from storage, etc.)
                callback.onSuccess(activationCode);
              }
          }
    }
    

Memulai UI aplikasi operator dalam alur aktivasi LPA

Pada perangkat yang menjalankan Android 11 dan lebih tinggi, LPA dapat memulai UI aplikasi operator. Ini berguna karena aplikasi operator mungkin memerlukan informasi tambahan dari pengguna sebelum memberikan kode aktivasi ke LPA. Misalnya, operator mungkin mengharuskan pengguna masuk untuk mengaktifkan nomor telepon mereka atau melakukan layanan porting lainnya.

Ini adalah proses untuk memulai UI aplikasi operator di LPA:

  1. LPA meluncurkan alur aktivasi aplikasi operator dengan mengirimkan maksud android.service.euicc.action.START_CARRIER_ACTIVATION ke paket aplikasi operator yang berisi tindakan tersebut. (Penerima aplikasi operator harus dilindungi dalam deklarasi manifes dengan android:permission="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS" untuk menghindari penerimaan maksud dari aplikasi non-LPA.)

    String packageName = // The carrier app's package name
    
    Intent carrierAppIntent =
        new Intent(“android.service.euicc.action.START_CARRIER_ACTIVATION”)
            .setPackage(packageName);
    
    ResolveInfo activity =
        context.getPackageManager().resolveActivity(carrierAppIntent, 0);
    
    carrierAppIntent
        .setClassName(activity.activityInfo.packageName, activity.activityInfo.name);
    
    startActivityForResult(carrierAppIntent, requestCode);
    
  2. Aplikasi operator melakukan tugasnya menggunakan UI-nya sendiri. Misalnya, memasukkan pengguna atau mengirim permintaan HTTP ke backend operator.

  3. Aplikasi operator merespons LPA dengan memanggil setResult(int, Intent) dan finish() .

    1. Jika aplikasi operator merespons dengan RESULT_OK , LPA melanjutkan alur aktivasi. Jika aplikasi operator menentukan bahwa pengguna harus memindai kode QR alih-alih membiarkan LPA mengikat layanan aplikasi operator, aplikasi operator akan merespons LPA menggunakan setResult(int, Intent) dengan RESULT_OK dan instance Intent yang berisi android.telephony.euicc.extra.USE_QR_SCANNER disetel ke true . LPA kemudian memeriksa ekstra dan meluncurkan pemindai QR alih-alih mengikat implementasi ICarrierEuiccProvisioningService aplikasi operator.
    2. Jika aplikasi operator mogok atau merespons dengan RESULT_CANCELED (ini adalah kode respons default), LPA membatalkan alur aktivasi eSIM.
    3. Jika aplikasi operator merespons dengan sesuatu selain RESULT_OK atau RESULT_CANCELED , LPA menganggapnya sebagai kesalahan.

    Demi alasan keamanan, LPA tidak boleh secara langsung menerima kode aktivasi yang diberikan dalam maksud hasil untuk memastikan bahwa penelepon non-LPA tidak bisa mendapatkan kode aktivasi dari aplikasi operator.

Meluncurkan alur aktivasi LPA di aplikasi operator

Mulai Android 11, aplikasi operator dapat menggunakan API eUICC untuk memulai LUI untuk aktivasi eSIM. Metode ini memunculkan UI alur aktivasi eSIM LPA untuk mengaktifkan profil eSIM. LPA kemudian mengirimkan siaran ketika aktivasi profil eSIM selesai.

  1. LPA harus mendeklarasikan aktivitas termasuk filter maksud dengan tindakan android.service.euicc.action.START_EUICC_ACTIVATION . Prioritas filter maksud harus ditetapkan ke nilai bukan nol jika terdapat beberapa implementasi pada perangkat. Misalnya:

    <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. Aplikasi operator melakukan tugasnya menggunakan UI-nya sendiri. Misalnya, memasukkan pengguna atau mengirim permintaan HTTP ke backend operator.

  3. Pada titik ini, aplikasi operator harus siap memberikan kode aktivasi melalui penerapan ICarrierEuiccProvisioningService . Aplikasi operator meluncurkan LPA dengan memanggil startActivityForResult(Intent, int) dengan tindakan android.telephony.euicc.action.START_EUICC_ACTIVATION . LPA juga memeriksa boolean ekstra android.telephony.euicc.extra.USE_QR_SCANNER . Jika nilainya true , LPA meluncurkan pemindai QR agar pengguna dapat memindai kode QR profil.

  4. Di sisi LPA, LPA mengikat implementasi ICarrierEuiccProvisioningService aplikasi operator untuk mengambil kode aktivasi dan mengunduh profil yang sesuai. LPA menampilkan semua elemen UI yang diperlukan selama pengunduhan, seperti layar pemuatan.

  5. Ketika alur aktivasi LPA selesai, LPA merespons aplikasi operator dengan kode hasil, yang ditangani aplikasi operator di onActivityResult(int, int, Intent) .

    1. Jika LPA berhasil mengunduh profil eSIM baru, LPA akan merespons dengan RESULT_OK .
    2. Jika pengguna membatalkan aktivasi profil eSIM di LPA, pengguna akan merespons dengan RESULT_CANCELED .
    3. Jika LPA merespons dengan sesuatu selain RESULT_OK atau RESULT_CANCELED , aplikasi operator menganggap ini sebagai kesalahan.

    Demi alasan keamanan, LPA tidak menerima kode aktivasi secara langsung dalam maksud yang disediakan untuk memastikan bahwa penelepon non-LPA tidak bisa mendapatkan kode aktivasi dari aplikasi operator.

Mendukung banyak eSIM

Untuk perangkat yang menjalankan Android 10 atau lebih tinggi, kelas EuiccManager mendukung perangkat dengan beberapa eSIM. Perangkat dengan satu eSIM yang diupgrade ke Android 10 tidak memerlukan modifikasi apa pun pada implementasi LPA karena platform secara otomatis mengaitkan instance EuiccManager dengan eUICC default. EUICC default ditentukan oleh platform untuk perangkat dengan radio HAL versi 1.2 atau lebih tinggi dan oleh LPA untuk perangkat dengan radio HAL versi lebih rendah dari 1.2.

Persyaratan

Untuk mendukung beberapa eSIM, perangkat harus memiliki lebih dari satu eUICC, yang dapat berupa eUICC internal atau slot SIM fisik tempat eUICC yang dapat dilepas dapat dimasukkan.

Radio HAL versi 1.2 atau lebih tinggi diperlukan untuk mendukung beberapa eSIM. Radio HAL versi 1.4 dan RadioConfig HAL versi 1.2 direkomendasikan.

Penerapan

Untuk mendukung beberapa eSIM (termasuk eUICC yang dapat dilepas atau SIM yang dapat diprogram), LPA harus menerapkan EuiccService , yang menerima ID slot yang sesuai dengan ID kartu yang diberikan penelepon.

Sumber daya non_removable_euicc_slots yang ditentukan dalam arrays.xml adalah array bilangan bulat yang mewakili ID slot eUICC bawaan perangkat. Anda harus menentukan sumber daya ini agar platform dapat menentukan apakah eUICC yang dimasukkan dapat dilepas atau tidak.

Aplikasi operator untuk perangkat dengan beberapa eSIM

Saat membuat aplikasi operator untuk perangkat dengan beberapa eSIM, gunakan metode createForCardId di EuiccManager untuk membuat objek EuiccManager yang disematkan ke ID kartu tertentu. ID kartu adalah nilai bilangan bulat yang secara unik mengidentifikasi UICC atau eUICC pada perangkat.

Untuk mendapatkan ID kartu untuk eUICC default perangkat, gunakan metode getCardIdForDefaultEuicc di TelephonyManager . Metode ini mengembalikan UNSUPPORTED_CARD_ID jika versi radio HAL lebih rendah dari 1.2 dan mengembalikan UNINITIALIZED_CARD_ID jika perangkat belum membaca eUICC.

Anda juga bisa mendapatkan ID kartu dari getUiccCardsInfo dan getUiccSlotsInfo (API sistem) di TelephonyManager , dan getCardId di SubscriptionInfo .

Ketika objek EuiccManager telah dibuat dengan ID kartu tertentu, semua operasi diarahkan ke eUICC dengan ID kartu tersebut. Jika eUICC menjadi tidak dapat dijangkau (misalnya, saat dimatikan atau dihapus) EuiccManager tidak lagi berfungsi.

Anda dapat menggunakan contoh kode berikut untuk membuat aplikasi operator.

Contoh 1: Dapatkan langganan aktif dan buat instance EuiccManager

// Get the active subscription and instantiate an EuiccManager for the eUICC which holds
// that subscription
SubscriptionManager subMan = (SubscriptionManager)
        mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
int cardId = subMan.getActiveSubscriptionInfo().getCardId();
EuiccManager euiccMan = (EuiccManager) mContext.getSystemService(Context.EUICC_SERVICE)
            .createForCardId(cardId);

Contoh 2: Iterasi melalui UICC dan buat instance EuiccManager untuk eUICC yang dapat dilepas

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

Validasi

AOSP tidak dilengkapi dengan implementasi LPA dan Anda tidak diharapkan memiliki LPA yang tersedia di semua versi Android (tidak semua ponsel mendukung eSIM). Karena alasan ini, tidak ada kasus uji CTS end-to-end. Namun, kasus pengujian dasar tersedia di AOSP untuk memastikan API eUICC yang diekspos valid di build Android.

Anda harus memastikan build lulus kasus uji CTS berikut (untuk API publik): /platform/cts/tests/tests/telephony/current/src/android/telephony/euicc/cts .

Operator yang menerapkan aplikasi operator harus menjalani siklus jaminan kualitas internal yang normal untuk memastikan semua fitur yang diterapkan berfungsi sesuai harapan. Minimal, aplikasi operator harus dapat mencantumkan semua profil langganan yang dimiliki oleh operator yang sama, mengunduh dan menginstal profil, mengaktifkan layanan pada profil, beralih antar profil, dan menghapus profil.

Jika Anda membuat LPA sendiri, Anda harus melalui pengujian yang lebih ketat. Anda harus bekerja sama dengan vendor modem, vendor chip eUICC atau OS eSIM, vendor SM-DP+, dan operator untuk menyelesaikan masalah dan memastikan interoperabilitas LPA Anda dalam arsitektur RSP. Banyaknya pengujian manual tidak bisa dihindari. Untuk cakupan pengujian terbaik, Anda harus mengikuti Rencana Tes RSP GSMA SGP.23 .