• 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.imsserviceentitlement.entitlement;
18 
19 import android.content.Context;
20 
21 import com.android.imsserviceentitlement.ts43.Ts43Constants.ResponseXmlAttributes;
22 import com.android.imsserviceentitlement.ts43.Ts43Constants.ResponseXmlNode;
23 import com.android.imsserviceentitlement.utils.XmlDoc;
24 import com.android.libraries.entitlement.ServiceEntitlement;
25 
26 import java.util.Optional;
27 import java.util.concurrent.TimeUnit;
28 
29 /** Provides the entitlement characteristic which stored from previous query. */
30 public class EntitlementConfiguration {
31     /** Default value of version for VERS characteristic. */
32     private static final int DEFAULT_VERSION = 0;
33     /** Default value of validity for VERS and TOKEN characteristics. */
34     private static final long DEFAULT_VALIDITY = 0;
35     /** Default value of VoLTE/VoWifi/SMSoverIP entitlemenet status. */
36     private static final int INCOMPATIBLE_STATE = 2;
37 
38     private final EntitlementConfigurationsDataStore mConfigurationsDataStore;
39 
40     private XmlDoc mXmlDoc = new XmlDoc(null);
41 
EntitlementConfiguration(Context context, int subId)42     public EntitlementConfiguration(Context context, int subId) {
43         mConfigurationsDataStore = EntitlementConfigurationsDataStore.getInstance(context, subId);
44         mConfigurationsDataStore.get().ifPresent(rawXml -> mXmlDoc = new XmlDoc(rawXml));
45     }
46 
47     /** Update VERS characteristics with given version and validity. */
update(String rawXml)48     public void update(String rawXml) {
49         mConfigurationsDataStore.set(rawXml);
50         mXmlDoc = new XmlDoc(rawXml);
51     }
52 
53     /**
54      * Returns VoLTE entitlement status from the {@link EntitlementConfigurationsDataStore}. If no
55      * data exist then return the default value {@link #INCOMPATIBLE_STATE}.
56      */
getVolteStatus()57     public int getVolteStatus() {
58         return mXmlDoc.get(
59                 ResponseXmlNode.APPLICATION,
60                 ResponseXmlAttributes.ENTITLEMENT_STATUS,
61                 ServiceEntitlement.APP_VOLTE)
62                 .map(Integer::parseInt)
63                 .orElse(INCOMPATIBLE_STATE);
64     }
65 
66     /**
67      * Returns VoWiFi entitlement status from the {@link EntitlementConfigurationsDataStore}. If no
68      * data exist then return the default value {@link #INCOMPATIBLE_STATE}.
69      */
getVoWifiStatus()70     public int getVoWifiStatus() {
71         return mXmlDoc.get(
72                 ResponseXmlNode.APPLICATION,
73                 ResponseXmlAttributes.ENTITLEMENT_STATUS,
74                 ServiceEntitlement.APP_VOWIFI)
75                 .map(Integer::parseInt)
76                 .orElse(INCOMPATIBLE_STATE);
77     }
78 
79     /**
80      * Returns SMSoIP entitlement status from the {@link EntitlementConfigurationsDataStore}. If no
81      * data exist then return the default value {@link #INCOMPATIBLE_STATE}.
82      */
getSmsOverIpStatus()83     public int getSmsOverIpStatus() {
84         return mXmlDoc.get(
85                 ResponseXmlNode.APPLICATION,
86                 ResponseXmlAttributes.ENTITLEMENT_STATUS,
87                 ServiceEntitlement.APP_SMSOIP)
88                 .map(Integer::parseInt)
89                 .orElse(INCOMPATIBLE_STATE);
90     }
91 
92     /**
93      * Returns token stored in the {@link EntitlementConfigurationsDataStore} if it is in validity
94      * period. Returns {@link Optional#empty()} if the token was expired or the value of token
95      * validity not positive.
96      */
getToken()97     public Optional<String> getToken() {
98         return isTokenInValidityPeriod()
99                 ? mXmlDoc.get(ResponseXmlNode.TOKEN, ResponseXmlAttributes.TOKEN, null)
100                 : Optional.empty();
101     }
102 
isTokenInValidityPeriod()103     private boolean isTokenInValidityPeriod() {
104         long queryTimeMillis = mConfigurationsDataStore.getQueryTimeMillis();
105         long tokenValidityMillis = TimeUnit.SECONDS.toMillis(getTokenValidity());
106 
107         if (queryTimeMillis <= 0) {
108             // False if the query time not been set.
109             return false;
110         }
111 
112         // When the token validity is set to 0, the Entitlement Client shall store the token without
113         // any limitation of duration.
114         if (tokenValidityMillis <= 0) {
115             return true;
116         }
117 
118         return (System.currentTimeMillis() - queryTimeMillis) < tokenValidityMillis;
119     }
120 
121     /**
122      * Returns the validity of the token, in seconds. The validity is counted from the time it is
123      * received by the client. If no data exist then returns default value 0.
124      */
getTokenValidity()125     public long getTokenValidity() {
126         return mXmlDoc.get(
127                 ResponseXmlNode.TOKEN,
128                 ResponseXmlAttributes.VALIDITY,
129                 null)
130                 .map(Long::parseLong)
131                 .orElse(DEFAULT_VALIDITY);
132     }
133 
134     /**
135      * Returns version stored in the {@link EntitlementCharacteristicDataStore}.
136      * If no data exists then return the default value {@link #DEFAULT_VERSION}.
137      */
getVersion()138     public String getVersion() {
139         return mXmlDoc.get(ResponseXmlNode.VERS, ResponseXmlAttributes.VERSION, null)
140                 .orElse(String.valueOf(DEFAULT_VERSION));
141     }
142 
143     /**
144      * Returns the validity of the version, in seconds. The validity is counted from the time it is
145      * received by the client. If no data exist then returns default value 0.
146      */
getVersValidity()147     public long getVersValidity() {
148         return mXmlDoc.get(
149                 ResponseXmlNode.VERS,
150                 ResponseXmlAttributes.VALIDITY,
151                 null)
152                 .map(Long::parseLong)
153                 .orElse(DEFAULT_VALIDITY);
154     }
155 
156     public enum ClientBehavior {
157         /** Unknown behavior. */
158         UNKNOWN_BEHAVIOR,
159         /** Entitlement data is valid during validity seconds. */
160         VALID_DURING_VALIDITY,
161         /** Entitlement data is valid without any limitation of duration. */
162         VALID_WITHOUT_DURATION,
163         /** Entitlement data has to be reset to default configuration */
164         NEEDS_TO_RESET,
165         /**
166          * Entitlement data has to be reset to default configuration except for version and
167          * validity. The Entitlement Client shall not perform client configuration requests anymore
168          * for the services just configured.
169          */
170         NEEDS_TO_RESET_EXCEPT_VERS,
171         /**
172          * entitlement data has to be reset to default configuration except for version and
173          * validity. The Entitlement Client shall not perform client configuration requests anymore
174          * for the services just configured, until the end-user switches the setting to On.
175          */
176         NEEDS_TO_RESET_EXCEPT_VERS_UNTIL_SETTING_ON,
177     }
178 
179     /** Returns {@link ClientBehavior} for the service to be configured. */
entitlementValidation()180     public ClientBehavior entitlementValidation() {
181         int version = mXmlDoc.get(
182                 ResponseXmlNode.VERS,
183                 ResponseXmlAttributes.VERSION,
184                 null)
185                 .map(Integer::parseInt)
186                 .orElse(DEFAULT_VERSION);
187         long validity = mXmlDoc.get(
188                 ResponseXmlNode.VERS,
189                 ResponseXmlAttributes.VALIDITY,
190                 null)
191                 .map(Long::parseLong)
192                 .orElse(DEFAULT_VALIDITY);
193 
194         if (version > 0 && validity > 0) {
195             return ClientBehavior.VALID_DURING_VALIDITY;
196         } else if (version > 0 && validity == 0) {
197             return ClientBehavior.VALID_WITHOUT_DURATION;
198         } else if (version == 0 && validity == 0) {
199             return ClientBehavior.NEEDS_TO_RESET;
200         } else if (version == -1 && validity == -1) {
201             return ClientBehavior.NEEDS_TO_RESET_EXCEPT_VERS;
202         } else if (version == -2 && validity == -2) {
203             return ClientBehavior.NEEDS_TO_RESET_EXCEPT_VERS_UNTIL_SETTING_ON;
204         }
205 
206         // Should never reach.
207         return ClientBehavior.UNKNOWN_BEHAVIOR;
208     }
209 
210     /**
211      * Removes the stored configuration and reverts to the default configuration when:
212      * <ul>
213      *   <li>on SIM card change
214      *   <li>on menu Factory reset
215      *   <li>if a service is barred by the Service Provider (i.e. configuration version set to 0,
216      *       -1, -2). In that case, version and validity are not reset
217      * </ul>
218      */
reset()219     public void reset() {
220         // Default configuration of the Characteristics:
221         //   - VERS.version = 0
222         //   - VERS.validity = 0
223         //   - TOKEN.token = null (i.e. no value assigned)
224         //   - TOKEN.validity =0
225         //   - VoLTE.EntitlementStatus=2 (INCOMPATIBLE_STATE)
226         //   - VoWiFi.EntitlementStatus=2 (INCOMPATIBLE_STATE)
227         //   - SMSoIP.EntitlementStatus=2 (INCOMPATIBLE_STATE)
228         update(null);
229     }
230 
231     /** Reverts to the default configurations except the version and validity. */
resetConfigsExceptVers()232     public void resetConfigsExceptVers() {
233         String rawXml =
234                 "<wap-provisioningdoc version=\"1.1\">"
235                 + "  <characteristic type=\"VERS\">"
236                 + "    <parm name=\"version\" value=\"" + getVersion() + "\"/>"
237                 + "    <parm name=\"validity\" value=\"" + getVersValidity() + "\"/>"
238                 + "  </characteristic>"
239                 + "  <characteristic type=\"TOKEN\">"
240                 + "    <parm name=\"token\" value=\"\"/>"
241                 + "    <parm name=\"validity\" value=\"0\"/>"
242                 + "  </characteristic>"
243                 + "  <characteristic type=\"APPLICATION\">"
244                 + "    <parm name=\"AppID\" value=\"ap2003\"/>"
245                 + "    <parm name=\"EntitlementStatus\" value=\"2\"/>"
246                 + "  </characteristic>"
247                 + "  <characteristic type=\"APPLICATION\">"
248                 + "    <parm name=\"AppID\" value=\"ap2004\"/>"
249                 + "    <parm name=\"EntitlementStatus\" value=\"2\"/>"
250                 + "  </characteristic>"
251                 + "  <characteristic type=\"APPLICATION\">"
252                 + "    <parm name=\"AppID\" value=\"ap2005\"/>"
253                 + "    <parm name=\"EntitlementStatus\" value=\"2\"/>"
254                 + "  </characteristic>"
255                 + "</wap-provisioningdoc>";
256         update(rawXml);
257     }
258 }
259