Implementasikan eSIM

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

LPA adalah aplikasi sistem mandiri yang harus disertakan dalam Image build Android. Pengelolaan profil pada eSIM umumnya dilakukan dengan 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 langganan yang disematkan untuk profil. Framework Android secara otomatis menemukan dan terhubung ke LPA 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 pengelolaan profil tingkat tinggi seperti downloadSubscription(), switchToSubscription(), dan deleteSubscription().

Jika Anda adalah OEM perangkat yang tertarik membuat aplikasi sistem LPA sendiri, Anda harus perluas EuiccService agar kerangka kerja Android dapat terhubung ke layanan LPA. 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 {i>chip<i} eUICC, seperti prepareDownload(), loadBoundProfilePackage(), retrieveNotificationList(), dan resetMemory().

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

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

Buat aplikasi operator

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

Pengelola Euicc

EuiccManager adalah titik entri utama bagi aplikasi untuk berinteraksi dengan IPA. Ini termasuk aplikasi operator yang mendownload, menghapus, dan beralih ke langganan yang dimiliki oleh operator. Termasuk pula aplikasi sistem LUI, menyediakan lokasi/UI pusat untuk mengelola semua langganan yang disematkan, dan dapat berupa aplikasi terpisah dari aplikasi yang menyediakan EuiccService.

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

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

Anda harus memeriksa apakah eSIM didukung di perangkat sebelum melakukan apa pun Operasi eSIM. EuiccManager#isEnabled() umumnya menampilkan true jika Fitur android.hardware.telephony.euicc ditentukan dan paket LPA ditetapkan saat ini.

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

Untuk mendapatkan informasi tentang hardware eUICC dan versi OS eSIM:

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

Banyak API, seperti downloadSubscription() dan switchToSubscription(), menggunakan Callback PendingIntent karena mungkin perlu waktu beberapa detik atau bahkan menit untuk menyelesaikannya. PendingIntent dikirim dengan kode hasil di EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_ ruang, yang memberikan kode error yang ditentukan framework, serta kode hasil mendetail arbitrer disebarkan dari LPA sebagai EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, sehingga memungkinkan aplikasi operator untuk melacak tujuan logging/proses debug. PendingIntent callback harus BroadcastReceiver.

Untuk mengunduh langganan tertentu yang dapat diunduh (yang 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 mengetahui daftar lengkap EuiccManager API dan contoh kode, lihat eUICC API.

Error yang dapat diselesaikan

Dalam beberapa kasus, sistem tidak dapat menyelesaikan operasi eSIM tetapi {i>error<i} dapat diselesaikan oleh pengguna. Misalnya, downloadSubscription mungkin gagal jika metadata profil menunjukkan bahwa kode konfirmasi ekspedisi tidak diperlukan. Atau switchToSubscription mungkin gagal jika aplikasi operator memiliki operator hak istimewa di atas profil tujuan (yaitu, ekspedisi yang memiliki profil) tetapi tidak memiliki hak istimewa operator atas profil yang saat ini diaktifkan, sehingga izin pengguna diperlukan.

Untuk kasus ini, callback pemanggil dipanggil dengan EuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR. Callback Intent berisi tambahan internal sedemikian rupa sehingga saat pemanggil meneruskannya ke EuiccManager#startResolutionActivity, penyelesaian dapat diminta melalui LUI. Menggunakan kode konfirmasi untuk contoh lagi, EuiccManager#startResolutionActivity memicu layar LUI yang memungkinkan pengguna memasukkan kode konfirmasi; setelah kode dimasukkan, operasi download akan dilanjutkan. Pendekatan ini memberi aplikasi operator kontrol penuh atas waktu ditampilkannya, tetapi memberi LPA/LUI metode yang dapat diperluas untuk menambahkan penanganan baru masalah di masa mendatang tanpa perlu mengubah aplikasi klien.

Android 9 mendefinisikan error yang dapat diselesaikan ini 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 sendiri yang memanggil EuiccManager untuk mengunduh profil ke perangkat, profil Anda harus menyertakan operator aturan hak istimewa yang sesuai dengan aplikasi operator Anda di metadata. Ini adalah karena profil langganan milik operator yang berbeda dapat digunakan berdampingan dalam eUICC perangkat, dan setiap aplikasi operator hanya boleh mengakses profil yang dimiliki oleh {i>operators<i} tersebut. Misalnya, operator A seharusnya tidak dapat mengunduh, mengaktifkan, atau menonaktifkan profil yang dimiliki 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). Tujuan Platform Android memuat sertifikat yang disimpan di file aturan akses profil (ARF) dan memberikan izin kepada aplikasi yang ditandatangani oleh sertifikat ini untuk melakukan panggilan ke EuiccManager API. Proses tingkat tinggi dijelaskan di bawah ini:

  1. Operator menandatangani APK aplikasi operator; tindakan 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) sertifikat kunci publik aplikasi operator (wajib diisi)
    2. Nama paket aplikasi ekspedisi (sangat disarankan)
  3. Aplikasi operator mencoba menjalankan operasi eUICC dengan EuiccManager API.

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

  5. Setelah tanda tangan dan nama paket (jika disertakan) diverifikasi, hak istimewa operator diberikan ke aplikasi penelepon di atas 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 bila profil dinonaktifkan), data harus berisi aturan hak istimewa operator yang sama seperti di profil.

