blob: 056e4d0bd7daddf6613d9f79fad32ae7f390b883 [file] [log] [blame]
/*
* Copyright (c) 2015, Motorola Mobility LLC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - Neither the name of Motorola Mobility nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*/
package com.android.service.ims;
import android.content.Context;
import android.os.PersistableBundle;
import android.telephony.AccessNetworkConstants;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.ims.ImsException;
import android.telephony.ims.ImsManager;
import android.telephony.ims.ImsMmTelManager;
import android.telephony.ims.ImsRcsManager;
import android.telephony.ims.ProvisioningManager;
import android.telephony.ims.feature.MmTelFeature;
import android.telephony.ims.stub.ImsRegistrationImplBase;
import com.android.ims.internal.Logger;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
public class RcsSettingUtils {
static private Logger logger = Logger.getLogger("RcsSettingUtils");
private static final int TIMEOUT_GET_CONFIGURATION_MS = 5000;
// Default number of entries for getMaxNumbersInRCL
private static final int DEFAULT_NUM_ENTRIES_IN_RCL = 100;
// Default for getCapabPollListSubExp in seconds.
private static final int DEFAULT_CAPABILITY_POLL_LIST_SUB_EXPIRATION_SEC = 30;
// Default for getAvailabilityCacheExpiration in seconds.
private static final int DEFAULT_AVAILABILITY_CACHE_EXPIRATION_SEC = 30;
// Default for getPublishThrottle in milliseconds
private static final int DEFAULT_PUBLISH_THROTTLE_MS = 60000;
public static boolean isVoLteProvisioned(int subId) {
try {
boolean isProvisioned;
ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
isProvisioned = manager.getProvisioningStatusForCapability(
MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
logger.debug("isVoLteProvisioned=" + isProvisioned);
return isProvisioned;
} catch (Exception e) {
logger.debug("isVoLteProvisioned, exception = " + e.getMessage());
return false;
}
}
public static boolean isVowifiProvisioned(int subId) {
try {
boolean isProvisioned;
ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
isProvisioned = manager.getProvisioningStatusForCapability(
MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN);
logger.debug("isVowifiProvisioned=" + isProvisioned);
return isProvisioned;
} catch (Exception e) {
logger.debug("isVowifiProvisioned, exception = " + e.getMessage());
return false;
}
}
public static boolean isLvcProvisioned(int subId) {
try {
boolean isProvisioned;
ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
isProvisioned = manager.getProvisioningStatusForCapability(
MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO,
ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
logger.debug("isLvcProvisioned=" + isProvisioned);
return isProvisioned;
} catch (Exception e) {
logger.debug("isLvcProvisioned, exception = " + e.getMessage());
return false;
}
}
public static boolean isEabProvisioned(Context context, int subId) {
boolean isProvisioned = false;
if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
logger.debug("isEabProvisioned: no valid subscriptions!");
return false;
}
CarrierConfigManager configManager = (CarrierConfigManager)
context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
if (configManager != null) {
PersistableBundle config = configManager.getConfigForSubId(subId);
if (config != null && !config.getBoolean(
CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONED_BOOL)) {
// If we don't need provisioning, just return true.
return true;
}
}
try {
ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
isProvisioned = manager.getProvisioningIntValue(
ProvisioningManager.KEY_EAB_PROVISIONING_STATUS)
== ProvisioningManager.PROVISIONING_VALUE_ENABLED;
} catch (Exception e) {
logger.debug("isEabProvisioned: exception=" + e.getMessage());
}
logger.debug("isEabProvisioned=" + isProvisioned);
return isProvisioned;
}
public static boolean hasUserEnabledContactDiscovery(Context context, int subId) {
if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
logger.debug("hasUserEnabledContactDiscovery: no valid subscriptions!");
return false;
}
try {
ImsManager imsManager = context.getSystemService(ImsManager.class);
ImsRcsManager rcsManager = imsManager.getImsRcsManager(subId);
return rcsManager.getUceAdapter().isUceSettingEnabled();
} catch (Exception e) {
logger.warn("hasUserEnabledContactDiscovery: Exception = " + e.getMessage());
return false;
}
}
public static int getSIPT1Timer(int subId) {
int sipT1Timer = 0;
try {
ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
sipT1Timer = manager.getProvisioningIntValue(ProvisioningManager.KEY_T1_TIMER_VALUE_MS);
} catch (Exception e) {
// If there is no active subscriptions, this will throw an exception.
logger.debug("getSIPT1Timer: exception=" + e.getMessage());
}
logger.debug("getSIPT1Timer=" + sipT1Timer);
return sipT1Timer;
}
/**
* Capability discovery status of Enabled (1), or Disabled (0).
*/
public static boolean getCapabilityDiscoveryEnabled(int subId) {
boolean capabilityDiscoveryEnabled = false;
try {
ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
capabilityDiscoveryEnabled = manager.getProvisioningIntValue(
ProvisioningManager.KEY_RCS_CAPABILITY_DISCOVERY_ENABLED) ==
ProvisioningManager.PROVISIONING_VALUE_ENABLED;
} catch (Exception e) {
// If there is no active subscriptions, this will throw an exception.
logger.debug("capabilityDiscoveryEnabled: exception=" + e.getMessage());
}
logger.debug("capabilityDiscoveryEnabled=" + capabilityDiscoveryEnabled);
return capabilityDiscoveryEnabled;
}
/**
* The Maximum number of MDNs contained in one Request Contained List.
*/
public static int getMaxNumbersInRCL(int subId) {
int maxNumbersInRCL = DEFAULT_NUM_ENTRIES_IN_RCL;
try {
ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
maxNumbersInRCL = manager.getProvisioningIntValue(
ProvisioningManager.KEY_RCS_MAX_NUM_ENTRIES_IN_RCL);
} catch (Exception e) {
// If there is no active subscriptions, this will throw an exception.
logger.debug("getMaxNumbersInRCL: exception=" + e.getMessage());
}
logger.debug("getMaxNumbersInRCL=" + maxNumbersInRCL);
return maxNumbersInRCL;
}
/**
* Expiration timer for subscription of a Request Contained List, used in capability polling.
*/
public static int getCapabPollListSubExp(int subId) {
int capabPollListSubExp = DEFAULT_CAPABILITY_POLL_LIST_SUB_EXPIRATION_SEC;
try {
ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
capabPollListSubExp = manager.getProvisioningIntValue(
ProvisioningManager.KEY_RCS_CAPABILITY_POLL_LIST_SUB_EXP_SEC);
} catch (Exception e) {
// If there is no active subscriptions, this will throw an exception.
logger.debug("getCapabPollListSubExp: exception=" + e.getMessage());
}
logger.debug("getCapabPollListSubExp=" + capabPollListSubExp);
return capabPollListSubExp;
}
/**
* Period of time the availability information of a contact is cached on device.
*/
public static int getAvailabilityCacheExpiration(int subId) {
int availabilityCacheExpiration = DEFAULT_AVAILABILITY_CACHE_EXPIRATION_SEC;
try {
ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
availabilityCacheExpiration = manager.getProvisioningIntValue(
ProvisioningManager.KEY_RCS_AVAILABILITY_CACHE_EXPIRATION_SEC);
} catch (Exception e) {
// If there is no active subscriptions, this will throw an exception.
logger.debug("getAvailabilityCacheExpiration: exception=" + e.getMessage());
}
logger.debug("getAvailabilityCacheExpiration=" + availabilityCacheExpiration);
return availabilityCacheExpiration;
}
public static int getPublishThrottle(int subId) {
// Default
int publishThrottle = DEFAULT_PUBLISH_THROTTLE_MS;
try {
ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
publishThrottle = manager.getProvisioningIntValue(
ProvisioningManager.KEY_RCS_PUBLISH_SOURCE_THROTTLE_MS);
} catch (Exception e) {
// If there is no active subscriptions, this will throw an exception.
logger.debug("publishThrottle: exception=" + e.getMessage());
}
logger.debug("publishThrottle=" + publishThrottle);
return publishThrottle;
}
public static boolean isVtEnabledByUser(int subId) {
try {
ImsMmTelManager mmTelManager = ImsMmTelManager.createForSubscriptionId(subId);
return mmTelManager.isVtSettingEnabled();
} catch (Exception e) {
logger.warn("isVtEnabledByUser exception = " + e.getMessage());
return false;
}
}
public static boolean isWfcEnabledByUser(int subId) {
try {
ImsMmTelManager mmTelManager = ImsMmTelManager.createForSubscriptionId(subId);
return mmTelManager.isVoWiFiSettingEnabled();
} catch (Exception e) {
logger.warn("isWfcEnabledByUser exception = " + e.getMessage());
return false;
}
}
public static boolean isAdvancedCallingEnabledByUser(int subId) {
try {
ImsMmTelManager mmTelManager = ImsMmTelManager.createForSubscriptionId(subId);
return mmTelManager.isAdvancedCallingSettingEnabled();
} catch (Exception e) {
logger.warn("isAdvancedCallingEnabledByUser exception = " + e.getMessage());
return false;
}
}
public static boolean isVoLteSupported(int subId) {
if (!SubscriptionManager.isValidSubscriptionId(subId)) {
return false;
}
LinkedBlockingQueue<Boolean> resultQueue = new LinkedBlockingQueue<>(1);
try {
ImsMmTelManager mmTelManager = ImsMmTelManager.createForSubscriptionId(subId);
mmTelManager.isSupported(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
AccessNetworkConstants.TRANSPORT_TYPE_WWAN, Runnable::run, resultQueue::offer);
} catch (ImsException e) {
logger.warn("isVoLteSupported: ImsException = " + e.getMessage());
return false;
}
try {
Boolean result = resultQueue.poll(TIMEOUT_GET_CONFIGURATION_MS, TimeUnit.MILLISECONDS);
return (result != null) ? result : false;
} catch (InterruptedException e) {
logger.warn("isVoLteSupported, InterruptedException=" + e.getMessage());
return false;
}
}
public static boolean isVoWiFiSupported(int subId) {
if (!SubscriptionManager.isValidSubscriptionId(subId)) {
return false;
}
LinkedBlockingQueue<Boolean> resultQueue = new LinkedBlockingQueue<>(1);
try {
ImsMmTelManager mmTelManager = ImsMmTelManager.createForSubscriptionId(subId);
mmTelManager.isSupported(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
AccessNetworkConstants.TRANSPORT_TYPE_WLAN, Runnable::run, resultQueue::offer);
} catch (ImsException e) {
logger.warn("isVoWiFiSupported: ImsException = " + e.getMessage());
return false;
}
try {
Boolean result = resultQueue.poll(TIMEOUT_GET_CONFIGURATION_MS, TimeUnit.MILLISECONDS);
return (result != null) ? result : false;
} catch (InterruptedException e) {
logger.warn("isVoWiFiSupported, InterruptedException=" + e.getMessage());
return false;
}
}
public static boolean isVtSupported(int subId) {
if (!SubscriptionManager.isValidSubscriptionId(subId)) {
return false;
}
LinkedBlockingQueue<Boolean> resultQueue = new LinkedBlockingQueue<>(1);
try {
ImsMmTelManager mmTelManager = ImsMmTelManager.createForSubscriptionId(subId);
mmTelManager.isSupported(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO,
AccessNetworkConstants.TRANSPORT_TYPE_WWAN, Runnable::run, resultQueue::offer);
} catch (ImsException e) {
logger.warn("isVoWiFiSupported: ImsException = " + e.getMessage());
return false;
}
try {
Boolean result = resultQueue.poll(TIMEOUT_GET_CONFIGURATION_MS, TimeUnit.MILLISECONDS);
return (result != null) ? result : false;
} catch (InterruptedException e) {
logger.warn("isVtSupported, InterruptedException=" + e.getMessage());
return false;
}
}
public static int getDefaultSubscriptionId(Context context) {
SubscriptionManager sm = context.getSystemService(SubscriptionManager.class);
if (sm == null) return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
List<SubscriptionInfo> infos = sm.getActiveSubscriptionInfoList();
if (infos == null || infos.isEmpty()) {
// There are no active subscriptions right now.
return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
}
// This code does not support MSIM unfortunately, so only provide presence on the default
// voice subscription that the user chose.
int defaultSub = SubscriptionManager.getDefaultVoiceSubscriptionId();
if (!SubscriptionManager.isValidSubscriptionId(defaultSub)) {
// The voice sub may not have been specified, in this case, use the default data.
defaultSub = SubscriptionManager.getDefaultDataSubscriptionId();
}
// If the user has no default set, just pick the first as backup.
if (!SubscriptionManager.isValidSubscriptionId(defaultSub)) {
for (SubscriptionInfo info : infos) {
if (!info.isOpportunistic()) {
defaultSub = info.getSubscriptionId();
break;
}
}
}
return defaultSub;
}
}