Создание приложения для оператора – Часть 2

API eUICC в Android 9 позволяют операторам мобильной связи создавать приложения под брендом оператора для непосредственного управления своими профилями. Это включает в себя загрузку и удаление профилей подписки, принадлежащих перевозчику, а также переключение на профиль, принадлежащий перевозчику.

Создание приложения для оператора - Часть 2

EuiccManager

EuiccManagerявляется основной точкой входа для создание приложения для оператора с LPA. Это включает в себя приложения оператора, которые загружают, удаляют и переключаются на подписки, принадлежащие поставщику. Это также включает системное приложение LUI, которое предоставляет центральное местоположение / пользовательский интерфейс для управления всеми встроенными подписками, и может быть отдельным приложением от того, которое предоставляет EuiccService.

Чтобы использовать общедоступные API, приложение-носитель должно сначала получить экземпляр сEuiccManagerпомощью Context#getSystemService:

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

Вы должны проверить, поддерживается ли eSIM на устройстве, прежде чем выполнять какие-либо операции eSIM. EuiccManager#isEnabled()обычно возвращает true, если функция android.hardware.telephony.euicc определена и присутствует пакет LPA.

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

Чтобы получить информацию об оборудовании eUICC и версии ОС eSIM:

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

Многие API, такие как downloadSubscription()и switchToSubscription(), используютPendingIntentобратные вызовы, поскольку для их завершения могут потребоваться секунды или даже минуты. Он PendingIntentотправляется с результирующим кодом вEuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_пространстве, который предоставляет определяемые платформой коды ошибок, а также произвольный подробный результирующий код, распространяемый из LPA as EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, что позволяет приложению-поставщику отслеживать для целей регистрации / отладки. PendingIntent Должно быть BroadcastReceiver.

Чтобы загрузить данные DownloadableSubscription(созданные из кода активации или 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,
                     /* defaultValue*/);
                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);
PendingIntent callbackIntent = PendingIntent.getBroadcast(
        getContext(),  /* requestCode */, intent,
        PendingIntent.FLAG_UPDATE_CURRENT);
mgr.downloadSubscription(sub, true /* switchAfterDownload */,
        callbackIntent);

Чтобы перейти на подписку с указанным идентификатором подписки:

// 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,
                     /* 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);
PendingIntent callbackIntent = PendingIntent.getBroadcast(
        getContext(),  /* requestCode */, intent,
        PendingIntent.FLAG_UPDATE_CURRENT);
mgr.switchToSubscription(1 /* subscriptionId */, callbackIntent);

Полный список EuiccManagerAPI и примеры кода см. В разделе API eUICC .

Читать также:  Проверка - Часть 4

Разрешаемые ошибки

В некоторых случаях система не может завершить операцию eSIM, но ошибка может быть устранена пользователем. Например, downloadSubscription может произойти сбой, если метаданные профиля указывают, что требуется код подтверждения несущей . Или switchToSubscriptionможет произойти сбой, если приложение оператора связи имеет права оператора связи в профиле назначения (т. Е. У оператора есть профиль), но не имеет права оператора связи в текущем активированном профиле, и, следовательно, требуется согласие пользователя.

В этих случаях обратный вызов вызывающей стороны вызывается с помощьюEuiccManager#EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR. Обратный вызов Intentбудет содержать внутренние дополнения, так что когда вызывающий абонент передает егоEuiccManager#startResolutionActivity, разрешение может быть запрошено через LUI. EuiccManager#startResolutionActivity Повторное использование кода подтверждения, например,вызывает экран LUI, который позволяет пользователю ввести код подтверждения; после ввода кода операция загрузки возобновляется. Этот подход предоставляет приложению-носителю полный контроль над отображением пользовательского интерфейса, но дает LPA / LUI расширяемый метод для добавления новой обработки восстанавливаемых пользователем проблем в будущем без необходимости изменения клиентских приложений.

Android 9 определяет эти разрешимые ошибки EuiccService, которые должен обрабатывать 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 input carrier confirmation code. */
public static final String ACTION_RESOLVE_CONFIRMATION_CODE =
        "android.service.euicc.action.RESOLVE_CONFIRMATION_CODE";

Привилегии перевозчика

Если вы являетесь разработчиком, создающимся создание приложения для оператора, которое запрашивает EuiccManager загрузку профилей на устройство, ваш профиль должен включать в метаданные правила привилегий операторов, соответствующие вашему приложению. Это связано с тем, что в eUICC устройства могут сосуществовать профили подписки, принадлежащие разным носителям, и каждому приложению-носителю должен быть разрешен только доступ к профилям, принадлежащим этому носителю. Например, оператор связи А не должен иметь возможность загружать, включать или отключать профиль, принадлежащий оператору Б.

Читать также:  Требования к модему для поддержки eSIM - Часть 5

Чтобы гарантировать, что профиль доступен только его владельцу, Android использует механизм предоставления специальных привилегий приложению владельца профиля (то есть приложению-носителю). Платформа Android загружает сертификаты, хранящиеся в файле правил доступа (ARF) профиля, и предоставляет приложениям, подписанным этими сертификатами, разрешение на вызовы EuiccManagerAPI. Процесс высокого уровня описан ниже:

  1. Оператор подписывает приложение-носитель APK; apksigner инструмент прикрепляет сертификат открытого ключа в АПК.
  2. Оператор / SM-DP + подготавливает профиль и его метаданные, которые включают в себя ARF, который содержит:
    1. Подпись (SHA-1 или SHA-256) сертификата открытого ключа приложения-носителя (обязательно)
    2. Название пакета приложения-носителя (необязательно)
  3. Приложение Carrier пытается выполнить операцию eUICC через EuiccManagerAPI.
  4. Платформа Android проверяет, что хэш SHA-1 или SHA-256 сертификата приложения вызывающего абонента совпадает с подписью сертификата, полученного из ARF целевого профиля. Если имя пакета приложения-носителя включено в ARF, оно также должно совпадать с именем пакета приложения вызывающего абонента.
  5. После проверки подписи и имени пакета (если оно включено) привилегия оператора предоставляется приложению вызывающей стороны через целевой профиль.

Поскольку метаданные профиля могут быть доступны за пределами самого профиля (чтобы LPA мог получать метаданные профиля из SM-DP + до загрузки профиля или из ISD-R, когда профиль отключен), он должен содержать те же правила привилегий несущей. как в профиле.

Читать также:  Обзор платформы Twilio: цена и функциональные возможности

ОС eUICC и SM-DP + должны поддерживать собственный тег BF76 в метаданных профиля. Содержимое тега должно соответствовать тем же правилам привилегий оператора, что и ARA (апплет правила доступа), определенный в UICC Carrier Privileges :

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] BIT STRING (SIZE(8))  -- Tag DB
    }
}

Подробнее о подписи приложения см. В разделе « Подписать приложение» . Подробнее о привилегиях оператора см. В разделе « Права оператора UICC» .

Похожие публикации
Дата публикации:
Ссылка на основную публикацию