eUICC OS dan SM-DP+ harus mendukung tag eksklusif BF76 di profil {i>metadata<i}. Konten tag harus memiliki aturan hak istimewa operator yang sama dengan yang ditampilkan dengan applet aturan akses (ARA) yang ditentukan di 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 Tanda tangani aplikasi Anda. Untuk detail tentang hak istimewa operator, lihat Hak Istimewa Operator UICC.

Buat aplikasi asisten profil lokal

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

Persyaratan hardware/modem

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

Selain itu, untuk mengintegrasikan dengan API eUICC di Android 9, modem perangkat harus mengirimkan kemampuan terminal dengan dukungan untuk kemampuan eUICC yang dienkode (pengelolaan profil lokal dan download profil). Aplikasi juga perlu mengimplementasikan 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 agar dapat mengizinkan download atau transfer eSIM hanya untuk operator yang diizinkan. Jika tidak, pengguna mungkin akan mendownload dan mentransfer SIM, lalu menyadari bahwa perangkat tersebut dikunci oleh operator ke operator lain.

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

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

Modem akan mengenali eSIM dengan profil booting default diaktifkan sebagai SIM yang valid dan pastikan SIM tetap aktif.

Untuk perangkat yang menjalankan Android 10, eUICC tidak dapat dilepas array ID slot 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 bisa diimplementasikan dalam APK): backend LPA, dan UI LPA atau LUI.

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

<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 dengan sesuai kebutuhan untuk mendukung Android eUICC API. PackageManager dikueri untuk semua aplikasi dengan izin android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS, yang menentukan layanan untuk tindakan android.service.euicc.EuiccService. Layanan dengan prioritas tertinggi akan dipilih. Jika tidak ada layanan yang ditemukan, LPA {i>support<i} dinonaktifkan.

Untuk menerapkan 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 intent dengan tindakan yang sesuai, kategori android.service.euicc.category.EUICC_UI, dan prioritas bukan nol. Logika serupa digunakan untuk memilih implementasi bagi aktivitas ini sebagai dengan memilih implementasi EuiccService Contoh:

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

Ini menyiratkan bahwa UI yang mengimplementasikan layar ini bisa berasal dari APK dari APK yang mengimplementasikan EuiccService Apakah memiliki satu atau beberapa APK (misalnya, APK yang mengimplementasikan EuiccService dan yang menyediakan aktivitas LUI) adalah pilihan desain.

Pengelola Kartu Euicc

