1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.libraries.entitlement; 18 19 import android.content.Context; 20 21 import androidx.annotation.Nullable; 22 import androidx.annotation.VisibleForTesting; 23 24 import com.android.libraries.entitlement.eapaka.EapAkaApi; 25 26 import com.google.common.collect.ImmutableList; 27 28 /** 29 * Implemnets protocol for carrier service entitlement configuration query and operation, based on 30 * GSMA TS.43 spec. 31 */ 32 public class ServiceEntitlement { 33 /** 34 * App ID for Voice-Over-LTE entitlement. 35 */ 36 public static final String APP_VOLTE = "ap2003"; 37 /** 38 * App ID for Voice-Over-WiFi entitlement. 39 */ 40 public static final String APP_VOWIFI = "ap2004"; 41 /** 42 * App ID for SMS-Over-IP entitlement. 43 */ 44 public static final String APP_SMSOIP = "ap2005"; 45 /** 46 * App ID for on device service activation (OSDA) for companion device. 47 */ 48 public static final String APP_ODSA_COMPANION = "ap2006"; 49 /** 50 * App ID for on device service activation (OSDA) for primary device. 51 */ 52 public static final String APP_ODSA_PRIMARY = "ap2009"; 53 54 private final CarrierConfig carrierConfig; 55 private final EapAkaApi eapAkaApi; 56 57 /** 58 * Creates an instance for service entitlement configuration query and operation for the 59 * carrier. 60 * 61 * @param context context of application 62 * @param carrierConfig carrier specific configs used in the queries and operations. 63 * @param simSubscriptionId the subscroption ID of the carrier's SIM on device. This indicates 64 * which SIM to retrieve IMEI/IMSI from and perform EAP-AKA 65 * authentication with. See 66 * {@link android.telephony.SubscriptionManager} 67 * for how to get the subscroption ID. 68 */ ServiceEntitlement(Context context, CarrierConfig carrierConfig, int simSubscriptionId)69 public ServiceEntitlement(Context context, CarrierConfig carrierConfig, int simSubscriptionId) { 70 this.carrierConfig = carrierConfig; 71 this.eapAkaApi = new EapAkaApi(context, simSubscriptionId); 72 } 73 74 @VisibleForTesting ServiceEntitlement(CarrierConfig carrierConfig, EapAkaApi eapAkaApi)75 ServiceEntitlement(CarrierConfig carrierConfig, EapAkaApi eapAkaApi) { 76 this.carrierConfig = carrierConfig; 77 this.eapAkaApi = eapAkaApi; 78 } 79 80 /** 81 * Retrieves service entitlement configuration. For on device service activation (ODSA) of eSIM 82 * for companion/primary devices, use {@link #performEsimOdsa} instead. 83 * 84 * <p>Supported {@code appId}: {@link #APP_VOLTE}, {@link #APP_VOWIFI}, {@link #APP_SMSOIP}. 85 * 86 * <p>This method sends an HTTP GET request to entitlement server, responds to EAP-AKA 87 * challenge if needed, and returns the raw configuration doc as a string. The following 88 * parameters are set in the HTTP request: 89 * 90 * <ul> 91 * <li>"app": {@code appId} 92 * <li>"vers": 0, or {@code request.configurationVersion()} if it's not 0. 93 * <li>"entitlement_version": "2.0", or {@code request.entitlementVersion()} if it's not empty. 94 * <li>"token": not set, or {@code request.authenticationToken()} if it's not empty. 95 * <li>"IMSI": if "token" is set, set to {@link android.telephony.TelephonyManager#getImei}. 96 * <li>"EAP_ID": if "token" is not set, set this parameter to trigger embedded EAP-AKA 97 * authentication as decribed in TS.43 section 2.6.1. Its value is derived from IMSI as per 98 * GSMA spec RCC.14 section C.2. 99 * <li>"terminal_id": IMEI, or {@code request.terminalId()} if it's not empty. 100 * <li>"terminal_vendor": {@link android.os.Build#MANUFACTURER}, or {@code 101 * request.terminalVendor()} if it's not empty. 102 * <li>"terminal_model": {@link android.os.Build#MODEL}, or {@code request.terminalModel()} if 103 * it's not empty. 104 * <li>"terminal_sw_version": {@llink android.os.Build.VERSION#BASE_OS}, or {@code 105 * request.terminalSoftwareVersion()} if it's not empty. 106 * <li>"app_name": not set, or {@code request.appName()} if it's not empty. 107 * <li>"app_version": not set, or {@code request.appVersion()} if it's not empty. 108 * <li>"notif_token": not set, or {@code request.notificationToken()} if it's not empty. 109 * <li>"notif_action": {@code request.notificationAction()} if "notif_token" is set, otherwise 110 * not set. 111 * </ul> 112 * 113 * <p>Requires permission: READ_PRIVILEGED_PHONE_STATE, or carrier privilege. 114 * 115 * @param appId an app ID string defined in TS.43 section 2.2, e.g. {@link #APP_VOWIFI}. 116 * @param request contains parameters that can be used in the HTTP request. 117 */ 118 @Nullable queryEntitlementStatus(String appId, ServiceEntitlementRequest request)119 public String queryEntitlementStatus(String appId, ServiceEntitlementRequest request) 120 throws ServiceEntitlementException { 121 return eapAkaApi.queryEntitlementStatus(ImmutableList.of(appId), carrierConfig, request); 122 } 123 124 /** 125 * Retrieves service entitlement configurations for multiple app IDs in one HTTP 126 * request/response. For on device service activation (ODSA) of eSIM for companion/primary 127 * devices, use {@link #performEsimOdsa} instead. 128 * 129 * <p>Same with {@link #queryEntitlementStatus(String, ServiceEntitlementRequest)} except that 130 * multiple "app" parameters will be set in the HTTP request, in the order as they appear in 131 * parameter {@code appIds}. 132 */ queryEntitlementStatus(ImmutableList<String> appIds, ServiceEntitlementRequest request)133 public String queryEntitlementStatus(ImmutableList<String> appIds, 134 ServiceEntitlementRequest request) 135 throws ServiceEntitlementException { 136 return eapAkaApi.queryEntitlementStatus(appIds, carrierConfig, request); 137 } 138 139 /** 140 * Performs on device service activation (ODSA) of eSIM for companion/primary devices. 141 * 142 * <p>Supported {@code appId}: {@link #APP_ODSA_COMPANION}, {@link #APP_ODSA_PRIMARY}. 143 * 144 * <p>Similar to {@link #queryEntitlementStatus(String, ServiceEntitlementRequest)}, this 145 * method sends an HTTP GET request to entitlement server, responds to EAP-AKA challenge if 146 * needed, and returns the raw configuration doc as a string. Additional parameters from {@code 147 * operation} are set to the HTTP request. See {@link EsimOdsaOperation} for details. 148 */ performEsimOdsa( String appId, ServiceEntitlementRequest request, EsimOdsaOperation operation)149 public String performEsimOdsa( 150 String appId, ServiceEntitlementRequest request, EsimOdsaOperation operation) 151 throws ServiceEntitlementException { 152 return eapAkaApi.performEsimOdsaOperation(appId, carrierConfig, request, operation); 153 } 154 } 155