• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2015, Motorola Mobility LLC
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *     - Redistributions of source code must retain the above copyright
8  *       notice, this list of conditions and the following disclaimer.
9  *     - Redistributions in binary form must reproduce the above copyright
10  *       notice, this list of conditions and the following disclaimer in the
11  *       documentation and/or other materials provided with the distribution.
12  *     - Neither the name of Motorola Mobility nor the
13  *       names of its contributors may be used to endorse or promote products
14  *       derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26  * DAMAGE.
27  */
28 
29 package com.android.service.ims;
30 
31 import android.content.Context;
32 import android.os.PersistableBundle;
33 import android.telephony.AccessNetworkConstants;
34 import android.telephony.CarrierConfigManager;
35 import android.telephony.SubscriptionInfo;
36 import android.telephony.SubscriptionManager;
37 import android.telephony.ims.ImsException;
38 import android.telephony.ims.ImsManager;
39 import android.telephony.ims.ImsMmTelManager;
40 import android.telephony.ims.ImsRcsManager;
41 import android.telephony.ims.ProvisioningManager;
42 import android.telephony.ims.feature.MmTelFeature;
43 import android.telephony.ims.stub.ImsRegistrationImplBase;
44 
45 import com.android.ims.internal.Logger;
46 
47 import java.util.List;
48 import java.util.concurrent.LinkedBlockingQueue;
49 import java.util.concurrent.TimeUnit;
50 
51 public class RcsSettingUtils {
52     static private Logger logger = Logger.getLogger("RcsSettingUtils");
53     private static final int TIMEOUT_GET_CONFIGURATION_MS = 5000;
54 
55     // Default number of entries for getMaxNumbersInRCL
56     private static final int DEFAULT_NUM_ENTRIES_IN_RCL = 100;
57     // Default for getCapabPollListSubExp in seconds.
58     private static final int DEFAULT_CAPABILITY_POLL_LIST_SUB_EXPIRATION_SEC = 30;
59     // Default for getAvailabilityCacheExpiration in seconds.
60     private static final int DEFAULT_AVAILABILITY_CACHE_EXPIRATION_SEC = 30;
61     // Default for getPublishThrottle in milliseconds
62     private static final int DEFAULT_PUBLISH_THROTTLE_MS = 60000;
63 
isVoLteProvisioned(int subId)64     public static boolean isVoLteProvisioned(int subId) {
65         try {
66             boolean isProvisioned;
67             ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
68             isProvisioned = manager.getProvisioningStatusForCapability(
69                     MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
70                     ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
71             logger.debug("isVoLteProvisioned=" + isProvisioned);
72             return isProvisioned;
73         } catch (Exception e) {
74             logger.debug("isVoLteProvisioned, exception = " + e.getMessage());
75             return false;
76         }
77     }
78 
isVowifiProvisioned(int subId)79     public static boolean isVowifiProvisioned(int subId) {
80         try {
81             boolean isProvisioned;
82             ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
83             isProvisioned = manager.getProvisioningStatusForCapability(
84                     MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
85                     ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN);
86             logger.debug("isVowifiProvisioned=" + isProvisioned);
87             return isProvisioned;
88         } catch (Exception e) {
89             logger.debug("isVowifiProvisioned, exception = " + e.getMessage());
90             return false;
91         }
92     }
93 
isLvcProvisioned(int subId)94     public static boolean isLvcProvisioned(int subId) {
95         try {
96             boolean isProvisioned;
97             ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
98             isProvisioned = manager.getProvisioningStatusForCapability(
99                     MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO,
100                     ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
101             logger.debug("isLvcProvisioned=" + isProvisioned);
102             return isProvisioned;
103         } catch (Exception e) {
104             logger.debug("isLvcProvisioned, exception = " + e.getMessage());
105             return false;
106         }
107     }
108 
isEabProvisioned(Context context, int subId)109     public static boolean isEabProvisioned(Context context, int subId) {
110         boolean isProvisioned = false;
111         if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
112             logger.debug("isEabProvisioned: no valid subscriptions!");
113             return false;
114         }
115         CarrierConfigManager configManager = (CarrierConfigManager)
116                 context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
117         if (configManager != null) {
118             PersistableBundle config = configManager.getConfigForSubId(subId);
119             if (config != null && !config.getBoolean(
120                     CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONED_BOOL)) {
121                 // If we don't need provisioning, just return true.
122                 return true;
123             }
124         }
125         try {
126             ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
127             isProvisioned = manager.getProvisioningIntValue(
128                     ProvisioningManager.KEY_EAB_PROVISIONING_STATUS)
129                     == ProvisioningManager.PROVISIONING_VALUE_ENABLED;
130         } catch (Exception e) {
131             logger.debug("isEabProvisioned: exception=" + e.getMessage());
132         }
133         logger.debug("isEabProvisioned=" + isProvisioned);
134         return isProvisioned;
135     }
136 
isPublishEnabled(Context context, int subId)137     public static boolean isPublishEnabled(Context context, int subId) {
138         if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
139             logger.debug("isPublishEnabled: no valid subscriptions!");
140             return false;
141         }
142         CarrierConfigManager configManager = (CarrierConfigManager)
143                 context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
144         if (configManager != null) {
145             PersistableBundle config = configManager.getConfigForSubId(subId);
146             return (config != null) && config.getBoolean(
147                     CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, false);
148         }
149         return false;
150     }
151 
hasUserEnabledContactDiscovery(Context context, int subId)152     public static boolean hasUserEnabledContactDiscovery(Context context, int subId) {
153         if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
154             logger.debug("hasUserEnabledContactDiscovery: no valid subscriptions!");
155             return false;
156         }
157         try {
158             ImsManager imsManager = context.getSystemService(ImsManager.class);
159             ImsRcsManager rcsManager = imsManager.getImsRcsManager(subId);
160             return rcsManager.getUceAdapter().isUceSettingEnabled();
161         } catch (Exception e) {
162             logger.warn("hasUserEnabledContactDiscovery: Exception = " + e.getMessage());
163             return false;
164         }
165     }
166 
getSIPT1Timer(int subId)167     public static int getSIPT1Timer(int subId) {
168         int sipT1Timer = 0;
169         try {
170             ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
171             sipT1Timer = manager.getProvisioningIntValue(ProvisioningManager.KEY_T1_TIMER_VALUE_MS);
172         } catch (Exception e) {
173             // If there is no active subscriptions, this will throw an exception.
174             logger.debug("getSIPT1Timer: exception=" + e.getMessage());
175         }
176         logger.debug("getSIPT1Timer=" + sipT1Timer);
177         return sipT1Timer;
178     }
179 
180     /**
181      * Capability discovery status of Enabled (1), or Disabled (0).
182      */
getCapabilityDiscoveryEnabled(int subId)183     public static boolean getCapabilityDiscoveryEnabled(int subId) {
184         boolean capabilityDiscoveryEnabled = false;
185         try {
186             ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
187             capabilityDiscoveryEnabled = manager.getProvisioningIntValue(
188                     ProvisioningManager.KEY_RCS_CAPABILITY_DISCOVERY_ENABLED) ==
189                     ProvisioningManager.PROVISIONING_VALUE_ENABLED;
190         } catch (Exception e) {
191             // If there is no active subscriptions, this will throw an exception.
192             logger.debug("capabilityDiscoveryEnabled: exception=" + e.getMessage());
193         }
194         logger.debug("capabilityDiscoveryEnabled=" + capabilityDiscoveryEnabled);
195         return capabilityDiscoveryEnabled;
196     }
197 
198     /**
199      * The Maximum number of MDNs contained in one Request Contained List.
200      */
getMaxNumbersInRCL(int subId)201     public static int getMaxNumbersInRCL(int subId) {
202         int maxNumbersInRCL = DEFAULT_NUM_ENTRIES_IN_RCL;
203         try {
204             ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
205             maxNumbersInRCL = manager.getProvisioningIntValue(
206                     ProvisioningManager.KEY_RCS_MAX_NUM_ENTRIES_IN_RCL);
207         } catch (Exception e) {
208             // If there is no active subscriptions, this will throw an exception.
209             logger.debug("getMaxNumbersInRCL: exception=" + e.getMessage());
210         }
211         logger.debug("getMaxNumbersInRCL=" + maxNumbersInRCL);
212         return maxNumbersInRCL;
213     }
214 
215     /**
216      * Expiration timer for subscription of a Request Contained List, used in capability polling.
217      */
getCapabPollListSubExp(int subId)218     public static int getCapabPollListSubExp(int subId) {
219         int capabPollListSubExp = DEFAULT_CAPABILITY_POLL_LIST_SUB_EXPIRATION_SEC;
220         try {
221             ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
222             capabPollListSubExp = manager.getProvisioningIntValue(
223                     ProvisioningManager.KEY_RCS_CAPABILITY_POLL_LIST_SUB_EXP_SEC);
224         } catch (Exception e) {
225             // If there is no active subscriptions, this will throw an exception.
226             logger.debug("getCapabPollListSubExp: exception=" + e.getMessage());
227         }
228         logger.debug("getCapabPollListSubExp=" + capabPollListSubExp);
229         return capabPollListSubExp;
230     }
231 
232     /**
233      * Period of time the availability information of a contact is cached on device.
234      */
getAvailabilityCacheExpiration(int subId)235     public static int getAvailabilityCacheExpiration(int subId) {
236         int availabilityCacheExpiration = DEFAULT_AVAILABILITY_CACHE_EXPIRATION_SEC;
237         try {
238             ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
239             availabilityCacheExpiration = manager.getProvisioningIntValue(
240                     ProvisioningManager.KEY_RCS_AVAILABILITY_CACHE_EXPIRATION_SEC);
241         } catch (Exception e) {
242             // If there is no active subscriptions, this will throw an exception.
243             logger.debug("getAvailabilityCacheExpiration: exception=" + e.getMessage());
244         }
245         logger.debug("getAvailabilityCacheExpiration=" + availabilityCacheExpiration);
246         return availabilityCacheExpiration;
247     }
248 
getPublishThrottle(int subId)249     public static int getPublishThrottle(int subId) {
250         // Default
251         int publishThrottle = DEFAULT_PUBLISH_THROTTLE_MS;
252         try {
253             ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
254             publishThrottle = manager.getProvisioningIntValue(
255                     ProvisioningManager.KEY_RCS_PUBLISH_SOURCE_THROTTLE_MS);
256         } catch (Exception e) {
257             // If there is no active subscriptions, this will throw an exception.
258             logger.debug("publishThrottle: exception=" + e.getMessage());
259         }
260         logger.debug("publishThrottle=" + publishThrottle);
261         return publishThrottle;
262     }
263 
isVtEnabledByUser(int subId)264     public static boolean isVtEnabledByUser(int subId) {
265         try {
266             ImsMmTelManager mmTelManager = ImsMmTelManager.createForSubscriptionId(subId);
267             return mmTelManager.isVtSettingEnabled();
268         } catch (Exception e) {
269             logger.warn("isVtEnabledByUser exception = " + e.getMessage());
270             return false;
271         }
272     }
273 
isWfcEnabledByUser(int subId)274     public static boolean isWfcEnabledByUser(int subId) {
275         try {
276             ImsMmTelManager mmTelManager = ImsMmTelManager.createForSubscriptionId(subId);
277         return mmTelManager.isVoWiFiSettingEnabled();
278         } catch (Exception e) {
279             logger.warn("isWfcEnabledByUser exception = " + e.getMessage());
280             return false;
281         }
282     }
283 
isAdvancedCallingEnabledByUser(int subId)284     public static boolean isAdvancedCallingEnabledByUser(int subId) {
285         try {
286             ImsMmTelManager mmTelManager = ImsMmTelManager.createForSubscriptionId(subId);
287             return mmTelManager.isAdvancedCallingSettingEnabled();
288         } catch (Exception e) {
289             logger.warn("isAdvancedCallingEnabledByUser exception = " + e.getMessage());
290             return false;
291         }
292     }
293 
isVoLteSupported(int subId)294     public static boolean isVoLteSupported(int subId) {
295         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
296             return false;
297         }
298         LinkedBlockingQueue<Boolean> resultQueue = new LinkedBlockingQueue<>(1);
299         try {
300             ImsMmTelManager mmTelManager = ImsMmTelManager.createForSubscriptionId(subId);
301             mmTelManager.isSupported(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
302                     AccessNetworkConstants.TRANSPORT_TYPE_WWAN, Runnable::run, resultQueue::offer);
303         } catch (ImsException e) {
304             logger.warn("isVoLteSupported: ImsException = " + e.getMessage());
305             return false;
306         }
307         try {
308             Boolean result = resultQueue.poll(TIMEOUT_GET_CONFIGURATION_MS, TimeUnit.MILLISECONDS);
309             return (result != null) ? result : false;
310         } catch (InterruptedException e) {
311             logger.warn("isVoLteSupported, InterruptedException=" + e.getMessage());
312             return false;
313         }
314     }
315 
isVoWiFiSupported(int subId)316     public static boolean isVoWiFiSupported(int subId) {
317         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
318             return false;
319         }
320         LinkedBlockingQueue<Boolean> resultQueue = new LinkedBlockingQueue<>(1);
321         try {
322             ImsMmTelManager mmTelManager = ImsMmTelManager.createForSubscriptionId(subId);
323             mmTelManager.isSupported(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
324                     AccessNetworkConstants.TRANSPORT_TYPE_WLAN, Runnable::run, resultQueue::offer);
325         } catch (ImsException e) {
326             logger.warn("isVoWiFiSupported: ImsException = " + e.getMessage());
327             return false;
328         }
329         try {
330             Boolean result = resultQueue.poll(TIMEOUT_GET_CONFIGURATION_MS, TimeUnit.MILLISECONDS);
331             return (result != null) ? result : false;
332         } catch (InterruptedException e) {
333             logger.warn("isVoWiFiSupported, InterruptedException=" + e.getMessage());
334             return false;
335         }
336     }
337 
isVtSupported(int subId)338     public static boolean isVtSupported(int subId) {
339         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
340             return false;
341         }
342         LinkedBlockingQueue<Boolean> resultQueue = new LinkedBlockingQueue<>(1);
343         try {
344             ImsMmTelManager mmTelManager = ImsMmTelManager.createForSubscriptionId(subId);
345             mmTelManager.isSupported(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO,
346                     AccessNetworkConstants.TRANSPORT_TYPE_WWAN, Runnable::run, resultQueue::offer);
347         } catch (ImsException e) {
348             logger.warn("isVoWiFiSupported: ImsException = " + e.getMessage());
349             return false;
350         }
351         try {
352             Boolean result = resultQueue.poll(TIMEOUT_GET_CONFIGURATION_MS, TimeUnit.MILLISECONDS);
353             return (result != null) ? result : false;
354         } catch (InterruptedException e) {
355             logger.warn("isVtSupported, InterruptedException=" + e.getMessage());
356             return false;
357         }
358     }
359 
getDefaultSubscriptionId(Context context)360     public static int getDefaultSubscriptionId(Context context) {
361         SubscriptionManager sm = context.getSystemService(SubscriptionManager.class);
362         if (sm == null) return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
363             List<SubscriptionInfo> infos = sm.getActiveSubscriptionInfoList();
364         if (infos == null || infos.isEmpty()) {
365             // There are no active subscriptions right now.
366             return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
367         }
368         // This code does not support MSIM unfortunately, so only provide presence on the default
369         // voice subscription that the user chose.
370         int defaultSub = SubscriptionManager.getDefaultVoiceSubscriptionId();
371         if (!SubscriptionManager.isValidSubscriptionId(defaultSub)) {
372             // The voice sub may not have been specified, in this case, use the default data.
373             defaultSub = SubscriptionManager.getDefaultDataSubscriptionId();
374         }
375         // If the user has no default set, just pick the first as backup.
376         if (!SubscriptionManager.isValidSubscriptionId(defaultSub)) {
377             for (SubscriptionInfo info : infos) {
378                 if (!info.isOpportunistic()) {
379                     defaultSub = info.getSubscriptionId();
380                     break;
381                 }
382             }
383         }
384         return defaultSub;
385     }
386 }
387 
388