EuiccCardManager adalah antarmuka untuk berkomunikasi dengan chip eSIM. Ini menyediakan fungsi ES10 (seperti 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 hak istimewa sistem aplikasi.

Aplikasi operator, LPA, dan Euicc API

Gambar 2. Aplikasi operator dan LPA sama-sama menggunakan Euicc API

API operasi profil melalui EuiccCardManager mengharuskan pemanggil sebuah LPA. Hal ini diberlakukan oleh framework Android. Ini berarti pemanggil harus memperluas EuiccService dan dideklarasikan dalam file manifes, seperti yang dijelaskan dalam bagian sebelumnya.

Serupa dengan EuiccManager, untuk menggunakan EuiccCardManager API, LPA Anda harus pertama-tama dapatkan 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 terikat ke EuiccCardController (yang berjalan di proses ponsel) melalui antarmuka AIDL, dan setiap metode EuiccCardManager menerima callback-nya dari proses telepon melalui AIDL khusus yang berbeda dalam antarmuka berbasis web yang sederhana. Saat menggunakan EuiccCardManager API, pemanggil (LPA) harus memberikan Executor tempat callback akan dipanggil. Objek Executor ini dapat berjalan di di satu thread atau pada kumpulan thread pilihan Anda.

Sebagian besar EuiccCardManager API memiliki pola penggunaan yang sama. Misalnya, untuk memuat terikat paket profil 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 peristiwa notifikasi tertentu:

...
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 yang lebih baru, Anda dapat menggunakan aplikasi operator untuk mengaktifkan eSIM dan download profil. Aplikasi operator dapat mendownload profil dengan menelepon downloadSubscription secara langsung atau dengan memberikan kode aktivasi ke LPA.

Saat aplikasi operator mendownload profil dengan memanggil downloadSubscription, panggilan memberlakukan bahwa aplikasi dapat mengelola profil melalui BF76 tag metadata yang mengenkode aturan hak istimewa operator untuk untuk profil. Jika profil tidak memiliki tag BF76 atau jika tag BF76-nya tidak memiliki tag cocok dengan tanda tangan aplikasi operator panggilan, download akan ditolak.

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

Aktifkan eSIM menggunakan kode aktivasi

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

Menentukan layanan penyediaan eUICC operator

LPA dan aplikasi operator berkomunikasi melalui dua AIDL antarmuka: ICarrierEuiccProvisioningService dan IGetActivationCodeCallback. Operator aplikasi harus mengimplementasikan antarmuka ICarrierEuiccProvisioningService dan mengeksposnya dalam pernyataan manifes. LPA harus terikat ke ICarrierEuiccProvisioningService dan mengimplementasikan IGetActivationCodeCallback. Untuk informasi selengkapnya tentang cara menerapkan dan mengekspos antarmuka AIDL, lihat Mendefinisikan dan antarmuka AIDL.

Untuk menentukan antarmuka AIDL, buat file AIDL berikut untuk aplikasi LPA dan 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 penerapan LPA

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

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

Setelah melakukan binding ke ICarrierEuiccProvisioningService aplikasi operator implementasi, LPA akan memanggil getActivationCode atau getActivationCodeForEid untuk mendapatkan kode aktivasi dari aplikasi operator dengan meneruskan implementasi class stub IGetActivationCodeCallback.

Perbedaan antara getActivationCode dan getActivationCodeForEid adalah getActivationCodeForEid memungkinkan operator mengikat profil terlebih dahulu ke EID sebelum proses download 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 mengikat ke aplikasi operator, aplikasi operator harus menyalin kedua ICarrierEuiccProvisioningService.aidl dan IGetActivationCodeCallback.aidl untuk project Anda dan deklarasikan layanan ICarrierEuiccProvisioningService di File AndroidManifest.xml. Layanan harus memerlukan Izin sistem android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS untuk memastikan sehingga hanya LPA, aplikasi dengan hak istimewa sistem, yang dapat mengikatnya. Layanan harus juga menyertakan filter intent 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 Stub dan menerapkan getActivationCode serta getActivationCodeForEid metode. LPA kemudian dapat memanggil salah satu metode untuk mengambil aktivasi profil pada kode sumber. Aplikasi operator harus merespons dengan memanggil IGetActivationCodeCallback#onSuccess dengan kode aktivasi jika kodenya berhasil diambil dari server operator. Jika gagal, aplikasi operator akan 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 yang lebih tinggi, LPA dapat memulai UI aplikasi operator. Hal ini berguna karena aplikasi operator mungkin memerlukan informasi tambahan dari sebelum memberikan kode aktivasi ke LPA. Misalnya, ekspedisi mungkin mengharuskan pengguna login untuk mengaktifkan nomor telepon atau melakukan transfer lainnya layanan IT perusahaan mereka.

Ini adalah proses untuk memulai UI aplikasi operator di LPA:

  1. LPA meluncurkan alur aktivasi aplikasi operator dengan mengirimkan android.service.euicc.action.START_CARRIER_ACTIVATION ke paket aplikasi operator yang berisi tindakan. (Penerima aplikasi operator harus dilindungi dalam deklarasi manifes dengan android:permission="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS" hingga menghindari penerimaan intent 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, mencatat pada 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, bukan membiarkan LPA mengikat operator aplikasi, aplikasi operator merespons LPA menggunakan setResult(int, Intent) dengan RESULT_OK dan instance Intent yang berisi tambahan boolean android.telephony.euicc.extra.USE_QR_SCANNER disetel ke true. LPA lalu memeriksa ekstra dan meluncurkan pemindai QR, bukan mengikat implementasi ICarrierEuiccProvisioningService aplikasi operator.
    2. Jika aplikasi operator mengalami error atau merespons dengan RESULT_CANCELED (ini adalah kode respons default), LPA akan membatalkan eSIM alur aktivasi.
    3. Jika aplikasi operator merespons dengan sesuatu selain RESULT_OK atau RESULT_CANCELED, LPA akan memperlakukannya sebagai error.

    Untuk alasan keamanan, LPA tidak boleh secara langsung menerima kode aktivasi yang diberikan dalam intent hasil untuk memastikan bahwa kode penelepon 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 eSIM aktivasi. Metode ini menampilkan UI alur aktivasi eSIM LPA untuk mengaktifkan profil eSIM. LPA kemudian mengirim siaran ketika profil eSIM aktivasi selesai.

  1. LPA harus mendeklarasikan aktivitas yang mencakup filter intent dengan Tindakan android.service.euicc.action.START_EUICC_ACTIVATION. Prioritas filter intent harus diatur ke nilai bukan nol jika beberapa implementasinya ada di perangkat. Contoh:

    <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, mencatat pada pengguna atau mengirim permintaan HTTP ke backend operator.

  3. Pada tahap ini, aplikasi operator harus siap untuk menyediakan aktivasi kode melalui implementasi ICarrierEuiccProvisioningService-nya. Tujuan aplikasi operator meluncurkan LPA dengan memanggil startActivityForResult(Intent, int) dengan android.telephony.euicc.action.START_EUICC_ACTIVATION tindakan. LPA juga memeriksa tambahan boolean android.telephony.euicc.extra.USE_QR_SCANNER. Jika nilainya true, parameter LPA meluncurkan pemindai QR agar pengguna dapat memindai kode QR profil.

  4. Di sisi LPA, LPA mengikat ke antarmuka aplikasi operator Implementasi ICarrierEuiccProvisioningService untuk mengambil aktivasi kode dan mendownload profil yang sesuai. LPA menampilkan semua data yang diperlukan Elemen UI selama proses download, seperti layar pemuatan.

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

    1. Jika LPA berhasil mendownload profil eSIM baru, merespons dengan RESULT_OK.
    2. Jika pengguna membatalkan aktivasi profil eSIM di LPA, merespons dengan RESULT_CANCELED.
    3. Jika LPA merespons dengan sesuatu selain RESULT_OK atau RESULT_CANCELED, aplikasi operator akan memperlakukan hal ini sebagai error.

    Untuk alasan keamanan, LPA tidak menerima kode aktivasi langsung di intent yang disediakan untuk memastikan bahwa pemanggil non-LPA tidak bisa kode aktivasi dari aplikasi operator.

Mendukung beberapa eSIM

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

Persyaratan

Untuk mendukung beberapa eSIM, perangkat harus memiliki lebih dari satu eUICC, yang dapat eUICC bawaan atau slot SIM fisik di mana eUICC yang dapat dilepas disisipkan.

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

Implementasi

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 oleh pemanggil.

Tujuan non_removable_euicc_slots resource yang ditetapkan dalam arrays.xml adalah array bilangan bulat yang mewakili ID slot dari sebuah perangkat eUICC. Anda harus menentukan resource 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 createForCardId di EuiccManager untuk membuat objek EuiccManager yang disematkan ke ID kartu yang diberikan. ID kartu adalah nilai bilangan bulat yang secara unik mengidentifikasi UICC atau eUICC pada perangkat.

Guna mendapatkan ID kartu untuk eUICC default perangkat, gunakan metode getCardIdForDefaultEuicc di TelephonyManager. Metode ini akan menampilkan UNSUPPORTED_CARD_ID jika versi HAL radio 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, serta getCardId di SubscriptionInfo.

Setelah instance objek EuiccManager dibuat dengan ID kartu tertentu, semua operasinya diarahkan ke eUICC dengan ID kartu tersebut. Jika eUICC menjadi tidak dapat dijangkau (misalnya saat dinonaktifkan atau dihapus) EuiccManager tidak lama bekerja.

Anda dapat menggunakan contoh kode berikut untuk membuat aplikasi operator.

Contoh 1: Mendapatkan langganan aktif dan membuat 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: Lakukan 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 build Android (tidak setiap ponsel mendukung eSIM). Sebagai alasan ini, tidak ada kasus tes CTS{i> <i}yang menyeluruh. Namun, kasus uji dasar tersedia di AOSP untuk memastikan eUICC API yang terekspos valid di build Android.

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

Operator yang menerapkan aplikasi operator harus melalui jaringan internal uji mutu untuk memastikan semua fitur yang diimplementasikan berfungsi seperti yang diharapkan. Di aplikasi operator harus dapat mencantumkan semua profil langganan dimiliki oleh operator yang sama, mendownload dan menginstal profil, mengaktifkan layanan di profil, berganti profil, dan menghapus profil.

Jika Anda membuat LPA sendiri, Anda harus melewati langkah yang jauh lebih ketat pengujian. Anda harus bekerja sama dengan vendor modem, chip eUICC, atau vendor OS eSIM, Vendor SM-DP+ dan operator untuk menyelesaikan masalah dan memastikan interoperabilitas LPA Anda dalam arsitektur RSP. Jumlah pengujian manual yang baik tidak terelakkan. Untuk cakupan pengujian terbaik, Anda harus mengikuti Rencana Pengujian RSP GSMA SGP.23.