• 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 import com.android.internal.telephony.flags.Flags;
47 
48 import java.util.List;
49 import java.util.concurrent.LinkedBlockingQueue;
50 import java.util.concurrent.TimeUnit;
51 
52 public class RcsSettingUtils {
53     static private Logger logger = Logger.getLogger("RcsSettingUtils");
54     private static final int TIMEOUT_GET_CONFIGURATION_MS = 5000;
55 
56     // Default number of entries for getMaxNumbersInRCL
57     private static final int DEFAULT_NUM_ENTRIES_IN_RCL = 100;
58     // Default for getCapabPollListSubExp in seconds.
59     private static final int DEFAULT_CAPABILITY_POLL_LIST_SUB_EXPIRATION_SEC = 30;
60     // Default for getAvailabilityCacheExpiration in seconds.
61     private static final int DEFAULT_AVAILABILITY_CACHE_EXPIRATION_SEC = 30;
62     // Default for getPublishThrottle in milliseconds
63     private static final int DEFAULT_PUBLISH_THROTTLE_MS = 60000;
64 
isVoLteProvisioned(int subId)65     public static boolean isVoLteProvisioned(int subId) {
66         try {
67             boolean isProvisioned;
68             ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
69             isProvisioned = manager.getProvisioningStatusForCapability(
70                     MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
71                     ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
72             logger.debug("isVoLteProvisioned=" + isProvisioned);
73             return isProvisioned;
74         } catch (Exception e) {
75             logger.debug("isVoLteProvisioned, exception = " + e.getMessage());
76             return false;
77         }
78     }
79 
isVowifiProvisioned(int subId)80     public static boolean isVowifiProvisioned(int subId) {
81         try {
82             boolean isProvisioned;
83             ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
84             isProvisioned = manager.getProvisioningStatusForCapability(
85                     MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
86                     ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN);
87             logger.debug("isVowifiProvisioned=" + isProvisioned);
88             return isProvisioned;
89         } catch (Exception e) {
90             logger.debug("isVowifiProvisioned, exception = " + e.getMessage());
91             return false;
92         }
93     }
94 
isLvcProvisioned(int subId)95     public static boolean isLvcProvisioned(int subId) {
96         try {
97             boolean isProvisioned;
98             ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
99             isProvisioned = manager.getProvisioningStatusForCapability(
100                     MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO,
101                     ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
102             logger.debug("isLvcProvisioned=" + isProvisioned);
103             return isProvisioned;
104         } catch (Exception e) {
105             logger.debug("isLvcProvisioned, exception = " + e.getMessage());
106             return false;
107         }
108     }
109 
isEabProvisioned(Context context, int subId)110     public static boolean isEabProvisioned(Context context, int subId) {
111         boolean isProvisioned = false;
112         if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
113             logger.debug("isEabProvisioned: no valid subscriptions!");
114             return false;
115         }
116         CarrierConfigManager configManager = (CarrierConfigManager)
117                 context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
118         if (configManager != null) {
119             PersistableBundle config = configManager.getConfigForSubId(subId);
120             if (config != null && !config.getBoolean(
121                     CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONED_BOOL)) {
122                 // If we don't need provisioning, just return true.
123                 return true;
124             }
125         }
126         try {
127             ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
128             isProvisioned = manager.getRcsProvisioningStatusForCapability(
129                     ImsRcsManager.CAPABILITY_TYPE_PRESENCE_UCE,
130                     ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
131         } catch (Exception e) {
132             logger.debug("isEabProvisioned: exception=" + e.getMessage());
133         }
134         logger.debug("isEabProvisioned=" + isProvisioned);
135         return isProvisioned;
136     }
137 
isPublishEnabled(Context context, int subId)138     public static boolean isPublishEnabled(Context context, int subId) {
139         if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
140             logger.debug("isPublishEnabled: no valid subscriptions!");
141             return false;
142         }
143         CarrierConfigManager configManager = (CarrierConfigManager)
144                 context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
145         if (configManager != null) {
146             PersistableBundle config = configManager.getConfigForSubId(subId);
147             return (config != null) && config.getBoolean(
148                     CarrierConfigManager.Ims.KEY_ENABLE_PRESENCE_PUBLISH_BOOL, false);
149         }
150         return false;
151     }
152 
hasUserEnabledContactDiscovery(Context context, int subId)153     public static boolean hasUserEnabledContactDiscovery(Context context, int subId) {
154         if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
155             logger.debug("hasUserEnabledContactDiscovery: no valid subscriptions!");
156             return false;
157         }
158         try {
159             ImsManager imsManager = context.getSystemService(ImsManager.class);
160             ImsRcsManager rcsManager = imsManager.getImsRcsManager(subId);
161             return rcsManager.getUceAdapter().isUceSettingEnabled();
162         } catch (Exception e) {
163             logger.warn("hasUserEnabledContactDiscovery: Exception = " + e.getMessage());
164             return false;
165         }
166     }
167 
getSIPT1Timer(int subId)168     public static int getSIPT1Timer(int subId) {
169         int sipT1Timer = 0;
170         try {
171             ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
172             sipT1Timer = manager.getProvisioningIntValue(ProvisioningManager.KEY_T1_TIMER_VALUE_MS);
173         } catch (Exception e) {
174             // If there is no active subscriptions, this will throw an exception.
175             logger.debug("getSIPT1Timer: exception=" + e.getMessage());
176         }
177         logger.debug("getSIPT1Timer=" + sipT1Timer);
178         return sipT1Timer;
179     }
180 
181     /**
182      * Capability discovery status of Enabled (1), or Disabled (0).
183      */
getCapabilityDiscoveryEnabled(int subId)184     public static boolean getCapabilityDiscoveryEnabled(int subId) {
185         boolean capabilityDiscoveryEnabled = false;
186         try {
187             ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
188             capabilityDiscoveryEnabled = manager.getProvisioningIntValue(
189                     ProvisioningManager.KEY_RCS_CAPABILITY_DISCOVERY_ENABLED) ==
190                     ProvisioningManager.PROVISIONING_VALUE_ENABLED;
191         } catch (Exception e) {
192             // If there is no active subscriptions, this will throw an exception.
193             logger.debug("capabilityDiscoveryEnabled: exception=" + e.getMessage());
194         }
195         logger.debug("capabilityDiscoveryEnabled=" + capabilityDiscoveryEnabled);
196         return capabilityDiscoveryEnabled;
197     }
198 
199     /**
200      * The Maximum number of MDNs contained in one Request Contained List.
201      */
getMaxNumbersInRCL(int subId)202     public static int getMaxNumbersInRCL(int subId) {
203         int maxNumbersInRCL = DEFAULT_NUM_ENTRIES_IN_RCL;
204         try {
205             ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
206             maxNumbersInRCL = manager.getProvisioningIntValue(
207                     ProvisioningManager.KEY_RCS_MAX_NUM_ENTRIES_IN_RCL);
208         } catch (Exception e) {
209             // If there is no active subscriptions, this will throw an exception.
210             logger.debug("getMaxNumbersInRCL: exception=" + e.getMessage());
211         }
212         logger.debug("getMaxNumbersInRCL=" + maxNumbersInRCL);
213         return maxNumbersInRCL;
214     }
215 
216     /**
217      * Expiration timer for subscription of a Request Contained List, used in capability polling.
218      */
getCapabPollListSubExp(int subId)219     public static int getCapabPollListSubExp(int subId) {
220         int capabPollListSubExp = DEFAULT_CAPABILITY_POLL_LIST_SUB_EXPIRATION_SEC;
221         try {
222             ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
223             capabPollListSubExp = manager.getProvisioningIntValue(
224                     ProvisioningManager.KEY_RCS_CAPABILITY_POLL_LIST_SUB_EXP_SEC);
225         } catch (Exception e) {
226             // If there is no active subscriptions, this will throw an exception.
227             logger.debug("getCapabPollListSubExp: exception=" + e.getMessage());
228         }
229         logger.debug("getCapabPollListSubExp=" + capabPollListSubExp);
230         return capabPollListSubExp;
231     }
232 
233     /**
234      * Period of time the availability information of a contact is cached on device.
235      */
getAvailabilityCacheExpiration(int subId)236     public static int getAvailabilityCacheExpiration(int subId) {
237         int availabilityCacheExpiration = DEFAULT_AVAILABILITY_CACHE_EXPIRATION_SEC;
238         try {
239             ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
240             availabilityCacheExpiration = manager.getProvisioningIntValue(
241                     ProvisioningManager.KEY_RCS_AVAILABILITY_CACHE_EXPIRATION_SEC);
242         } catch (Exception e) {
243             // If there is no active subscriptions, this will throw an exception.
244             logger.debug("getAvailabilityCacheExpiration: exception=" + e.getMessage());
245         }
246         logger.debug("getAvailabilityCacheExpiration=" + availabilityCacheExpiration);
247         return availabilityCacheExpiration;
248     }
249 
getPublishThrottle(int subId)250     public static int getPublishThrottle(int subId) {
251         // Default
252         int publishThrottle = DEFAULT_PUBLISH_THROTTLE_MS;
253         try {
254             ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
255             publishThrottle = manager.getProvisioningIntValue(
256                     ProvisioningManager.KEY_RCS_PUBLISH_SOURCE_THROTTLE_MS);
257         } catch (Exception e) {
258             // If there is no active subscriptions, this will throw an exception.
259             logger.debug("publishThrottle: exception=" + e.getMessage());
260         }
261         logger.debug("publishThrottle=" + publishThrottle);
262         return publishThrottle;
263     }
264 
isVtEnabledByUser(int subId)265     public static boolean isVtEnabledByUser(int subId) {
266         try {
267             ImsMmTelManager mmTelManager = ImsMmTelManager.createForSubscriptionId(subId);
268             return mmTelManager.isVtSettingEnabled();
269         } catch (Exception e) {
270             logger.warn("isVtEnabledByUser exception = " + e.getMessage());
271             return false;
272         }
273     }
274 
isWfcEnabledByUser(int subId)275     public static boolean isWfcEnabledByUser(int subId) {
276         try {
277             ImsMmTelManager mmTelManager = ImsMmTelManager.createForSubscriptionId(subId);
278         return mmTelManager.isVoWiFiSettingEnabled();
279         } catch (Exception e) {
280             logger.warn("isWfcEnabledByUser exception = " + e.getMessage());
281             return false;
282         }
283     }
284 
isAdvancedCallingEnabledByUser(int subId)285     public static boolean isAdvancedCallingEnabledByUser(int subId) {
286         try {
287             ImsMmTelManager mmTelManager = ImsMmTelManager.createForSubscriptionId(subId);
288             return mmTelManager.isAdvancedCallingSettingEnabled();
289         } catch (Exception e) {
290             logger.warn("isAdvancedCallingEnabledByUser exception = " + e.getMessage());
291             return false;
292         }
293     }
294 
isVoLteSupported(int subId)295     public static boolean isVoLteSupported(int subId) {
296         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
297             return false;
298         }
299         LinkedBlockingQueue<Boolean> resultQueue = new LinkedBlockingQueue<>(1);
300         try {
301             ImsMmTelManager mmTelManager = ImsMmTelManager.createForSubscriptionId(subId);
302             mmTelManager.isSupported(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
303                     AccessNetworkConstants.TRANSPORT_TYPE_WWAN, Runnable::run, resultQueue::offer);
304         } catch (ImsException e) {
305             logger.warn("isVoLteSupported: ImsException = " + e.getMessage());
306             return false;
307         }
308         try {
309             Boolean result = resultQueue.poll(TIMEOUT_GET_CONFIGURATION_MS, TimeUnit.MILLISECONDS);
310             return (result != null) ? result : false;
311         } catch (InterruptedException e) {
312             logger.warn("isVoLteSupported, InterruptedException=" + e.getMessage());
313             return false;
314         }
315     }
316 
isVoWiFiSupported(int subId)317     public static boolean isVoWiFiSupported(int subId) {
318         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
319             return false;
320         }
321         LinkedBlockingQueue<Boolean> resultQueue = new LinkedBlockingQueue<>(1);
322         try {
323             ImsMmTelManager mmTelManager = ImsMmTelManager.createForSubscriptionId(subId);
324             mmTelManager.isSupported(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
325                     AccessNetworkConstants.TRANSPORT_TYPE_WLAN, Runnable::run, resultQueue::offer);
326         } catch (ImsException e) {
327             logger.warn("isVoWiFiSupported: ImsException = " + e.getMessage());
328             return false;
329         }
330         try {
331             Boolean result = resultQueue.poll(TIMEOUT_GET_CONFIGURATION_MS, TimeUnit.MILLISECONDS);
332             return (result != null) ? result : false;
333         } catch (InterruptedException e) {
334             logger.warn("isVoWiFiSupported, InterruptedException=" + e.getMessage());
335             return false;
336         }
337     }
338 
isVtSupported(int subId)339     public static boolean isVtSupported(int subId) {
340         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
341             return false;
342         }
343         LinkedBlockingQueue<Boolean> resultQueue = new LinkedBlockingQueue<>(1);
344         try {
345             ImsMmTelManager mmTelManager = ImsMmTelManager.createForSubscriptionId(subId);
346             mmTelManager.isSupported(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO,
347                     AccessNetworkConstants.TRANSPORT_TYPE_WWAN, Runnable::run, resultQueue::offer);
348         } catch (ImsException e) {
349             logger.warn("isVoWiFiSupported: ImsException = " + e.getMessage());
350             return false;
351         }
352         try {
353             Boolean result = resultQueue.poll(TIMEOUT_GET_CONFIGURATION_MS, TimeUnit.MILLISECONDS);
354             return (result != null) ? result : false;
355         } catch (InterruptedException e) {
356             logger.warn("isVtSupported, InterruptedException=" + e.getMessage());
357             return false;
358         }
359     }
360 
getDefaultSubscriptionId(Context context)361     public static int getDefaultSubscriptionId(Context context) {
362         SubscriptionManager sm = context.getSystemService(SubscriptionManager.class);
363         if (sm == null) return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
364         sm = sm.createForAllUserProfiles();
365 
366         List<SubscriptionInfo> infos = sm.getActiveSubscriptionInfoList();
367         if (infos == null || infos.isEmpty()) {
368             // There are no active subscriptions right now.
369             return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
370         }
371         // This code does not support MSIM unfortunately, so only provide presence on the default
372         // voice subscription that the user chose.
373         int defaultSub = SubscriptionManager.getDefaultVoiceSubscriptionId();
374         if (!SubscriptionManager.isValidSubscriptionId(defaultSub)) {
375             // The voice sub may not have been specified, in this case, use the default data.
376             defaultSub = SubscriptionManager.getDefaultDataSubscriptionId();
377         }
378         // If the user has no default set, just pick the first as backup.
379         if (!SubscriptionManager.isValidSubscriptionId(defaultSub)) {
380             for (SubscriptionInfo info : infos) {
381                 if (!info.isOpportunistic()) {
382                     defaultSub = info.getSubscriptionId();
383                     break;
384                 }
385             }
386         }
387         return defaultSub;
388     }
389 }
390 
391