• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 import java.util.List;
29 
30 /**
31  * Implemnets protocol for carrier service entitlement configuration query and operation, based on
32  * GSMA TS.43 spec.
33  */
34 public class ServiceEntitlement {
35     /**
36      * App ID for Voice-Over-LTE entitlement.
37      */
38     public static final String APP_VOLTE = "ap2003";
39     /**
40      * App ID for Voice-Over-WiFi entitlement.
41      */
42     public static final String APP_VOWIFI = "ap2004";
43     /**
44      * App ID for SMS-Over-IP entitlement.
45      */
46     public static final String APP_SMSOIP = "ap2005";
47     /**
48      * App ID for on device service activation (OSDA) for companion device.
49      */
50     public static final String APP_ODSA_COMPANION = "ap2006";
51     /**
52      * App ID for on device service activation (OSDA) for primary device.
53      */
54     public static final String APP_ODSA_PRIMARY = "ap2009";
55     /**
56      * App ID for data plan information entitlement.
57      */
58     public static final String APP_DATA_PLAN_BOOST = "ap2010";
59 
60     private final CarrierConfig carrierConfig;
61     private final EapAkaApi eapAkaApi;
62 
63     /**
64      * Creates an instance for service entitlement configuration query and operation for the
65      * carrier.
66      *
67      * @param context           context of application
68      * @param carrierConfig     carrier specific configs used in the queries and operations.
69      * @param simSubscriptionId the subscroption ID of the carrier's SIM on device. This indicates
70      *                          which SIM to retrieve IMEI/IMSI from and perform EAP-AKA
71      *                          authentication with. See
72      *                          {@link android.telephony.SubscriptionManager}
73      *                          for how to get the subscroption ID.
74      */
ServiceEntitlement(Context context, CarrierConfig carrierConfig, int simSubscriptionId)75     public ServiceEntitlement(Context context, CarrierConfig carrierConfig, int simSubscriptionId) {
76         this(
77                 context,
78                 carrierConfig,
79                 simSubscriptionId,
80                 /* saveHttpHistory= */ false,
81                 /* bypassEapAkaResponse= */ "");
82     }
83 
84     /**
85      * Creates an instance for service entitlement configuration query and operation for the
86      * carrier.
87      *
88      * @param context context of application
89      * @param carrierConfig carrier specific configs used in the queries and operations.
90      * @param simSubscriptionId the subscroption ID of the carrier's SIM on device. This indicates
91      *     which SIM to retrieve IMEI/IMSI from and perform EAP-AKA authentication with. See {@link
92      *     android.telephony.SubscriptionManager} for how to get the subscroption ID.
93      * @param saveHttpHistory set to {@code true} to save the history of request and response which
94      *     can later be retrieved by {@code getHistory()}. Intended for debugging.
95      */
ServiceEntitlement( Context context, CarrierConfig carrierConfig, int simSubscriptionId, boolean saveHttpHistory)96     public ServiceEntitlement(
97             Context context,
98             CarrierConfig carrierConfig,
99             int simSubscriptionId,
100             boolean saveHttpHistory) {
101         this(
102                 context,
103                 carrierConfig,
104                 simSubscriptionId,
105                 saveHttpHistory,
106                 /* bypassEapAkaResponse= */ "");
107     }
108 
109     /**
110      * Creates an instance for service entitlement configuration query and operation for the
111      * carrier.
112      *
113      * @param context context of application
114      * @param carrierConfig carrier specific configs used in the queries and operations.
115      * @param simSubscriptionId the subscroption ID of the carrier's SIM on device. This indicates
116      *     which SIM to retrieve IMEI/IMSI from and perform EAP-AKA authentication with. See {@link
117      *     android.telephony.SubscriptionManager} for how to get the subscroption ID.
118      * @param saveHttpHistory set to {@code true} to save the history of request and response which
119      *     can later be retrieved by {@code getHistory()}. Intended for debugging.
120      * @param bypassEapAkaResponse set to non empty string to bypass EAP-AKA authentication.
121      *     The client will accept any challenge from the server and return this string as a
122      *     response. Must not be {@code null}. Intended for testing.
123      */
ServiceEntitlement( Context context, CarrierConfig carrierConfig, int simSubscriptionId, boolean saveHttpHistory, String bypassEapAkaResponse)124     public ServiceEntitlement(
125             Context context,
126             CarrierConfig carrierConfig,
127             int simSubscriptionId,
128             boolean saveHttpHistory,
129             String bypassEapAkaResponse) {
130         this.carrierConfig = carrierConfig;
131         this.eapAkaApi =
132                 new EapAkaApi(context, simSubscriptionId, saveHttpHistory, bypassEapAkaResponse);
133     }
134 
135     @VisibleForTesting
ServiceEntitlement(CarrierConfig carrierConfig, EapAkaApi eapAkaApi)136     ServiceEntitlement(CarrierConfig carrierConfig, EapAkaApi eapAkaApi) {
137         this.carrierConfig = carrierConfig;
138         this.eapAkaApi = eapAkaApi;
139     }
140 
141     /**
142      * Retrieves service entitlement configuration. For on device service activation (ODSA) of eSIM
143      * for companion/primary devices, use {@link #performEsimOdsa} instead.
144      *
145      * <p>Supported {@code appId}: {@link #APP_VOLTE}, {@link #APP_VOWIFI}, {@link #APP_SMSOIP}.
146      *
147      * <p>This method sends an HTTP GET request to entitlement server, responds to EAP-AKA
148      * challenge if needed, and returns the raw configuration doc as a string. The following
149      * parameters are set in the HTTP request:
150      *
151      * <ul>
152      * <li>"app": {@code appId}
153      * <li>"vers": 0, or {@code request.configurationVersion()} if it's not 0.
154      * <li>"entitlement_version": "2.0", or {@code request.entitlementVersion()} if it's not empty.
155      * <li>"token": not set, or {@code request.authenticationToken()} if it's not empty.
156      * <li>"IMSI": if "token" is set, set to {@link android.telephony.TelephonyManager#getImei}.
157      * <li>"EAP_ID": if "token" is not set, set this parameter to trigger embedded EAP-AKA
158      * authentication as decribed in TS.43 section 2.6.1. Its value is derived from IMSI as per
159      * GSMA spec RCC.14 section C.2.
160      * <li>"terminal_id": IMEI, or {@code request.terminalId()} if it's not empty.
161      * <li>"terminal_vendor": {@link android.os.Build#MANUFACTURER}, or {@code
162      * request.terminalVendor()} if it's not empty.
163      * <li>"terminal_model": {@link android.os.Build#MODEL}, or {@code request.terminalModel()} if
164      * it's not empty.
165      * <li>"terminal_sw_version": {@llink android.os.Build.VERSION#BASE_OS}, or {@code
166      * request.terminalSoftwareVersion()} if it's not empty.
167      * <li>"app_name": not set, or {@code request.appName()} if it's not empty.
168      * <li>"app_version": not set, or {@code request.appVersion()} if it's not empty.
169      * <li>"notif_token": not set, or {@code request.notificationToken()} if it's not empty.
170      * <li>"notif_action": {@code request.notificationAction()} if "notif_token" is set, otherwise
171      * not set.
172      * </ul>
173      *
174      * <p>Requires permission: READ_PRIVILEGED_PHONE_STATE, or carrier privilege.
175      *
176      * @param appId   an app ID string defined in TS.43 section 2.2, e.g. {@link #APP_VOWIFI}.
177      * @param request contains parameters that can be used in the HTTP request.
178      */
179     @Nullable
queryEntitlementStatus(String appId, ServiceEntitlementRequest request)180     public String queryEntitlementStatus(String appId, ServiceEntitlementRequest request)
181             throws ServiceEntitlementException {
182         return eapAkaApi.queryEntitlementStatus(ImmutableList.of(appId), carrierConfig, request);
183     }
184 
185     /**
186      * Retrieves service entitlement configurations for multiple app IDs in one HTTP
187      * request/response. For on device service activation (ODSA) of eSIM for companion/primary
188      * devices, use {@link #performEsimOdsa} instead.
189      *
190      * <p>Same with {@link #queryEntitlementStatus(String, ServiceEntitlementRequest)} except that
191      * multiple "app" parameters will be set in the HTTP request, in the order as they appear in
192      * parameter {@code appIds}.
193      */
queryEntitlementStatus(ImmutableList<String> appIds, ServiceEntitlementRequest request)194     public String queryEntitlementStatus(ImmutableList<String> appIds,
195             ServiceEntitlementRequest request)
196             throws ServiceEntitlementException {
197         return eapAkaApi.queryEntitlementStatus(appIds, carrierConfig, request);
198     }
199 
200     /**
201      * Performs on device service activation (ODSA) of eSIM for companion/primary devices.
202      *
203      * <p>Supported {@code appId}: {@link #APP_ODSA_COMPANION}, {@link #APP_ODSA_PRIMARY}.
204      *
205      * <p>Similar to {@link #queryEntitlementStatus(String, ServiceEntitlementRequest)}, this
206      * method sends an HTTP GET request to entitlement server, responds to EAP-AKA challenge if
207      * needed, and returns the raw configuration doc as a string. Additional parameters from {@code
208      * operation} are set to the HTTP request. See {@link EsimOdsaOperation} for details.
209      */
performEsimOdsa( String appId, ServiceEntitlementRequest request, EsimOdsaOperation operation)210     public String performEsimOdsa(
211             String appId, ServiceEntitlementRequest request, EsimOdsaOperation operation)
212             throws ServiceEntitlementException {
213         return eapAkaApi.performEsimOdsaOperation(appId, carrierConfig, request, operation);
214     }
215 
216     /**
217      * Retrieves the history of past HTTP request and responses if {@code saveHttpHistory} was set
218      * in constructor.
219      */
getHistory()220     public List<String> getHistory() {
221         return eapAkaApi.getHistory();
222     }
223 
224     /**
225      * Clears the history of past HTTP request and responses.
226      */
clearHistory()227     public void clearHistory() {
228         eapAkaApi.clearHistory();
229     }
230 }
231