blob: 35c37efbb93bd580754d853d102a5e4622c1abfa [file] [log] [blame]
Wink Savilleef36ef62014-06-11 08:39:38 -07001/*
2 * Copyright (c) 2013 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
17package com.android.ims;
18
19import android.app.PendingIntent;
Etan Cohena00c9192014-12-23 15:02:29 -080020import android.app.QueuedWork;
Wink Savilleef36ef62014-06-11 08:39:38 -070021import android.content.Context;
22import android.content.Intent;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -070023import android.content.SharedPreferences;
Pavel Zhamaitsiak4de9cbb2016-02-11 17:21:05 -080024import android.net.Uri;
Wink Savilleef36ef62014-06-11 08:39:38 -070025import android.os.IBinder;
Wink Savilleef36ef62014-06-11 08:39:38 -070026import android.os.Message;
Jonathan Basseri2acea6f2015-07-01 15:00:38 -070027import android.os.PersistableBundle;
Wink Savilleef36ef62014-06-11 08:39:38 -070028import android.os.RemoteException;
29import android.os.ServiceManager;
Etan Cohenaf55a402014-09-04 22:34:41 -070030import android.os.SystemProperties;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -070031import android.preference.PreferenceManager;
Etan Cohen82f78122014-12-15 10:10:14 -080032import android.provider.Settings;
33import android.telecom.TelecomManager;
Junda Liue7663c02015-06-23 11:16:26 -070034import android.telephony.CarrierConfigManager;
Wink Savilleef36ef62014-06-11 08:39:38 -070035import android.telephony.Rlog;
Etan Cohen82f78122014-12-15 10:10:14 -080036import android.telephony.SubscriptionManager;
Etan Cohencfc784d2014-08-07 18:40:31 -070037import android.telephony.TelephonyManager;
Wink Savilleef36ef62014-06-11 08:39:38 -070038
39import com.android.ims.internal.IImsCallSession;
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -070040import com.android.ims.internal.IImsEcbm;
41import com.android.ims.internal.IImsEcbmListener;
Wink Savilleef36ef62014-06-11 08:39:38 -070042import com.android.ims.internal.IImsRegistrationListener;
43import com.android.ims.internal.IImsService;
44import com.android.ims.internal.IImsUt;
45import com.android.ims.internal.ImsCallSession;
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -050046import com.android.ims.internal.IImsConfig;
47
Jack Yu2f102bd2015-12-28 15:31:48 -080048import java.io.FileDescriptor;
49import java.io.PrintWriter;
Etan Cohend7727462014-07-12 14:54:10 -070050import java.util.HashMap;
51
Wink Savilleef36ef62014-06-11 08:39:38 -070052/**
53 * Provides APIs for IMS services, such as initiating IMS calls, and provides access to
54 * the operator's IMS network. This class is the starting point for any IMS actions.
55 * You can acquire an instance of it with {@link #getInstance getInstance()}.</p>
56 * <p>The APIs in this class allows you to:</p>
57 *
58 * @hide
59 */
60public class ImsManager {
Etan Cohen19604c02014-08-11 14:32:57 -070061
Etan Cohenaf55a402014-09-04 22:34:41 -070062 /*
63 * Debug flag to override configuration flag
64 */
Etan Cohenb651fa52014-10-22 10:51:29 -070065 public static final String PROPERTY_DBG_VOLTE_AVAIL_OVERRIDE = "persist.dbg.volte_avail_ovr";
66 public static final int PROPERTY_DBG_VOLTE_AVAIL_OVERRIDE_DEFAULT = 0;
Etan Cohenea2b5832014-10-23 18:50:35 -070067 public static final String PROPERTY_DBG_VT_AVAIL_OVERRIDE = "persist.dbg.vt_avail_ovr";
68 public static final int PROPERTY_DBG_VT_AVAIL_OVERRIDE_DEFAULT = 0;
Etan Cohena00c9192014-12-23 15:02:29 -080069 public static final String PROPERTY_DBG_WFC_AVAIL_OVERRIDE = "persist.dbg.wfc_avail_ovr";
70 public static final int PROPERTY_DBG_WFC_AVAIL_OVERRIDE_DEFAULT = 0;
Etan Cohenaf55a402014-09-04 22:34:41 -070071
Wink Savilleef36ef62014-06-11 08:39:38 -070072 /**
73 * For accessing the IMS related service.
74 * Internal use only.
75 * @hide
76 */
Etan Cohend7727462014-07-12 14:54:10 -070077 private static final String IMS_SERVICE = "ims";
Wink Savilleef36ef62014-06-11 08:39:38 -070078
79 /**
80 * The result code to be sent back with the incoming call {@link PendingIntent}.
81 * @see #open(PendingIntent, ImsConnectionStateListener)
82 */
83 public static final int INCOMING_CALL_RESULT_CODE = 101;
84
85 /**
86 * Key to retrieve the call ID from an incoming call intent.
87 * @see #open(PendingIntent, ImsConnectionStateListener)
88 */
89 public static final String EXTRA_CALL_ID = "android:imsCallID";
90
91 /**
92 * Action to broadcast when ImsService is up.
93 * Internal use only.
94 * @hide
95 */
96 public static final String ACTION_IMS_SERVICE_UP =
97 "com.android.ims.IMS_SERVICE_UP";
98
99 /**
100 * Action to broadcast when ImsService is down.
101 * Internal use only.
102 * @hide
103 */
104 public static final String ACTION_IMS_SERVICE_DOWN =
105 "com.android.ims.IMS_SERVICE_DOWN";
106
107 /**
Pavel Zhamaitsiak0c2f15c2015-03-12 15:37:54 -0700108 * Action to broadcast when ImsService registration fails.
109 * Internal use only.
110 * @hide
111 */
112 public static final String ACTION_IMS_REGISTRATION_ERROR =
113 "com.android.ims.REGISTRATION_ERROR";
114
115 /**
Etan Cohend7727462014-07-12 14:54:10 -0700116 * Part of the ACTION_IMS_SERVICE_UP or _DOWN intents.
Etan Cohenabbd7882014-09-26 22:35:35 -0700117 * A long value; the phone ID corresponding to the IMS service coming up or down.
Etan Cohend7727462014-07-12 14:54:10 -0700118 * Internal use only.
119 * @hide
120 */
Etan Cohenabbd7882014-09-26 22:35:35 -0700121 public static final String EXTRA_PHONE_ID = "android:phone_id";
Etan Cohend7727462014-07-12 14:54:10 -0700122
123 /**
Wink Savilleef36ef62014-06-11 08:39:38 -0700124 * Action for the incoming call intent for the Phone app.
125 * Internal use only.
126 * @hide
127 */
128 public static final String ACTION_IMS_INCOMING_CALL =
129 "com.android.ims.IMS_INCOMING_CALL";
130
131 /**
132 * Part of the ACTION_IMS_INCOMING_CALL intents.
133 * An integer value; service identifier obtained from {@link ImsManager#open}.
134 * Internal use only.
135 * @hide
136 */
137 public static final String EXTRA_SERVICE_ID = "android:imsServiceId";
138
139 /**
140 * Part of the ACTION_IMS_INCOMING_CALL intents.
141 * An boolean value; Flag to indicate that the incoming call is a normal call or call for USSD.
142 * The value "true" indicates that the incoming call is for USSD.
143 * Internal use only.
144 * @hide
145 */
146 public static final String EXTRA_USSD = "android:ussd";
147
Shriram Ganeshd3adfad2015-05-31 10:06:15 -0700148 /**
149 * Part of the ACTION_IMS_INCOMING_CALL intents.
150 * A boolean value; Flag to indicate whether the call is an unknown
151 * dialing call. Such calls are originated by sending commands (like
152 * AT commands) directly to modem without Android involvement.
153 * Even though they are not incoming calls, they are propagated
154 * to Phone app using same ACTION_IMS_INCOMING_CALL intent.
155 * Internal use only.
156 * @hide
157 */
Anju Mathapati9c033792015-06-16 16:33:16 -0700158 public static final String EXTRA_IS_UNKNOWN_CALL = "android:isUnknown";
Shriram Ganeshd3adfad2015-05-31 10:06:15 -0700159
Wink Savilleef36ef62014-06-11 08:39:38 -0700160 private static final String TAG = "ImsManager";
161 private static final boolean DBG = true;
162
Wink Saville1e5a38a2014-10-23 10:24:46 -0700163 private static HashMap<Integer, ImsManager> sImsManagerInstances =
164 new HashMap<Integer, ImsManager>();
Etan Cohend7727462014-07-12 14:54:10 -0700165
Wink Savilleef36ef62014-06-11 08:39:38 -0700166 private Context mContext;
Etan Cohenabbd7882014-09-26 22:35:35 -0700167 private int mPhoneId;
Wink Savilleef36ef62014-06-11 08:39:38 -0700168 private IImsService mImsService = null;
169 private ImsServiceDeathRecipient mDeathRecipient = new ImsServiceDeathRecipient();
170 // Ut interface for the supplementary service configuration
171 private ImsUt mUt = null;
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -0500172 // Interface to get/set ims config items
173 private ImsConfig mConfig = null;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -0700174 private boolean mConfigUpdated = false;
175 private static final String PREF_ENABLE_VIDEO_CALLING_KEY = "enable_video_calling";
Wink Savilleef36ef62014-06-11 08:39:38 -0700176
Pavel Zhamaitsiakf4b90322016-01-26 14:34:09 -0800177 private ImsConfigListener mImsConfigListener;
178
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -0700179 // ECBM interface
180 private ImsEcbm mEcbm = null;
181
Wink Savilleef36ef62014-06-11 08:39:38 -0700182 /**
183 * Gets a manager instance.
184 *
185 * @param context application context for creating the manager object
Etan Cohenabbd7882014-09-26 22:35:35 -0700186 * @param phoneId the phone ID for the IMS Service
187 * @return the manager instance corresponding to the phoneId
Wink Savilleef36ef62014-06-11 08:39:38 -0700188 */
Etan Cohenabbd7882014-09-26 22:35:35 -0700189 public static ImsManager getInstance(Context context, int phoneId) {
Etan Cohend7727462014-07-12 14:54:10 -0700190 synchronized (sImsManagerInstances) {
Etan Cohenabbd7882014-09-26 22:35:35 -0700191 if (sImsManagerInstances.containsKey(phoneId))
192 return sImsManagerInstances.get(phoneId);
Wink Savilleef36ef62014-06-11 08:39:38 -0700193
Etan Cohenabbd7882014-09-26 22:35:35 -0700194 ImsManager mgr = new ImsManager(context, phoneId);
195 sImsManagerInstances.put(phoneId, mgr);
Etan Cohend7727462014-07-12 14:54:10 -0700196
197 return mgr;
198 }
Wink Savilleef36ef62014-06-11 08:39:38 -0700199 }
200
Etan Cohen45b5f312014-08-19 15:55:08 -0700201 /**
202 * Returns the user configuration of Enhanced 4G LTE Mode setting
203 */
204 public static boolean isEnhanced4gLteModeSettingEnabledByUser(Context context) {
Sungmin Choi2f1af952016-02-01 17:15:35 +0900205 // If user can't edit Enhanced 4G LTE Mode, it assumes Enhanced 4G LTE Mode is always true.
206 // If user changes SIM from editable mode to uneditable mode, need to return true.
207 if (!getBooleanCarrierConfig(context,
208 CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL)) {
209 return true;
210 }
Libin.Tang@motorola.com8a6bf4b2014-10-10 15:02:41 -0500211 int enabled = android.provider.Settings.Global.getInt(
212 context.getContentResolver(),
Etan Cohenb651fa52014-10-22 10:51:29 -0700213 android.provider.Settings.Global.ENHANCED_4G_MODE_ENABLED, ImsConfig.FeatureValueConstants.ON);
Etan Cohena00c9192014-12-23 15:02:29 -0800214 return (enabled == 1) ? true : false;
Etan Cohen45b5f312014-08-19 15:55:08 -0700215 }
216
217 /**
Etan Cohen82f78122014-12-15 10:10:14 -0800218 * Change persistent Enhanced 4G LTE Mode setting
219 */
220 public static void setEnhanced4gLteModeSetting(Context context, boolean enabled) {
221 int value = enabled ? 1 : 0;
222 android.provider.Settings.Global.putInt(
223 context.getContentResolver(),
224 android.provider.Settings.Global.ENHANCED_4G_MODE_ENABLED, value);
225
226 if (isNonTtyOrTtyOnVolteEnabled(context)) {
227 ImsManager imsManager = ImsManager.getInstance(context,
228 SubscriptionManager.getDefaultVoicePhoneId());
229 if (imsManager != null) {
230 try {
231 imsManager.setAdvanced4GMode(enabled);
232 } catch (ImsException ie) {
233 // do nothing
234 }
235 }
236 }
237 }
238
239 /**
240 * Indicates whether the call is non-TTY or if TTY - whether TTY on VoLTE is
241 * supported.
242 */
243 public static boolean isNonTtyOrTtyOnVolteEnabled(Context context) {
Junda Liue7663c02015-06-23 11:16:26 -0700244 if (getBooleanCarrierConfig(context,
fionaxu5803ef02016-03-08 11:48:48 -0800245 CarrierConfigManager.KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL)) {
Etan Cohen82f78122014-12-15 10:10:14 -0800246 return true;
247 }
248
249 return Settings.Secure.getInt(context.getContentResolver(),
250 Settings.Secure.PREFERRED_TTY_MODE, TelecomManager.TTY_MODE_OFF)
251 == TelecomManager.TTY_MODE_OFF;
252 }
253
254 /**
Etan Cohenea2b5832014-10-23 18:50:35 -0700255 * Returns a platform configuration for VoLTE which may override the user setting.
Etan Cohen45b5f312014-08-19 15:55:08 -0700256 */
Etan Cohenea2b5832014-10-23 18:50:35 -0700257 public static boolean isVolteEnabledByPlatform(Context context) {
Etan Cohenb651fa52014-10-22 10:51:29 -0700258 if (SystemProperties.getInt(PROPERTY_DBG_VOLTE_AVAIL_OVERRIDE,
259 PROPERTY_DBG_VOLTE_AVAIL_OVERRIDE_DEFAULT) == 1) {
Etan Cohenaf55a402014-09-04 22:34:41 -0700260 return true;
261 }
262
Etan Cohenb5388a32014-11-26 11:57:47 -0800263 return context.getResources().getBoolean(
Junda Liue7663c02015-06-23 11:16:26 -0700264 com.android.internal.R.bool.config_device_volte_available)
265 && getBooleanCarrierConfig(context,
Pavel Zhamaitsiak57911d12015-10-20 14:26:34 -0700266 CarrierConfigManager.KEY_CARRIER_VOLTE_AVAILABLE_BOOL)
267 && isGbaValid(context);
Etan Cohenb5388a32014-11-26 11:57:47 -0800268 }
269
270 /*
271 * Indicates whether VoLTE is provisioned on device
272 */
273 public static boolean isVolteProvisionedOnDevice(Context context) {
274 boolean isProvisioned = true;
Junda Liue7663c02015-06-23 11:16:26 -0700275 if (getBooleanCarrierConfig(context,
276 CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL)) {
Etan Cohenb5388a32014-11-26 11:57:47 -0800277 isProvisioned = false; // disable on any error
278 ImsManager mgr = ImsManager.getInstance(context,
Jonathan Basserid7133652015-04-07 19:54:24 -0700279 SubscriptionManager.getDefaultVoicePhoneId());
Etan Cohenb5388a32014-11-26 11:57:47 -0800280 if (mgr != null) {
281 try {
282 ImsConfig config = mgr.getConfigInterface();
283 if (config != null) {
284 isProvisioned = config.getVolteProvisioned();
285 }
286 } catch (ImsException ie) {
287 // do nothing
288 }
289 }
290 }
291
292 return isProvisioned;
Etan Cohenb651fa52014-10-22 10:51:29 -0700293 }
294
Etan Cohenea2b5832014-10-23 18:50:35 -0700295 /**
296 * Returns a platform configuration for VT which may override the user setting.
297 *
298 * Note: VT presumes that VoLTE is enabled (these are configuration settings
299 * which must be done correctly).
300 */
Etan Cohenb651fa52014-10-22 10:51:29 -0700301 public static boolean isVtEnabledByPlatform(Context context) {
Etan Cohenea2b5832014-10-23 18:50:35 -0700302 if (SystemProperties.getInt(PROPERTY_DBG_VT_AVAIL_OVERRIDE,
303 PROPERTY_DBG_VT_AVAIL_OVERRIDE_DEFAULT) == 1) {
304 return true;
305 }
306
Etan Cohenb651fa52014-10-22 10:51:29 -0700307 return
308 context.getResources().getBoolean(
309 com.android.internal.R.bool.config_device_vt_available) &&
Junda Liue7663c02015-06-23 11:16:26 -0700310 getBooleanCarrierConfig(context,
Pavel Zhamaitsiak57911d12015-10-20 14:26:34 -0700311 CarrierConfigManager.KEY_CARRIER_VT_AVAILABLE_BOOL) &&
312 isGbaValid(context);
Etan Cohen45b5f312014-08-19 15:55:08 -0700313 }
314
Etan Cohena00c9192014-12-23 15:02:29 -0800315 /**
Etan Cohena7d32e82015-05-04 18:02:09 -0700316 * Returns the user configuration of VT setting
317 */
318 public static boolean isVtEnabledByUser(Context context) {
319 int enabled = android.provider.Settings.Global.getInt(context.getContentResolver(),
320 android.provider.Settings.Global.VT_IMS_ENABLED,
321 ImsConfig.FeatureValueConstants.ON);
322 return (enabled == 1) ? true : false;
323 }
324
325 /**
326 * Change persistent VT enabled setting
327 */
328 public static void setVtSetting(Context context, boolean enabled) {
329 int value = enabled ? 1 : 0;
330 android.provider.Settings.Global.putInt(context.getContentResolver(),
331 android.provider.Settings.Global.VT_IMS_ENABLED, value);
332
333 ImsManager imsManager = ImsManager.getInstance(context,
334 SubscriptionManager.getDefaultVoicePhoneId());
335 if (imsManager != null) {
336 try {
337 ImsConfig config = imsManager.getConfigInterface();
338 config.setFeatureValue(ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_LTE,
339 TelephonyManager.NETWORK_TYPE_LTE,
340 enabled ? ImsConfig.FeatureValueConstants.ON
Pavel Zhamaitsiakf4b90322016-01-26 14:34:09 -0800341 : ImsConfig.FeatureValueConstants.OFF,
342 imsManager.mImsConfigListener);
Etan Cohena7d32e82015-05-04 18:02:09 -0700343
344 if (enabled) {
345 imsManager.turnOnIms();
Pavel Zhamaitsiak4ca0cde2015-12-22 16:51:57 -0800346 } else if (getBooleanCarrierConfig(context,
347 CarrierConfigManager.KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL)
348 && (!isVolteEnabledByPlatform(context)
Etan Cohena7d32e82015-05-04 18:02:09 -0700349 || !isEnhanced4gLteModeSettingEnabledByUser(context))) {
350 log("setVtSetting() : imsServiceAllowTurnOff -> turnOffIms");
351 imsManager.turnOffIms();
352 }
353 } catch (ImsException e) {
354 loge("setVtSetting(): " + e);
355 }
356 }
357 }
358
359 /**
Etan Cohena00c9192014-12-23 15:02:29 -0800360 * Returns the user configuration of WFC setting
361 */
362 public static boolean isWfcEnabledByUser(Context context) {
363 int enabled = android.provider.Settings.Global.getInt(context.getContentResolver(),
364 android.provider.Settings.Global.WFC_IMS_ENABLED,
fionaxu5803ef02016-03-08 11:48:48 -0800365 getBooleanCarrierConfig(context,
366 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL) ?
367 ImsConfig.FeatureValueConstants.ON : ImsConfig.FeatureValueConstants.OFF);
Etan Cohena00c9192014-12-23 15:02:29 -0800368 return (enabled == 1) ? true : false;
369 }
370
371 /**
372 * Change persistent WFC enabled setting
373 */
374 public static void setWfcSetting(Context context, boolean enabled) {
375 int value = enabled ? 1 : 0;
376 android.provider.Settings.Global.putInt(context.getContentResolver(),
377 android.provider.Settings.Global.WFC_IMS_ENABLED, value);
378
379 ImsManager imsManager = ImsManager.getInstance(context,
380 SubscriptionManager.getDefaultVoicePhoneId());
381 if (imsManager != null) {
382 try {
383 ImsConfig config = imsManager.getConfigInterface();
Etan Cohena00c9192014-12-23 15:02:29 -0800384 config.setFeatureValue(ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_WIFI,
Nathan Harold3a99f782015-07-24 15:02:34 -0700385 TelephonyManager.NETWORK_TYPE_IWLAN,
Etan Cohena00c9192014-12-23 15:02:29 -0800386 enabled ? ImsConfig.FeatureValueConstants.ON
Pavel Zhamaitsiakf4b90322016-01-26 14:34:09 -0800387 : ImsConfig.FeatureValueConstants.OFF,
388 imsManager.mImsConfigListener);
Pavel Zhamaitsiak183af602015-02-24 10:20:27 -0800389
390 if (enabled) {
391 imsManager.turnOnIms();
Junda Liue7663c02015-06-23 11:16:26 -0700392 } else if (getBooleanCarrierConfig(context,
393 CarrierConfigManager.KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL)
Pavel Zhamaitsiak183af602015-02-24 10:20:27 -0800394 && (!isVolteEnabledByPlatform(context)
395 || !isEnhanced4gLteModeSettingEnabledByUser(context))) {
396 log("setWfcSetting() : imsServiceAllowTurnOff -> turnOffIms");
397 imsManager.turnOffIms();
398 }
Pavel Zhamaitsiak9e6eca22015-03-16 15:30:53 -0700399
400 // Force IMS to register over LTE when turning off WFC
401 setWfcModeInternal(context, enabled
402 ? getWfcMode(context)
403 : ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED);
Etan Cohena00c9192014-12-23 15:02:29 -0800404 } catch (ImsException e) {
Pavel Zhamaitsiak183af602015-02-24 10:20:27 -0800405 loge("setWfcSetting(): " + e);
Etan Cohena00c9192014-12-23 15:02:29 -0800406 }
407 }
408 }
409
410 /**
411 * Returns the user configuration of WFC modem setting
412 */
413 public static int getWfcMode(Context context) {
414 int setting = android.provider.Settings.Global.getInt(context.getContentResolver(),
fionaxu5803ef02016-03-08 11:48:48 -0800415 android.provider.Settings.Global.WFC_IMS_MODE, getIntCarrierConfig(context,
416 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT));
Etan Cohena00c9192014-12-23 15:02:29 -0800417 if (DBG) log("getWfcMode - setting=" + setting);
418 return setting;
419 }
420
421 /**
422 * Returns the user configuration of WFC modem setting
423 */
424 public static void setWfcMode(Context context, int wfcMode) {
425 if (DBG) log("setWfcMode - setting=" + wfcMode);
426 android.provider.Settings.Global.putInt(context.getContentResolver(),
427 android.provider.Settings.Global.WFC_IMS_MODE, wfcMode);
428
Pavel Zhamaitsiak9e6eca22015-03-16 15:30:53 -0700429 setWfcModeInternal(context, wfcMode);
430 }
431
432 private static void setWfcModeInternal(Context context, int wfcMode) {
Etan Cohena00c9192014-12-23 15:02:29 -0800433 final ImsManager imsManager = ImsManager.getInstance(context,
434 SubscriptionManager.getDefaultVoicePhoneId());
435 if (imsManager != null) {
436 final int value = wfcMode;
437 QueuedWork.singleThreadExecutor().submit(new Runnable() {
438 public void run() {
439 try {
440 imsManager.getConfigInterface().setProvisionedValue(
441 ImsConfig.ConfigConstants.VOICE_OVER_WIFI_MODE,
442 value);
443 } catch (ImsException e) {
444 // do nothing
445 }
446 }
447 });
448 }
449 }
450
451 /**
452 * Returns the user configuration of WFC roaming setting
453 */
454 public static boolean isWfcRoamingEnabledByUser(Context context) {
455 int enabled = android.provider.Settings.Global.getInt(context.getContentResolver(),
456 android.provider.Settings.Global.WFC_IMS_ROAMING_ENABLED,
fionaxu5803ef02016-03-08 11:48:48 -0800457 getBooleanCarrierConfig(context,
458 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_ENABLED_BOOL) ?
459 ImsConfig.FeatureValueConstants.ON : ImsConfig.FeatureValueConstants.OFF);
Etan Cohena00c9192014-12-23 15:02:29 -0800460 return (enabled == 1) ? true : false;
461 }
462
463 /**
464 * Change persistent WFC roaming enabled setting
465 */
466 public static void setWfcRoamingSetting(Context context, boolean enabled) {
Etan Cohena00c9192014-12-23 15:02:29 -0800467 android.provider.Settings.Global.putInt(context.getContentResolver(),
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -0700468 android.provider.Settings.Global.WFC_IMS_ROAMING_ENABLED,
fionaxu5803ef02016-03-08 11:48:48 -0800469 enabled ? ImsConfig.FeatureValueConstants.ON
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -0700470 : ImsConfig.FeatureValueConstants.OFF);
Etan Cohena00c9192014-12-23 15:02:29 -0800471
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -0700472 setWfcRoamingSettingInternal(context, enabled);
473 }
474
475 private static void setWfcRoamingSettingInternal(Context context, boolean enabled) {
Etan Cohena00c9192014-12-23 15:02:29 -0800476 final ImsManager imsManager = ImsManager.getInstance(context,
477 SubscriptionManager.getDefaultVoicePhoneId());
478 if (imsManager != null) {
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -0700479 final int value = enabled
480 ? ImsConfig.FeatureValueConstants.ON
481 : ImsConfig.FeatureValueConstants.OFF;
Etan Cohena00c9192014-12-23 15:02:29 -0800482 QueuedWork.singleThreadExecutor().submit(new Runnable() {
483 public void run() {
484 try {
485 imsManager.getConfigInterface().setProvisionedValue(
486 ImsConfig.ConfigConstants.VOICE_OVER_WIFI_ROAMING,
487 value);
488 } catch (ImsException e) {
489 // do nothing
490 }
491 }
492 });
493 }
494 }
495
496 /**
497 * Returns a platform configuration for WFC which may override the user
498 * setting. Note: WFC presumes that VoLTE is enabled (these are
499 * configuration settings which must be done correctly).
500 */
501 public static boolean isWfcEnabledByPlatform(Context context) {
502 if (SystemProperties.getInt(PROPERTY_DBG_WFC_AVAIL_OVERRIDE,
503 PROPERTY_DBG_WFC_AVAIL_OVERRIDE_DEFAULT) == 1) {
504 return true;
505 }
506
507 return
508 context.getResources().getBoolean(
509 com.android.internal.R.bool.config_device_wfc_ims_available) &&
Junda Liue7663c02015-06-23 11:16:26 -0700510 getBooleanCarrierConfig(context,
Pavel Zhamaitsiak57911d12015-10-20 14:26:34 -0700511 CarrierConfigManager.KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL) &&
512 isGbaValid(context);
513 }
514
515 /**
516 * If carrier requires that IMS is only available if GBA capable SIM is used,
517 * then this function checks GBA bit in EF IST.
518 *
519 * Format of EF IST is defined in 3GPP TS 31.103 (Section 4.2.7).
520 */
521 private static boolean isGbaValid(Context context) {
522 if (getBooleanCarrierConfig(context,
523 CarrierConfigManager.KEY_CARRIER_IMS_GBA_REQUIRED_BOOL)) {
524 final TelephonyManager telephonyManager = TelephonyManager.getDefault();
525 String efIst = telephonyManager.getIsimIst();
526 if (efIst == null) {
527 loge("ISF is NULL");
528 return true;
529 }
530 boolean result = efIst != null && efIst.length() > 1 &&
531 (0x02 & (byte)efIst.charAt(1)) != 0;
532 if (DBG) log("GBA capable=" + result + ", ISF=" + efIst);
533 return result;
534 }
535 return true;
Etan Cohena00c9192014-12-23 15:02:29 -0800536 }
537
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -0700538 /**
539 * Sync carrier config and user settings with ImsConfig.
540 *
541 * @param context for the manager object
542 * @param phoneId phone id
543 * @param force update
544 */
545 public static void updateImsServiceConfig(Context context, int phoneId, boolean force) {
546 final ImsManager imsManager = ImsManager.getInstance(context, phoneId);
547 if (imsManager != null && (!imsManager.mConfigUpdated || force)) {
548 try {
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -0800549 boolean isImsUsed = imsManager.updateVolteFeatureValue();
550 isImsUsed |= imsManager.updateVideoCallFeatureValue();
551 isImsUsed |= imsManager.updateWfcFeatureAndProvisionedValues();
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -0700552
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -0800553 if (isImsUsed || !getBooleanCarrierConfig(context,
554 CarrierConfigManager.KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL)) {
555 // Turn on IMS if it is used.
556 // Also, if turning off is not allowed for current carrier,
557 // we need to turn IMS on because it might be turned off before
558 // phone switched to current carrier.
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -0700559 imsManager.turnOnIms();
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -0800560 } else {
561 // Turn off IMS if it is not used AND turning off is allowed for carrier.
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -0700562 imsManager.turnOffIms();
563 }
564
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -0700565 imsManager.mConfigUpdated = true;
566 } catch (ImsException e) {
567 loge("updateImsServiceConfig: " + e);
568 imsManager.mConfigUpdated = false;
569 }
570 }
571 }
572
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -0700573 /**
574 * Update VoLTE config
575 * @return whether feature is On
576 * @throws ImsException
577 */
578 private boolean updateVolteFeatureValue() throws ImsException {
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -0700579 boolean available = isVolteEnabledByPlatform(mContext);
580 boolean enabled = isEnhanced4gLteModeSettingEnabledByUser(mContext);
581 boolean isNonTty = isNonTtyOrTtyOnVolteEnabled(mContext);
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -0800582 boolean isFeatureOn = available && enabled && isNonTty;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -0700583
584 log("updateVolteFeatureValue: available = " + available
585 + ", enabled = " + enabled
586 + ", nonTTY = " + isNonTty);
587
588 getConfigInterface().setFeatureValue(
589 ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE,
590 TelephonyManager.NETWORK_TYPE_LTE,
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -0800591 isFeatureOn ?
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -0700592 ImsConfig.FeatureValueConstants.ON :
593 ImsConfig.FeatureValueConstants.OFF,
Pavel Zhamaitsiakf4b90322016-01-26 14:34:09 -0800594 mImsConfigListener);
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -0700595
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -0800596 return isFeatureOn;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -0700597 }
598
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -0700599 /**
600 * Update VC config
601 * @return whether feature is On
602 * @throws ImsException
603 */
604 private boolean updateVideoCallFeatureValue() throws ImsException {
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -0700605 boolean available = isVtEnabledByPlatform(mContext);
606 SharedPreferences sharedPrefs =
607 PreferenceManager.getDefaultSharedPreferences(mContext);
608 boolean enabled = isEnhanced4gLteModeSettingEnabledByUser(mContext) &&
609 sharedPrefs.getBoolean(PREF_ENABLE_VIDEO_CALLING_KEY, true);
610 boolean isNonTty = Settings.Secure.getInt(mContext.getContentResolver(),
611 Settings.Secure.PREFERRED_TTY_MODE, TelecomManager.TTY_MODE_OFF)
612 == TelecomManager.TTY_MODE_OFF;
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -0800613 boolean isFeatureOn = available && enabled && isNonTty;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -0700614
615 log("updateVideoCallFeatureValue: available = " + available
616 + ", enabled = " + enabled
617 + ", nonTTY = " + isNonTty);
618
619 getConfigInterface().setFeatureValue(
620 ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_LTE,
621 TelephonyManager.NETWORK_TYPE_LTE,
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -0800622 isFeatureOn ?
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -0700623 ImsConfig.FeatureValueConstants.ON :
624 ImsConfig.FeatureValueConstants.OFF,
Pavel Zhamaitsiakf4b90322016-01-26 14:34:09 -0800625 mImsConfigListener);
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -0700626
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -0800627 return isFeatureOn;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -0700628 }
629
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -0700630 /**
631 * Update WFC config
632 * @return whether feature is On
633 * @throws ImsException
634 */
635 private boolean updateWfcFeatureAndProvisionedValues() throws ImsException {
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -0700636 boolean available = isWfcEnabledByPlatform(mContext);
637 boolean enabled = isWfcEnabledByUser(mContext);
638 int mode = getWfcMode(mContext);
639 boolean roaming = isWfcRoamingEnabledByUser(mContext);
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -0800640 boolean isFeatureOn = available && enabled;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -0700641
642 log("updateWfcFeatureAndProvisionedValues: available = " + available
643 + ", enabled = " + enabled
644 + ", mode = " + mode
645 + ", roaming = " + roaming);
646
647 getConfigInterface().setFeatureValue(
Pavel Zhamaitsiake6f99432015-09-11 10:29:30 -0700648 ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_WIFI,
649 TelephonyManager.NETWORK_TYPE_IWLAN,
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -0800650 isFeatureOn ?
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -0700651 ImsConfig.FeatureValueConstants.ON :
652 ImsConfig.FeatureValueConstants.OFF,
Pavel Zhamaitsiakf4b90322016-01-26 14:34:09 -0800653 mImsConfigListener);
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -0700654
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -0800655 if (!isFeatureOn) {
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -0700656 mode = ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED;
657 roaming = false;
658 }
659 setWfcModeInternal(mContext, mode);
660 setWfcRoamingSettingInternal(mContext, roaming);
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -0700661
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -0800662 return isFeatureOn;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -0700663 }
664
Etan Cohenabbd7882014-09-26 22:35:35 -0700665 private ImsManager(Context context, int phoneId) {
Wink Savilleef36ef62014-06-11 08:39:38 -0700666 mContext = context;
Etan Cohenabbd7882014-09-26 22:35:35 -0700667 mPhoneId = phoneId;
Wink Savilleef36ef62014-06-11 08:39:38 -0700668 createImsService(true);
669 }
670
Etan Cohenf4311122015-02-26 17:47:13 -0800671 /*
672 * Returns a flag indicating whether the IMS service is available.
673 */
674 public boolean isServiceAvailable() {
675 if (mImsService != null) {
676 return true;
677 }
678
679 IBinder binder = ServiceManager.checkService(getImsServiceName(mPhoneId));
680 if (binder != null) {
681 return true;
682 }
683
684 return false;
685 }
686
Pavel Zhamaitsiakf4b90322016-01-26 14:34:09 -0800687 public void setImsConfigListener(ImsConfigListener listener) {
688 mImsConfigListener = listener;
689 }
690
Wink Savilleef36ef62014-06-11 08:39:38 -0700691 /**
692 * Opens the IMS service for making calls and/or receiving generic IMS calls.
693 * The caller may make subsquent calls through {@link #makeCall}.
694 * The IMS service will register the device to the operator's network with the credentials
695 * (from ISIM) periodically in order to receive calls from the operator's network.
696 * When the IMS service receives a new call, it will send out an intent with
697 * the provided action string.
698 * The intent contains a call ID extra {@link getCallId} and it can be used to take a call.
699 *
700 * @param serviceClass a service class specified in {@link ImsServiceClass}
701 * For VoLTE service, it MUST be a {@link ImsServiceClass#MMTEL}.
702 * @param incomingCallPendingIntent When an incoming call is received,
703 * the IMS service will call {@link PendingIntent#send(Context, int, Intent)} to
704 * send back the intent to the caller with {@link #INCOMING_CALL_RESULT_CODE}
705 * as the result code and the intent to fill in the call ID; It cannot be null
706 * @param listener To listen to IMS registration events; It cannot be null
707 * @return identifier (greater than 0) for the specified service
708 * @throws NullPointerException if {@code incomingCallPendingIntent}
709 * or {@code listener} is null
710 * @throws ImsException if calling the IMS service results in an error
711 * @see #getCallId
712 * @see #getServiceId
713 */
714 public int open(int serviceClass, PendingIntent incomingCallPendingIntent,
715 ImsConnectionStateListener listener) throws ImsException {
716 checkAndThrowExceptionIfServiceUnavailable();
717
718 if (incomingCallPendingIntent == null) {
719 throw new NullPointerException("incomingCallPendingIntent can't be null");
720 }
721
722 if (listener == null) {
723 throw new NullPointerException("listener can't be null");
724 }
725
726 int result = 0;
727
728 try {
Etan Cohenabbd7882014-09-26 22:35:35 -0700729 result = mImsService.open(mPhoneId, serviceClass, incomingCallPendingIntent,
Wink Savilleef36ef62014-06-11 08:39:38 -0700730 createRegistrationListenerProxy(serviceClass, listener));
731 } catch (RemoteException e) {
732 throw new ImsException("open()", e,
733 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
734 }
735
736 if (result <= 0) {
737 // If the return value is a minus value,
738 // it means that an error occurred in the service.
739 // So, it needs to convert to the reason code specified in ImsReasonInfo.
740 throw new ImsException("open()", (result * (-1)));
741 }
742
743 return result;
744 }
745
746 /**
747 * Closes the specified service ({@link ImsServiceClass}) not to make/receive calls.
748 * All the resources that were allocated to the service are also released.
749 *
750 * @param serviceId a service id to be closed which is obtained from {@link ImsManager#open}
751 * @throws ImsException if calling the IMS service results in an error
752 */
753 public void close(int serviceId) throws ImsException {
754 checkAndThrowExceptionIfServiceUnavailable();
755
756 try {
757 mImsService.close(serviceId);
758 } catch (RemoteException e) {
759 throw new ImsException("close()", e,
760 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
761 } finally {
762 mUt = null;
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -0500763 mConfig = null;
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -0700764 mEcbm = null;
Wink Savilleef36ef62014-06-11 08:39:38 -0700765 }
766 }
767
768 /**
769 * Gets the configuration interface to provision / withdraw the supplementary service settings.
770 *
771 * @param serviceId a service id which is obtained from {@link ImsManager#open}
772 * @return the Ut interface instance
773 * @throws ImsException if getting the Ut interface results in an error
774 */
775 public ImsUtInterface getSupplementaryServiceConfiguration(int serviceId)
776 throws ImsException {
777 // FIXME: manage the multiple Ut interfaces based on the service id
778 if (mUt == null) {
779 checkAndThrowExceptionIfServiceUnavailable();
780
781 try {
782 IImsUt iUt = mImsService.getUtInterface(serviceId);
783
784 if (iUt == null) {
785 throw new ImsException("getSupplementaryServiceConfiguration()",
786 ImsReasonInfo.CODE_UT_NOT_SUPPORTED);
787 }
788
789 mUt = new ImsUt(iUt);
790 } catch (RemoteException e) {
791 throw new ImsException("getSupplementaryServiceConfiguration()", e,
792 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
793 }
794 }
795
796 return mUt;
797 }
798
799 /**
800 * Checks if the IMS service has successfully registered to the IMS network
801 * with the specified service & call type.
802 *
803 * @param serviceId a service id which is obtained from {@link ImsManager#open}
804 * @param serviceType a service type that is specified in {@link ImsCallProfile}
805 * {@link ImsCallProfile#SERVICE_TYPE_NORMAL}
806 * {@link ImsCallProfile#SERVICE_TYPE_EMERGENCY}
807 * @param callType a call type that is specified in {@link ImsCallProfile}
808 * {@link ImsCallProfile#CALL_TYPE_VOICE_N_VIDEO}
809 * {@link ImsCallProfile#CALL_TYPE_VOICE}
810 * {@link ImsCallProfile#CALL_TYPE_VT}
811 * {@link ImsCallProfile#CALL_TYPE_VS}
812 * @return true if the specified service id is connected to the IMS network;
813 * false otherwise
814 * @throws ImsException if calling the IMS service results in an error
815 */
816 public boolean isConnected(int serviceId, int serviceType, int callType)
817 throws ImsException {
818 checkAndThrowExceptionIfServiceUnavailable();
819
820 try {
821 return mImsService.isConnected(serviceId, serviceType, callType);
822 } catch (RemoteException e) {
823 throw new ImsException("isServiceConnected()", e,
824 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
825 }
826 }
827
828 /**
829 * Checks if the specified IMS service is opend.
830 *
831 * @param serviceId a service id which is obtained from {@link ImsManager#open}
832 * @return true if the specified service id is opened; false otherwise
833 * @throws ImsException if calling the IMS service results in an error
834 */
835 public boolean isOpened(int serviceId) throws ImsException {
836 checkAndThrowExceptionIfServiceUnavailable();
837
838 try {
839 return mImsService.isOpened(serviceId);
840 } catch (RemoteException e) {
841 throw new ImsException("isOpened()", e,
842 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
843 }
844 }
845
846 /**
847 * Creates a {@link ImsCallProfile} from the service capabilities & IMS registration state.
848 *
849 * @param serviceId a service id which is obtained from {@link ImsManager#open}
850 * @param serviceType a service type that is specified in {@link ImsCallProfile}
851 * {@link ImsCallProfile#SERVICE_TYPE_NONE}
852 * {@link ImsCallProfile#SERVICE_TYPE_NORMAL}
853 * {@link ImsCallProfile#SERVICE_TYPE_EMERGENCY}
854 * @param callType a call type that is specified in {@link ImsCallProfile}
855 * {@link ImsCallProfile#CALL_TYPE_VOICE}
856 * {@link ImsCallProfile#CALL_TYPE_VT}
857 * {@link ImsCallProfile#CALL_TYPE_VT_TX}
858 * {@link ImsCallProfile#CALL_TYPE_VT_RX}
859 * {@link ImsCallProfile#CALL_TYPE_VT_NODIR}
860 * {@link ImsCallProfile#CALL_TYPE_VS}
861 * {@link ImsCallProfile#CALL_TYPE_VS_TX}
862 * {@link ImsCallProfile#CALL_TYPE_VS_RX}
863 * @return a {@link ImsCallProfile} object
864 * @throws ImsException if calling the IMS service results in an error
865 */
866 public ImsCallProfile createCallProfile(int serviceId,
867 int serviceType, int callType) throws ImsException {
868 checkAndThrowExceptionIfServiceUnavailable();
869
870 try {
871 return mImsService.createCallProfile(serviceId, serviceType, callType);
872 } catch (RemoteException e) {
873 throw new ImsException("createCallProfile()", e,
874 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
875 }
876 }
877
878 /**
879 * Creates a {@link ImsCall} to make a call.
880 *
881 * @param serviceId a service id which is obtained from {@link ImsManager#open}
882 * @param profile a call profile to make the call
883 * (it contains service type, call type, media information, etc.)
884 * @param participants participants to invite the conference call
885 * @param listener listen to the call events from {@link ImsCall}
886 * @return a {@link ImsCall} object
887 * @throws ImsException if calling the IMS service results in an error
888 */
889 public ImsCall makeCall(int serviceId, ImsCallProfile profile, String[] callees,
890 ImsCall.Listener listener) throws ImsException {
891 if (DBG) {
892 log("makeCall :: serviceId=" + serviceId
893 + ", profile=" + profile + ", callees=" + callees);
894 }
895
896 checkAndThrowExceptionIfServiceUnavailable();
897
898 ImsCall call = new ImsCall(mContext, profile);
899
900 call.setListener(listener);
901 ImsCallSession session = createCallSession(serviceId, profile);
902
903 if ((callees != null) && (callees.length == 1)) {
904 call.start(session, callees[0]);
905 } else {
906 call.start(session, callees);
907 }
908
909 return call;
910 }
911
912 /**
913 * Creates a {@link ImsCall} to take an incoming call.
914 *
915 * @param serviceId a service id which is obtained from {@link ImsManager#open}
916 * @param incomingCallIntent the incoming call broadcast intent
917 * @param listener to listen to the call events from {@link ImsCall}
918 * @return a {@link ImsCall} object
919 * @throws ImsException if calling the IMS service results in an error
920 */
921 public ImsCall takeCall(int serviceId, Intent incomingCallIntent,
922 ImsCall.Listener listener) throws ImsException {
923 if (DBG) {
924 log("takeCall :: serviceId=" + serviceId
925 + ", incomingCall=" + incomingCallIntent);
926 }
927
928 checkAndThrowExceptionIfServiceUnavailable();
929
930 if (incomingCallIntent == null) {
931 throw new ImsException("Can't retrieve session with null intent",
932 ImsReasonInfo.CODE_LOCAL_ILLEGAL_ARGUMENT);
933 }
934
935 int incomingServiceId = getServiceId(incomingCallIntent);
936
937 if (serviceId != incomingServiceId) {
938 throw new ImsException("Service id is mismatched in the incoming call intent",
939 ImsReasonInfo.CODE_LOCAL_ILLEGAL_ARGUMENT);
940 }
941
942 String callId = getCallId(incomingCallIntent);
943
944 if (callId == null) {
945 throw new ImsException("Call ID missing in the incoming call intent",
946 ImsReasonInfo.CODE_LOCAL_ILLEGAL_ARGUMENT);
947 }
948
949 try {
950 IImsCallSession session = mImsService.getPendingCallSession(serviceId, callId);
951
952 if (session == null) {
953 throw new ImsException("No pending session for the call",
954 ImsReasonInfo.CODE_LOCAL_NO_PENDING_CALL);
955 }
956
957 ImsCall call = new ImsCall(mContext, session.getCallProfile());
958
959 call.attachSession(new ImsCallSession(session));
960 call.setListener(listener);
961
962 return call;
963 } catch (Throwable t) {
964 throw new ImsException("takeCall()", t, ImsReasonInfo.CODE_UNSPECIFIED);
965 }
966 }
967
968 /**
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -0500969 * Gets the config interface to get/set service/capability parameters.
970 *
971 * @return the ImsConfig instance.
972 * @throws ImsException if getting the setting interface results in an error.
973 */
974 public ImsConfig getConfigInterface() throws ImsException {
975
976 if (mConfig == null) {
977 checkAndThrowExceptionIfServiceUnavailable();
978
979 try {
Etan Cohenabbd7882014-09-26 22:35:35 -0700980 IImsConfig config = mImsService.getConfigInterface(mPhoneId);
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -0500981 if (config == null) {
982 throw new ImsException("getConfigInterface()",
983 ImsReasonInfo.CODE_LOCAL_SERVICE_UNAVAILABLE);
984 }
Libin.Tang@motorola.com54953c72014-08-07 15:02:08 -0500985 mConfig = new ImsConfig(config, mContext);
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -0500986 } catch (RemoteException e) {
987 throw new ImsException("getConfigInterface()", e,
988 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
989 }
990 }
991 if (DBG) log("getConfigInterface(), mConfig= " + mConfig);
992 return mConfig;
993 }
994
Etan Cohen82f78122014-12-15 10:10:14 -0800995 public void setUiTTYMode(Context context, int serviceId, int uiTtyMode, Message onComplete)
Shriram Ganeshc403b7b2014-08-14 14:18:57 +0530996 throws ImsException {
997
Etan Cohen82f78122014-12-15 10:10:14 -0800998 checkAndThrowExceptionIfServiceUnavailable();
Shriram Ganeshc403b7b2014-08-14 14:18:57 +0530999
Etan Cohen82f78122014-12-15 10:10:14 -08001000 try {
1001 mImsService.setUiTTYMode(serviceId, uiTtyMode, onComplete);
1002 } catch (RemoteException e) {
1003 throw new ImsException("setTTYMode()", e,
1004 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1005 }
1006
Junda Liue7663c02015-06-23 11:16:26 -07001007 if (!getBooleanCarrierConfig(context,
1008 CarrierConfigManager.KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL)) {
Etan Cohen82f78122014-12-15 10:10:14 -08001009 setAdvanced4GMode((uiTtyMode == TelecomManager.TTY_MODE_OFF) &&
1010 isEnhanced4gLteModeSettingEnabledByUser(context));
1011 }
Shriram Ganeshc403b7b2014-08-14 14:18:57 +05301012 }
1013
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -05001014 /**
Junda Liue7663c02015-06-23 11:16:26 -07001015 * Get the boolean config from carrier config manager.
1016 *
1017 * @param context the context to get carrier service
1018 * @param key config key defined in CarrierConfigManager
1019 * @return boolean value of corresponding key.
1020 */
1021 private static boolean getBooleanCarrierConfig(Context context, String key) {
1022 CarrierConfigManager configManager = (CarrierConfigManager) context.getSystemService(
1023 Context.CARRIER_CONFIG_SERVICE);
Jonathan Basseri2acea6f2015-07-01 15:00:38 -07001024 PersistableBundle b = null;
Junda Liue7663c02015-06-23 11:16:26 -07001025 if (configManager != null) {
Jonathan Basseri2acea6f2015-07-01 15:00:38 -07001026 b = configManager.getConfig();
1027 }
1028 if (b != null) {
1029 return b.getBoolean(key);
Junda Liue7663c02015-06-23 11:16:26 -07001030 } else {
1031 // Return static default defined in CarrierConfigManager.
1032 return CarrierConfigManager.getDefaultConfig().getBoolean(key);
1033 }
1034 }
1035
1036 /**
fionaxu5803ef02016-03-08 11:48:48 -08001037 * Get the int config from carrier config manager.
1038 *
1039 * @param context the context to get carrier service
1040 * @param key config key defined in CarrierConfigManager
1041 * @return integer value of corresponding key.
1042 */
1043 private static int getIntCarrierConfig(Context context, String key) {
1044 CarrierConfigManager configManager = (CarrierConfigManager) context.getSystemService(
1045 Context.CARRIER_CONFIG_SERVICE);
1046 PersistableBundle b = null;
1047 if (configManager != null) {
1048 b = configManager.getConfig();
1049 }
1050 if (b != null) {
1051 return b.getInt(key);
1052 } else {
1053 // Return static default defined in CarrierConfigManager.
1054 return CarrierConfigManager.getDefaultConfig().getInt(key);
1055 }
1056 }
1057
1058 /**
Wink Savilleef36ef62014-06-11 08:39:38 -07001059 * Gets the call ID from the specified incoming call broadcast intent.
1060 *
1061 * @param incomingCallIntent the incoming call broadcast intent
1062 * @return the call ID or null if the intent does not contain it
1063 */
1064 private static String getCallId(Intent incomingCallIntent) {
1065 if (incomingCallIntent == null) {
1066 return null;
1067 }
1068
1069 return incomingCallIntent.getStringExtra(EXTRA_CALL_ID);
1070 }
1071
1072 /**
1073 * Gets the service type from the specified incoming call broadcast intent.
1074 *
1075 * @param incomingCallIntent the incoming call broadcast intent
1076 * @return the service identifier or -1 if the intent does not contain it
1077 */
1078 private static int getServiceId(Intent incomingCallIntent) {
1079 if (incomingCallIntent == null) {
1080 return (-1);
1081 }
1082
1083 return incomingCallIntent.getIntExtra(EXTRA_SERVICE_ID, -1);
1084 }
1085
1086 /**
1087 * Binds the IMS service only if the service is not created.
1088 */
1089 private void checkAndThrowExceptionIfServiceUnavailable()
1090 throws ImsException {
1091 if (mImsService == null) {
1092 createImsService(true);
1093
1094 if (mImsService == null) {
1095 throw new ImsException("Service is unavailable",
1096 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1097 }
1098 }
1099 }
1100
Etan Cohenabbd7882014-09-26 22:35:35 -07001101 private static String getImsServiceName(int phoneId) {
1102 // TODO: MSIM implementation needs to decide on service name as a function of phoneId
Etan Cohend7727462014-07-12 14:54:10 -07001103 return IMS_SERVICE;
1104 }
1105
Wink Savilleef36ef62014-06-11 08:39:38 -07001106 /**
1107 * Binds the IMS service to make/receive the call.
1108 */
1109 private void createImsService(boolean checkService) {
1110 if (checkService) {
Etan Cohenabbd7882014-09-26 22:35:35 -07001111 IBinder binder = ServiceManager.checkService(getImsServiceName(mPhoneId));
Wink Savilleef36ef62014-06-11 08:39:38 -07001112
1113 if (binder == null) {
1114 return;
1115 }
1116 }
1117
Etan Cohenabbd7882014-09-26 22:35:35 -07001118 IBinder b = ServiceManager.getService(getImsServiceName(mPhoneId));
Wink Savilleef36ef62014-06-11 08:39:38 -07001119
1120 if (b != null) {
1121 try {
1122 b.linkToDeath(mDeathRecipient, 0);
1123 } catch (RemoteException e) {
1124 }
1125 }
1126
1127 mImsService = IImsService.Stub.asInterface(b);
1128 }
1129
1130 /**
1131 * Creates a {@link ImsCallSession} with the specified call profile.
1132 * Use other methods, if applicable, instead of interacting with
1133 * {@link ImsCallSession} directly.
1134 *
1135 * @param serviceId a service id which is obtained from {@link ImsManager#open}
1136 * @param profile a call profile to make the call
1137 */
1138 private ImsCallSession createCallSession(int serviceId,
1139 ImsCallProfile profile) throws ImsException {
1140 try {
1141 return new ImsCallSession(mImsService.createCallSession(serviceId, profile, null));
1142 } catch (RemoteException e) {
1143 return null;
1144 }
1145 }
1146
1147 private ImsRegistrationListenerProxy createRegistrationListenerProxy(int serviceClass,
1148 ImsConnectionStateListener listener) {
1149 ImsRegistrationListenerProxy proxy =
1150 new ImsRegistrationListenerProxy(serviceClass, listener);
1151 return proxy;
1152 }
1153
Etan Cohena00c9192014-12-23 15:02:29 -08001154 private static void log(String s) {
Wink Savilleef36ef62014-06-11 08:39:38 -07001155 Rlog.d(TAG, s);
1156 }
1157
Etan Cohena00c9192014-12-23 15:02:29 -08001158 private static void loge(String s) {
Wink Savilleef36ef62014-06-11 08:39:38 -07001159 Rlog.e(TAG, s);
1160 }
1161
Etan Cohena00c9192014-12-23 15:02:29 -08001162 private static void loge(String s, Throwable t) {
Wink Savilleef36ef62014-06-11 08:39:38 -07001163 Rlog.e(TAG, s, t);
1164 }
1165
1166 /**
ram7da5a112014-07-16 20:59:27 +05301167 * Used for turning on IMS.if its off already
1168 */
Etan Cohen82f78122014-12-15 10:10:14 -08001169 private void turnOnIms() throws ImsException {
Etan Cohen0c9c09e2014-07-25 11:09:12 -07001170 checkAndThrowExceptionIfServiceUnavailable();
1171
ram7da5a112014-07-16 20:59:27 +05301172 try {
Etan Cohenabbd7882014-09-26 22:35:35 -07001173 mImsService.turnOnIms(mPhoneId);
ram7da5a112014-07-16 20:59:27 +05301174 } catch (RemoteException e) {
1175 throw new ImsException("turnOnIms() ", e, ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1176 }
1177 }
1178
Omkar Kolangade75f3ca32014-10-24 11:10:52 -07001179 private boolean isImsTurnOffAllowed() {
1180 return getBooleanCarrierConfig(mContext,
1181 CarrierConfigManager.KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL)
1182 && (!isWfcEnabledByPlatform(mContext)
1183 || !isWfcEnabledByUser(mContext));
1184 }
1185
Etan Cohen82f78122014-12-15 10:10:14 -08001186 private void setAdvanced4GMode(boolean turnOn) throws ImsException {
Etan Cohencfc784d2014-08-07 18:40:31 -07001187 checkAndThrowExceptionIfServiceUnavailable();
1188
Omkar Kolangade75f3ca32014-10-24 11:10:52 -07001189 try {
1190 ImsConfig config = getConfigInterface();
1191 if (config != null && (turnOn || !isImsTurnOffAllowed())) {
1192 config.setFeatureValue(ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE,
Pavel Zhamaitsiakf4b90322016-01-26 14:34:09 -08001193 TelephonyManager.NETWORK_TYPE_LTE, turnOn ? 1 : 0, mImsConfigListener);
1194
Omkar Kolangade75f3ca32014-10-24 11:10:52 -07001195 if (isVtEnabledByPlatform(mContext)) {
1196 // TODO: once VT is available on platform:
1197 // - replace the '1' with the current user configuration of VT.
1198 // - separate exception checks for setFeatureValue() failures for VoLTE and VT.
1199 // I.e. if VoLTE fails still try to configure VT.
1200 config.setFeatureValue(ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_LTE,
Pavel Zhamaitsiakf4b90322016-01-26 14:34:09 -08001201 TelephonyManager.NETWORK_TYPE_LTE, turnOn ? 1 : 0, mImsConfigListener);
Omkar Kolangade75f3ca32014-10-24 11:10:52 -07001202 }
Etan Cohenb651fa52014-10-22 10:51:29 -07001203 }
Omkar Kolangade75f3ca32014-10-24 11:10:52 -07001204 } catch (ImsException e) {
1205 log("setAdvanced4GMode() : " + e);
Etan Cohencfc784d2014-08-07 18:40:31 -07001206 }
Etan Cohencfc784d2014-08-07 18:40:31 -07001207 if (turnOn) {
1208 turnOnIms();
Omkar Kolangade75f3ca32014-10-24 11:10:52 -07001209 } else if (isImsTurnOffAllowed()) {
Etan Cohencfc784d2014-08-07 18:40:31 -07001210 log("setAdvanced4GMode() : imsServiceAllowTurnOff -> turnOffIms");
1211 turnOffIms();
1212 }
1213 }
1214
ram7da5a112014-07-16 20:59:27 +05301215 /**
1216 * Used for turning off IMS completely in order to make the device CSFB'ed.
1217 * Once turned off, all calls will be over CS.
1218 */
Etan Cohen82f78122014-12-15 10:10:14 -08001219 private void turnOffIms() throws ImsException {
Etan Cohen0c9c09e2014-07-25 11:09:12 -07001220 checkAndThrowExceptionIfServiceUnavailable();
1221
ram7da5a112014-07-16 20:59:27 +05301222 try {
Etan Cohenabbd7882014-09-26 22:35:35 -07001223 mImsService.turnOffIms(mPhoneId);
ram7da5a112014-07-16 20:59:27 +05301224 } catch (RemoteException e) {
1225 throw new ImsException("turnOffIms() ", e, ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1226 }
1227 }
1228
1229 /**
Wink Savilleef36ef62014-06-11 08:39:38 -07001230 * Death recipient class for monitoring IMS service.
1231 */
1232 private class ImsServiceDeathRecipient implements IBinder.DeathRecipient {
1233 @Override
1234 public void binderDied() {
1235 mImsService = null;
1236 mUt = null;
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -05001237 mConfig = null;
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -07001238 mEcbm = null;
Wink Savilleef36ef62014-06-11 08:39:38 -07001239
1240 if (mContext != null) {
Etan Cohend7727462014-07-12 14:54:10 -07001241 Intent intent = new Intent(ACTION_IMS_SERVICE_DOWN);
Etan Cohenabbd7882014-09-26 22:35:35 -07001242 intent.putExtra(EXTRA_PHONE_ID, mPhoneId);
Etan Cohend7727462014-07-12 14:54:10 -07001243 mContext.sendBroadcast(new Intent(intent));
Wink Savilleef36ef62014-06-11 08:39:38 -07001244 }
1245 }
1246 }
1247
1248 /**
1249 * Adapter class for {@link IImsRegistrationListener}.
1250 */
1251 private class ImsRegistrationListenerProxy extends IImsRegistrationListener.Stub {
1252 private int mServiceClass;
1253 private ImsConnectionStateListener mListener;
1254
1255 public ImsRegistrationListenerProxy(int serviceClass,
1256 ImsConnectionStateListener listener) {
1257 mServiceClass = serviceClass;
1258 mListener = listener;
1259 }
1260
1261 public boolean isSameProxy(int serviceClass) {
1262 return (mServiceClass == serviceClass);
1263 }
1264
Omkar Kolangadea7ced642015-05-04 17:55:13 -07001265 @Deprecated
Wink Savilleef36ef62014-06-11 08:39:38 -07001266 public void registrationConnected() {
1267 if (DBG) {
1268 log("registrationConnected ::");
1269 }
1270
1271 if (mListener != null) {
1272 mListener.onImsConnected();
1273 }
1274 }
1275
Omkar Kolangadea7ced642015-05-04 17:55:13 -07001276 @Deprecated
Rekha Kumar14631742015-02-04 10:47:00 -08001277 public void registrationProgressing() {
Wink Savilleef36ef62014-06-11 08:39:38 -07001278 if (DBG) {
Rekha Kumar14631742015-02-04 10:47:00 -08001279 log("registrationProgressing ::");
Wink Savilleef36ef62014-06-11 08:39:38 -07001280 }
1281
1282 if (mListener != null) {
Rekha Kumar14631742015-02-04 10:47:00 -08001283 mListener.onImsProgressing();
1284 }
1285 }
1286
1287 @Override
Omkar Kolangadea7ced642015-05-04 17:55:13 -07001288 public void registrationConnectedWithRadioTech(int imsRadioTech) {
1289 // Note: imsRadioTech value maps to RIL_RADIO_TECHNOLOGY
1290 // values in ServiceState.java.
1291 if (DBG) {
1292 log("registrationConnectedWithRadioTech :: imsRadioTech=" + imsRadioTech);
1293 }
1294
1295 if (mListener != null) {
1296 mListener.onImsConnected();
1297 }
1298 }
1299
1300 @Override
1301 public void registrationProgressingWithRadioTech(int imsRadioTech) {
1302 // Note: imsRadioTech value maps to RIL_RADIO_TECHNOLOGY
1303 // values in ServiceState.java.
1304 if (DBG) {
1305 log("registrationProgressingWithRadioTech :: imsRadioTech=" + imsRadioTech);
1306 }
1307
1308 if (mListener != null) {
1309 mListener.onImsProgressing();
1310 }
1311 }
1312
1313 @Override
Rekha Kumar14631742015-02-04 10:47:00 -08001314 public void registrationDisconnected(ImsReasonInfo imsReasonInfo) {
1315 if (DBG) {
1316 log("registrationDisconnected :: imsReasonInfo" + imsReasonInfo);
1317 }
1318
1319 if (mListener != null) {
1320 mListener.onImsDisconnected(imsReasonInfo);
Wink Savilleef36ef62014-06-11 08:39:38 -07001321 }
1322 }
1323
1324 @Override
1325 public void registrationResumed() {
1326 if (DBG) {
1327 log("registrationResumed ::");
1328 }
1329
1330 if (mListener != null) {
1331 mListener.onImsResumed();
1332 }
1333 }
1334
1335 @Override
1336 public void registrationSuspended() {
1337 if (DBG) {
1338 log("registrationSuspended ::");
1339 }
1340
1341 if (mListener != null) {
1342 mListener.onImsSuspended();
1343 }
1344 }
1345
1346 @Override
1347 public void registrationServiceCapabilityChanged(int serviceClass, int event) {
1348 log("registrationServiceCapabilityChanged :: serviceClass=" +
1349 serviceClass + ", event=" + event);
1350
1351 if (mListener != null) {
1352 mListener.onImsConnected();
1353 }
1354 }
ram7da5a112014-07-16 20:59:27 +05301355
1356 @Override
1357 public void registrationFeatureCapabilityChanged(int serviceClass,
1358 int[] enabledFeatures, int[] disabledFeatures) {
1359 log("registrationFeatureCapabilityChanged :: serviceClass=" +
1360 serviceClass);
Libin.Tang@motorola.come2296782014-08-19 14:20:01 -05001361 if (mListener != null) {
1362 mListener.onFeatureCapabilityChanged(serviceClass,
1363 enabledFeatures, disabledFeatures);
1364 }
ram7da5a112014-07-16 20:59:27 +05301365 }
1366
Shriram Ganeshd3adfad2015-05-31 10:06:15 -07001367 @Override
1368 public void voiceMessageCountUpdate(int count) {
1369 log("voiceMessageCountUpdate :: count=" + count);
1370
1371 if (mListener != null) {
1372 mListener.onVoiceMessageCountChanged(count);
1373 }
1374 }
1375
Pavel Zhamaitsiak4de9cbb2016-02-11 17:21:05 -08001376 @Override
1377 public void registrationAssociatedUriChanged(Uri[] uris) {
1378 if (DBG) log("registrationAssociatedUriChanged ::");
1379
1380 if (mListener != null) {
1381 mListener.registrationAssociatedUriChanged(uris);
1382 }
1383 }
Wink Savilleef36ef62014-06-11 08:39:38 -07001384 }
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -07001385 /**
1386 * Gets the ECBM interface to request ECBM exit.
1387 *
1388 * @param serviceId a service id which is obtained from {@link ImsManager#open}
1389 * @return the ECBM interface instance
1390 * @throws ImsException if getting the ECBM interface results in an error
1391 */
1392 public ImsEcbm getEcbmInterface(int serviceId) throws ImsException {
1393 if (mEcbm == null) {
1394 checkAndThrowExceptionIfServiceUnavailable();
1395
1396 try {
1397 IImsEcbm iEcbm = mImsService.getEcbmInterface(serviceId);
1398
1399 if (iEcbm == null) {
1400 throw new ImsException("getEcbmInterface()",
1401 ImsReasonInfo.CODE_ECBM_NOT_SUPPORTED);
1402 }
1403 mEcbm = new ImsEcbm(iEcbm);
1404 } catch (RemoteException e) {
1405 throw new ImsException("getEcbmInterface()", e,
1406 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1407 }
1408 }
1409 return mEcbm;
1410 }
Pavel Zhamaitsiak8c065f52015-11-10 14:36:44 -08001411
1412 /**
1413 * Resets ImsManager settings back to factory defaults.
1414 *
1415 * @hide
1416 */
1417 public static void factoryReset(Context context) {
1418 // Set VoLTE to default
1419 android.provider.Settings.Global.putInt(context.getContentResolver(),
1420 android.provider.Settings.Global.ENHANCED_4G_MODE_ENABLED,
1421 ImsConfig.FeatureValueConstants.ON);
1422
1423 // Set VoWiFi to default
1424 android.provider.Settings.Global.putInt(context.getContentResolver(),
1425 android.provider.Settings.Global.WFC_IMS_ENABLED,
fionaxu5803ef02016-03-08 11:48:48 -08001426 getBooleanCarrierConfig(context,
1427 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL) ?
1428 ImsConfig.FeatureValueConstants.ON : ImsConfig.FeatureValueConstants.OFF);
Pavel Zhamaitsiak8c065f52015-11-10 14:36:44 -08001429
1430 // Set VoWiFi mode to default
1431 android.provider.Settings.Global.putInt(context.getContentResolver(),
1432 android.provider.Settings.Global.WFC_IMS_MODE,
fionaxu5803ef02016-03-08 11:48:48 -08001433 getIntCarrierConfig(context,
1434 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT));
Pavel Zhamaitsiak8c065f52015-11-10 14:36:44 -08001435
1436 // Set VoWiFi roaming to default
1437 android.provider.Settings.Global.putInt(context.getContentResolver(),
1438 android.provider.Settings.Global.WFC_IMS_ROAMING_ENABLED,
fionaxu5803ef02016-03-08 11:48:48 -08001439 getBooleanCarrierConfig(context,
1440 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_ENABLED_BOOL) ?
1441 ImsConfig.FeatureValueConstants.ON : ImsConfig.FeatureValueConstants.OFF);
Pavel Zhamaitsiak8c065f52015-11-10 14:36:44 -08001442
1443 // Set VT to default
1444 SharedPreferences sharedPrefs =
1445 PreferenceManager.getDefaultSharedPreferences(context);
1446 SharedPreferences.Editor editor = sharedPrefs.edit();
1447 editor.putBoolean(PREF_ENABLE_VIDEO_CALLING_KEY, true);
1448 editor.commit();
1449
1450 // Push settings to ImsConfig
1451 ImsManager.updateImsServiceConfig(context,
1452 SubscriptionManager.getDefaultVoicePhoneId(), true);
1453 }
Jack Yu2f102bd2015-12-28 15:31:48 -08001454
1455 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1456 pw.println("ImsManager:");
1457 pw.println(" mPhoneId = " + mPhoneId);
1458 pw.println(" mConfigUpdated = " + mConfigUpdated);
1459 pw.println(" mImsService = " + mImsService);
1460
1461 pw.println(" isGbaValid = " + isGbaValid(mContext));
1462 pw.println(" isImsTurnOffAllowed = " + isImsTurnOffAllowed());
1463 pw.println(" isNonTtyOrTtyOnVolteEnabled = " + isNonTtyOrTtyOnVolteEnabled(mContext));
1464
1465 pw.println(" isVolteEnabledByPlatform = " + isVolteEnabledByPlatform(mContext));
1466 pw.println(" isVolteProvisionedOnDevice = " + isVolteProvisionedOnDevice(mContext));
1467 pw.println(" isEnhanced4gLteModeSettingEnabledByUser = " +
1468 isEnhanced4gLteModeSettingEnabledByUser(mContext));
1469 pw.println(" isVtEnabledByPlatform = " + isVtEnabledByPlatform(mContext));
1470 pw.println(" isVtEnabledByUser = " + isVtEnabledByUser(mContext));
1471
1472 pw.println(" isWfcEnabledByPlatform = " + isWfcEnabledByPlatform(mContext));
1473 pw.println(" isWfcEnabledByUser = " + isWfcEnabledByUser(mContext));
1474 pw.println(" getWfcMode = " + getWfcMode(mContext));
1475 pw.println(" isWfcRoamingEnabledByUser = " + isWfcRoamingEnabledByUser(mContext));
1476
1477 pw.flush();
1478 }
Wink Savilleef36ef62014-06-11 08:39:38 -07001479}