blob: 32d21e937989b54d2b34a6007ab8512c4b659fc0 [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;
20import android.content.Context;
21import android.content.Intent;
Pavel Zhamaitsiak4de9cbb2016-02-11 17:21:05 -080022import android.net.Uri;
Wink Savilleef36ef62014-06-11 08:39:38 -070023import android.os.IBinder;
Wink Savilleef36ef62014-06-11 08:39:38 -070024import android.os.Message;
Naveen Kalla525c3a22017-02-06 14:46:42 -080025import android.os.Parcel;
Jonathan Basseri2acea6f2015-07-01 15:00:38 -070026import android.os.PersistableBundle;
Wink Savilleef36ef62014-06-11 08:39:38 -070027import android.os.RemoteException;
Etan Cohenaf55a402014-09-04 22:34:41 -070028import android.os.SystemProperties;
Etan Cohen82f78122014-12-15 10:10:14 -080029import android.provider.Settings;
30import android.telecom.TelecomManager;
Junda Liue7663c02015-06-23 11:16:26 -070031import android.telephony.CarrierConfigManager;
Wink Savilleef36ef62014-06-11 08:39:38 -070032import android.telephony.Rlog;
Meng Wangbb98b9b2016-12-07 16:27:15 -080033import android.telephony.ServiceState;
Etan Cohen82f78122014-12-15 10:10:14 -080034import android.telephony.SubscriptionManager;
Etan Cohencfc784d2014-08-07 18:40:31 -070035import android.telephony.TelephonyManager;
Hall Liue511a202017-08-17 15:49:58 -070036import android.util.Log;
Wink Savilleef36ef62014-06-11 08:39:38 -070037
38import com.android.ims.internal.IImsCallSession;
Naveen Kalla525c3a22017-02-06 14:46:42 -080039import com.android.ims.internal.IImsConfig;
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -070040import com.android.ims.internal.IImsEcbm;
Tyler Gunn4d128b62016-04-13 15:44:38 -070041import com.android.ims.internal.IImsMultiEndpoint;
Brad Ebinger44fd8af2017-12-14 14:24:02 -080042import com.android.ims.internal.IImsRegistrationCallback;
Wink Savilleef36ef62014-06-11 08:39:38 -070043import com.android.ims.internal.IImsRegistrationListener;
Wink Savilleef36ef62014-06-11 08:39:38 -070044import com.android.ims.internal.IImsUt;
45import com.android.ims.internal.ImsCallSession;
Brad Ebinger16780ff2017-01-26 11:18:21 -080046import com.android.internal.annotations.VisibleForTesting;
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -050047
Jack Yu2f102bd2015-12-28 15:31:48 -080048import java.io.FileDescriptor;
49import java.io.PrintWriter;
Naveen Kalla525c3a22017-02-06 14:46:42 -080050import java.util.ArrayList;
Etan Cohend7727462014-07-12 14:54:10 -070051import java.util.HashMap;
Brad Ebinger16780ff2017-01-26 11:18:21 -080052import java.util.HashSet;
Brad Ebinger16780ff2017-01-26 11:18:21 -080053import java.util.Set;
Malcolm Chen18837ff2017-10-25 17:05:41 -070054import java.util.concurrent.ConcurrentLinkedDeque;
Brad Ebinger44fd8af2017-12-14 14:24:02 -080055import java.util.concurrent.CopyOnWriteArraySet;
Etan Cohend7727462014-07-12 14:54:10 -070056
Wink Savilleef36ef62014-06-11 08:39:38 -070057/**
58 * Provides APIs for IMS services, such as initiating IMS calls, and provides access to
59 * the operator's IMS network. This class is the starting point for any IMS actions.
60 * You can acquire an instance of it with {@link #getInstance getInstance()}.</p>
61 * <p>The APIs in this class allows you to:</p>
62 *
63 * @hide
64 */
65public class ImsManager {
Etan Cohen19604c02014-08-11 14:32:57 -070066
Etan Cohenaf55a402014-09-04 22:34:41 -070067 /*
68 * Debug flag to override configuration flag
69 */
Etan Cohenb651fa52014-10-22 10:51:29 -070070 public static final String PROPERTY_DBG_VOLTE_AVAIL_OVERRIDE = "persist.dbg.volte_avail_ovr";
71 public static final int PROPERTY_DBG_VOLTE_AVAIL_OVERRIDE_DEFAULT = 0;
Etan Cohenea2b5832014-10-23 18:50:35 -070072 public static final String PROPERTY_DBG_VT_AVAIL_OVERRIDE = "persist.dbg.vt_avail_ovr";
73 public static final int PROPERTY_DBG_VT_AVAIL_OVERRIDE_DEFAULT = 0;
Etan Cohena00c9192014-12-23 15:02:29 -080074 public static final String PROPERTY_DBG_WFC_AVAIL_OVERRIDE = "persist.dbg.wfc_avail_ovr";
75 public static final int PROPERTY_DBG_WFC_AVAIL_OVERRIDE_DEFAULT = 0;
Meng Wang9352c432016-06-08 14:22:20 -070076 public static final String PROPERTY_DBG_ALLOW_IMS_OFF_OVERRIDE = "persist.dbg.allow_ims_off";
77 public static final int PROPERTY_DBG_ALLOW_IMS_OFF_OVERRIDE_DEFAULT = 0;
Etan Cohenaf55a402014-09-04 22:34:41 -070078
Wink Savilleef36ef62014-06-11 08:39:38 -070079 /**
Wink Savilleef36ef62014-06-11 08:39:38 -070080 * 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.
Brad Ebinger16780ff2017-01-26 11:18:21 -080094 * @deprecated
Wink Savilleef36ef62014-06-11 08:39:38 -070095 * @hide
96 */
97 public static final String ACTION_IMS_SERVICE_UP =
98 "com.android.ims.IMS_SERVICE_UP";
99
100 /**
101 * Action to broadcast when ImsService is down.
102 * Internal use only.
Brad Ebinger16780ff2017-01-26 11:18:21 -0800103 * @deprecated
Wink Savilleef36ef62014-06-11 08:39:38 -0700104 * @hide
105 */
106 public static final String ACTION_IMS_SERVICE_DOWN =
107 "com.android.ims.IMS_SERVICE_DOWN";
108
109 /**
Pavel Zhamaitsiak0c2f15c2015-03-12 15:37:54 -0700110 * Action to broadcast when ImsService registration fails.
111 * Internal use only.
112 * @hide
113 */
114 public static final String ACTION_IMS_REGISTRATION_ERROR =
115 "com.android.ims.REGISTRATION_ERROR";
116
117 /**
Etan Cohend7727462014-07-12 14:54:10 -0700118 * Part of the ACTION_IMS_SERVICE_UP or _DOWN intents.
Etan Cohenabbd7882014-09-26 22:35:35 -0700119 * A long value; the phone ID corresponding to the IMS service coming up or down.
Etan Cohend7727462014-07-12 14:54:10 -0700120 * Internal use only.
121 * @hide
122 */
Etan Cohenabbd7882014-09-26 22:35:35 -0700123 public static final String EXTRA_PHONE_ID = "android:phone_id";
Etan Cohend7727462014-07-12 14:54:10 -0700124
125 /**
Wink Savilleef36ef62014-06-11 08:39:38 -0700126 * Action for the incoming call intent for the Phone app.
127 * Internal use only.
128 * @hide
129 */
130 public static final String ACTION_IMS_INCOMING_CALL =
131 "com.android.ims.IMS_INCOMING_CALL";
132
133 /**
134 * Part of the ACTION_IMS_INCOMING_CALL intents.
135 * An integer value; service identifier obtained from {@link ImsManager#open}.
136 * Internal use only.
137 * @hide
138 */
139 public static final String EXTRA_SERVICE_ID = "android:imsServiceId";
140
141 /**
142 * Part of the ACTION_IMS_INCOMING_CALL intents.
143 * An boolean value; Flag to indicate that the incoming call is a normal call or call for USSD.
144 * The value "true" indicates that the incoming call is for USSD.
145 * Internal use only.
146 * @hide
147 */
148 public static final String EXTRA_USSD = "android:ussd";
149
Shriram Ganeshd3adfad2015-05-31 10:06:15 -0700150 /**
151 * Part of the ACTION_IMS_INCOMING_CALL intents.
152 * A boolean value; Flag to indicate whether the call is an unknown
153 * dialing call. Such calls are originated by sending commands (like
154 * AT commands) directly to modem without Android involvement.
155 * Even though they are not incoming calls, they are propagated
156 * to Phone app using same ACTION_IMS_INCOMING_CALL intent.
157 * Internal use only.
158 * @hide
159 */
Anju Mathapati9c033792015-06-16 16:33:16 -0700160 public static final String EXTRA_IS_UNKNOWN_CALL = "android:isUnknown";
Shriram Ganeshd3adfad2015-05-31 10:06:15 -0700161
Malcolm Chen18837ff2017-10-25 17:05:41 -0700162 private static final int SYSTEM_PROPERTY_NOT_SET = -1;
163
164 // -1 indicates a subscriptionProperty value that is never set.
165 private static final int SUB_PROPERTY_NOT_INITIALIZED = -1;
166
Wink Savilleef36ef62014-06-11 08:39:38 -0700167 private static final String TAG = "ImsManager";
168 private static final boolean DBG = true;
169
Wink Saville1e5a38a2014-10-23 10:24:46 -0700170 private static HashMap<Integer, ImsManager> sImsManagerInstances =
171 new HashMap<Integer, ImsManager>();
Etan Cohend7727462014-07-12 14:54:10 -0700172
Wink Savilleef36ef62014-06-11 08:39:38 -0700173 private Context mContext;
Brad Ebinger16417b42017-03-07 13:48:50 -0800174 private CarrierConfigManager mConfigManager;
Etan Cohenabbd7882014-09-26 22:35:35 -0700175 private int mPhoneId;
Brad Ebinger16780ff2017-01-26 11:18:21 -0800176 private final boolean mConfigDynamicBind;
Brad Ebingera7c32432017-11-06 15:19:27 -0800177 private ImsServiceProxy mImsServiceProxy = null;
Wink Savilleef36ef62014-06-11 08:39:38 -0700178 private ImsServiceDeathRecipient mDeathRecipient = new ImsServiceDeathRecipient();
179 // Ut interface for the supplementary service configuration
180 private ImsUt mUt = null;
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -0500181 // Interface to get/set ims config items
182 private ImsConfig mConfig = null;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -0700183 private boolean mConfigUpdated = false;
Wink Savilleef36ef62014-06-11 08:39:38 -0700184
Pavel Zhamaitsiakf4b90322016-01-26 14:34:09 -0800185 private ImsConfigListener mImsConfigListener;
186
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -0700187 // ECBM interface
188 private ImsEcbm mEcbm = null;
189
Tyler Gunn4d128b62016-04-13 15:44:38 -0700190 private ImsMultiEndpoint mMultiEndpoint = null;
191
Brad Ebinger44fd8af2017-12-14 14:24:02 -0800192 private Set<ImsServiceProxy.IFeatureUpdate> mStatusCallbacks = new CopyOnWriteArraySet<>();
Brad Ebinger16780ff2017-01-26 11:18:21 -0800193
194 // Keep track of the ImsRegistrationListenerProxys that have been created so that we can
195 // remove them from the ImsService.
Brad Ebinger9a0280c2017-06-01 15:58:48 -0700196 private final Set<ImsConnectionStateListener> mRegistrationListeners = new HashSet<>();
197
Brad Ebinger44fd8af2017-12-14 14:24:02 -0800198
199 // Used for compatibility with the old Registration method
200 // TODO: Remove once the compat layer is in place
201 private final ImsRegistrationListenerProxy mImsRegistrationListenerProxy =
Brad Ebinger9a0280c2017-06-01 15:58:48 -0700202 new ImsRegistrationListenerProxy();
Brad Ebinger44fd8af2017-12-14 14:24:02 -0800203 // New API for registration to the ImsService.
204 private final ImsRegistrationCallback mRegistrationCallback = new ImsRegistrationCallback();
205
Brad Ebinger9a0280c2017-06-01 15:58:48 -0700206
207 // When true, we have registered the mRegistrationListenerProxy with the ImsService. Don't do
208 // it again.
209 private boolean mHasRegisteredForProxy = false;
210 private final Object mHasRegisteredLock = new Object();
Brad Ebinger16780ff2017-01-26 11:18:21 -0800211
Amit Mahajan24f7b162016-07-21 16:33:53 -0700212 public static final String TRUE = "true";
213 public static final String FALSE = "false";
Jack Yu643ffe42016-07-08 14:25:46 -0700214
Naveen Kalla525c3a22017-02-06 14:46:42 -0800215 // mRecentDisconnectReasons stores the last 16 disconnect reasons
216 private static final int MAX_RECENT_DISCONNECT_REASONS = 16;
217 private ConcurrentLinkedDeque<ImsReasonInfo> mRecentDisconnectReasons =
218 new ConcurrentLinkedDeque<>();
219
Wink Savilleef36ef62014-06-11 08:39:38 -0700220 /**
221 * Gets a manager instance.
222 *
223 * @param context application context for creating the manager object
Etan Cohenabbd7882014-09-26 22:35:35 -0700224 * @param phoneId the phone ID for the IMS Service
225 * @return the manager instance corresponding to the phoneId
Wink Savilleef36ef62014-06-11 08:39:38 -0700226 */
Etan Cohenabbd7882014-09-26 22:35:35 -0700227 public static ImsManager getInstance(Context context, int phoneId) {
Etan Cohend7727462014-07-12 14:54:10 -0700228 synchronized (sImsManagerInstances) {
Naveen Kalla525c3a22017-02-06 14:46:42 -0800229 if (sImsManagerInstances.containsKey(phoneId)) {
Brad Ebingerff097922017-06-19 15:43:08 -0700230 ImsManager m = sImsManagerInstances.get(phoneId);
231 // May be null for some tests
232 if (m != null) {
233 m.connectIfServiceIsAvailable();
234 }
235 return m;
Naveen Kalla525c3a22017-02-06 14:46:42 -0800236 }
Wink Savilleef36ef62014-06-11 08:39:38 -0700237
Etan Cohenabbd7882014-09-26 22:35:35 -0700238 ImsManager mgr = new ImsManager(context, phoneId);
239 sImsManagerInstances.put(phoneId, mgr);
Etan Cohend7727462014-07-12 14:54:10 -0700240
241 return mgr;
242 }
Wink Savilleef36ef62014-06-11 08:39:38 -0700243 }
244
Etan Cohen45b5f312014-08-19 15:55:08 -0700245 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800246 * Returns the user configuration of Enhanced 4G LTE Mode setting.
247 *
248 * @deprecated Doesn't support MSIM devices. Use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700249 * {@link #isEnhanced4gLteModeSettingEnabledByUser()} instead.
Etan Cohen45b5f312014-08-19 15:55:08 -0700250 */
251 public static boolean isEnhanced4gLteModeSettingEnabledByUser(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700252 ImsManager mgr = ImsManager.getInstance(context,
253 SubscriptionManager.getDefaultVoicePhoneId());
254 if (mgr != null) {
255 return mgr.isEnhanced4gLteModeSettingEnabledByUser();
Sungmin Choi2f1af952016-02-01 17:15:35 +0900256 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700257 loge("isEnhanced4gLteModeSettingEnabledByUser: ImsManager null, returning default value.");
258 return false;
Etan Cohen45b5f312014-08-19 15:55:08 -0700259 }
260
261 /**
manabu, shimoda96aee542017-10-06 15:39:36 +0900262 * Returns the user configuration of Enhanced 4G LTE Mode setting for slot. If the option is
263 * not editable ({@link CarrierConfigManager#KEY_EDITABLE_ENHANCED_4G_LTE_BOOL} is false), or
264 * the setting is not initialized, this method will return default value specified by
265 * {@link CarrierConfigManager#KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL}.
266 *
267 * Note that even if the setting was set, it may no longer be editable. If this is the case we
268 * return the default value.
Brad Ebinger16417b42017-03-07 13:48:50 -0800269 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700270 public boolean isEnhanced4gLteModeSettingEnabledByUser() {
Malcolm Chen212ca652017-09-28 17:28:45 -0700271 int setting = SubscriptionManager.getIntegerSubscriptionProperty(
272 getSubId(), SubscriptionManager.ENHANCED_4G_MODE_ENABLED,
273 SUB_PROPERTY_NOT_INITIALIZED, mContext);
manabu, shimoda96aee542017-10-06 15:39:36 +0900274 boolean onByDefault = getBooleanCarrierConfig(
275 CarrierConfigManager.KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL);
Malcolm Chen212ca652017-09-28 17:28:45 -0700276
manabu, shimoda96aee542017-10-06 15:39:36 +0900277 // If Enhanced 4G LTE Mode is uneditable or not initialized, we use the default value
278 if (!getBooleanCarrierConfig(CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL)
279 || setting == SUB_PROPERTY_NOT_INITIALIZED) {
280 return onByDefault;
281 } else {
282 return (setting == ImsConfig.FeatureValueConstants.ON);
283 }
Brad Ebinger16417b42017-03-07 13:48:50 -0800284 }
285
286 /**
287 * Change persistent Enhanced 4G LTE Mode setting.
288 *
Brad Ebinger479f52c2017-08-28 13:19:22 -0700289 * @deprecated Doesn't support MSIM devices. Use {@link #setEnhanced4gLteModeSetting(boolean)}
Brad Ebinger16417b42017-03-07 13:48:50 -0800290 * instead.
Etan Cohen82f78122014-12-15 10:10:14 -0800291 */
292 public static void setEnhanced4gLteModeSetting(Context context, boolean enabled) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700293 ImsManager mgr = ImsManager.getInstance(context,
294 SubscriptionManager.getDefaultVoicePhoneId());
295 if (mgr != null) {
296 mgr.setEnhanced4gLteModeSetting(enabled);
Etan Cohen82f78122014-12-15 10:10:14 -0800297 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700298 loge("setEnhanced4gLteModeSetting: ImsManager null, value not set.");
Etan Cohen82f78122014-12-15 10:10:14 -0800299 }
300
301 /**
manabu, shimoda96aee542017-10-06 15:39:36 +0900302 * Change persistent Enhanced 4G LTE Mode setting. If the option is not editable
Brad Ebinger16417b42017-03-07 13:48:50 -0800303 * ({@link CarrierConfigManager#KEY_EDITABLE_ENHANCED_4G_LTE_BOOL} is false), this method will
manabu, shimoda96aee542017-10-06 15:39:36 +0900304 * set the setting to the default value specified by
305 * {@link CarrierConfigManager#KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL}.
Brad Ebinger16417b42017-03-07 13:48:50 -0800306 *
307 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700308 public void setEnhanced4gLteModeSetting(boolean enabled) {
manabu, shimoda96aee542017-10-06 15:39:36 +0900309 // If editable=false, we must keep default advanced 4G mode.
310 if (!getBooleanCarrierConfig(CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL)) {
311 enabled = getBooleanCarrierConfig(
312 CarrierConfigManager.KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL);
313 }
Brad Ebinger16417b42017-03-07 13:48:50 -0800314
Malcolm Chen212ca652017-09-28 17:28:45 -0700315 int prevSetting = SubscriptionManager.getIntegerSubscriptionProperty(
316 getSubId(), SubscriptionManager.ENHANCED_4G_MODE_ENABLED,
317 SUB_PROPERTY_NOT_INITIALIZED, mContext);
Brad Ebinger16417b42017-03-07 13:48:50 -0800318
manabu, shimoda96aee542017-10-06 15:39:36 +0900319 if (prevSetting != (enabled ?
320 ImsConfig.FeatureValueConstants.ON :
321 ImsConfig.FeatureValueConstants.OFF)) {
Malcolm Chen212ca652017-09-28 17:28:45 -0700322 SubscriptionManager.setSubscriptionProperty(getSubId(),
323 SubscriptionManager.ENHANCED_4G_MODE_ENABLED, booleanToPropertyString(enabled));
324 if (isNonTtyOrTtyOnVolteEnabled()) {
325 try {
326 setAdvanced4GMode(enabled);
327 } catch (ImsException ie) {
328 // do nothing
329 }
Brad Ebinger16417b42017-03-07 13:48:50 -0800330 }
331 }
332 }
333
334 /**
Etan Cohen82f78122014-12-15 10:10:14 -0800335 * Indicates whether the call is non-TTY or if TTY - whether TTY on VoLTE is
336 * supported.
Brad Ebinger16417b42017-03-07 13:48:50 -0800337 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700338 * {@link #isNonTtyOrTtyOnVolteEnabled()} instead.
Etan Cohen82f78122014-12-15 10:10:14 -0800339 */
340 public static boolean isNonTtyOrTtyOnVolteEnabled(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700341 ImsManager mgr = ImsManager.getInstance(context,
342 SubscriptionManager.getDefaultVoicePhoneId());
343 if (mgr != null) {
344 return mgr.isNonTtyOrTtyOnVolteEnabled();
345 }
346 loge("isNonTtyOrTtyOnVolteEnabled: ImsManager null, returning default value.");
347 return false;
348 }
349
350 /**
351 * Indicates whether the call is non-TTY or if TTY - whether TTY on VoLTE is
352 * supported on a per slot basis.
353 */
354 public boolean isNonTtyOrTtyOnVolteEnabled() {
355 if (getBooleanCarrierConfig(
fionaxu5803ef02016-03-08 11:48:48 -0800356 CarrierConfigManager.KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL)) {
Etan Cohen82f78122014-12-15 10:10:14 -0800357 return true;
358 }
359
Brad Ebinger479f52c2017-08-28 13:19:22 -0700360 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
Hall Liue511a202017-08-17 15:49:58 -0700361 if (tm == null) {
362 Log.w(TAG, "isNonTtyOrTtyOnVolteEnabled: telecom not available");
363 return true;
364 }
365 return tm.getCurrentTtyMode() == TelecomManager.TTY_MODE_OFF;
Etan Cohen82f78122014-12-15 10:10:14 -0800366 }
367
368 /**
Etan Cohenea2b5832014-10-23 18:50:35 -0700369 * Returns a platform configuration for VoLTE which may override the user setting.
Brad Ebinger16417b42017-03-07 13:48:50 -0800370 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700371 * {@link #isVolteEnabledByPlatform()} instead.
Etan Cohen45b5f312014-08-19 15:55:08 -0700372 */
Etan Cohenea2b5832014-10-23 18:50:35 -0700373 public static boolean isVolteEnabledByPlatform(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700374 ImsManager mgr = ImsManager.getInstance(context,
375 SubscriptionManager.getDefaultVoicePhoneId());
376 if (mgr != null) {
377 return mgr.isVolteEnabledByPlatform();
Etan Cohenaf55a402014-09-04 22:34:41 -0700378 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700379 loge("isVolteEnabledByPlatform: ImsManager null, returning default value.");
380 return false;
Etan Cohenb5388a32014-11-26 11:57:47 -0800381 }
382
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -0700383 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800384 * Returns a platform configuration for VoLTE which may override the user setting on a per Slot
385 * basis.
386 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700387 public boolean isVolteEnabledByPlatform() {
Malcolm Chen18837ff2017-10-25 17:05:41 -0700388 // We first read the per slot value. If doesn't exist, we read the general value. If still
389 // doesn't exist, we use the hardcoded default value.
390 if (SystemProperties.getInt(
391 PROPERTY_DBG_VOLTE_AVAIL_OVERRIDE + Integer.toString(mPhoneId),
392 SYSTEM_PROPERTY_NOT_SET) == 1 ||
393 SystemProperties.getInt(PROPERTY_DBG_VOLTE_AVAIL_OVERRIDE,
394 SYSTEM_PROPERTY_NOT_SET) == 1) {
Brad Ebinger16417b42017-03-07 13:48:50 -0800395 return true;
396 }
397
398 return mContext.getResources().getBoolean(
399 com.android.internal.R.bool.config_device_volte_available)
Malcolm Chen212ca652017-09-28 17:28:45 -0700400 && getBooleanCarrierConfig(CarrierConfigManager.KEY_CARRIER_VOLTE_AVAILABLE_BOOL)
Brad Ebinger479f52c2017-08-28 13:19:22 -0700401 && isGbaValid();
Brad Ebinger16417b42017-03-07 13:48:50 -0800402 }
403
404 /**
405 * Indicates whether VoLTE is provisioned on device.
406 *
407 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700408 * {@link #isVolteProvisionedOnDevice()} instead.
Etan Cohenb5388a32014-11-26 11:57:47 -0800409 */
410 public static boolean isVolteProvisionedOnDevice(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700411 ImsManager mgr = ImsManager.getInstance(context,
412 SubscriptionManager.getDefaultVoicePhoneId());
413 if (mgr != null) {
414 return mgr.isVolteProvisionedOnDevice();
Etan Cohenb5388a32014-11-26 11:57:47 -0800415 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700416 loge("isVolteProvisionedOnDevice: ImsManager null, returning default value.");
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -0700417 return true;
418 }
419
420 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800421 * Indicates whether VoLTE is provisioned on this slot.
422 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700423 public boolean isVolteProvisionedOnDevice() {
424 if (getBooleanCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -0800425 CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL)) {
426 return isVolteProvisioned();
427 }
428
429 return true;
430 }
431
432 /**
Meng Wang54fd41a2017-04-12 11:44:47 -0700433 * Indicates whether VoWifi is provisioned on device.
434 *
435 * When CarrierConfig KEY_CARRIER_VOLTE_OVERRIDE_WFC_PROVISIONING_BOOL is true, and VoLTE is not
436 * provisioned on device, this method returns false.
Brad Ebinger16417b42017-03-07 13:48:50 -0800437 *
438 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700439 * {@link #isWfcProvisionedOnDevice()} instead.
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -0700440 */
441 public static boolean isWfcProvisionedOnDevice(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700442 ImsManager mgr = ImsManager.getInstance(context,
443 SubscriptionManager.getDefaultVoicePhoneId());
444 if (mgr != null) {
445 return mgr.isWfcProvisionedOnDevice();
Meng Wang54fd41a2017-04-12 11:44:47 -0700446 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700447 loge("isWfcProvisionedOnDevice: ImsManager null, returning default value.");
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -0700448 return true;
449 }
450
451 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800452 * Indicates whether VoWifi is provisioned on slot.
Meng Wang54fd41a2017-04-12 11:44:47 -0700453 *
454 * When CarrierConfig KEY_CARRIER_VOLTE_OVERRIDE_WFC_PROVISIONING_BOOL is true, and VoLTE is not
455 * provisioned on device, this method returns false.
Brad Ebinger16417b42017-03-07 13:48:50 -0800456 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700457 public boolean isWfcProvisionedOnDevice() {
458 if (getBooleanCarrierConfig(
Meng Wang54fd41a2017-04-12 11:44:47 -0700459 CarrierConfigManager.KEY_CARRIER_VOLTE_OVERRIDE_WFC_PROVISIONING_BOOL)) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700460 if (!isVolteProvisionedOnDevice()) {
Meng Wang54fd41a2017-04-12 11:44:47 -0700461 return false;
462 }
463 }
464
Brad Ebinger479f52c2017-08-28 13:19:22 -0700465 if (getBooleanCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -0800466 CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL)) {
Meng Wang54fd41a2017-04-12 11:44:47 -0700467 return isWfcProvisioned();
Brad Ebinger16417b42017-03-07 13:48:50 -0800468 }
469
470 return true;
471 }
472
473 /**
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -0700474 * Indicates whether VT is provisioned on device
Brad Ebinger16417b42017-03-07 13:48:50 -0800475 *
476 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700477 * {@link #isVtProvisionedOnDevice()} instead.
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -0700478 */
479 public static boolean isVtProvisionedOnDevice(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700480 ImsManager mgr = ImsManager.getInstance(context,
481 SubscriptionManager.getDefaultVoicePhoneId());
482 if (mgr != null) {
483 return mgr.isVtProvisionedOnDevice();
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -0700484 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700485 loge("isVtProvisionedOnDevice: ImsManager null, returning default value.");
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -0700486 return true;
Etan Cohenb651fa52014-10-22 10:51:29 -0700487 }
488
Etan Cohenea2b5832014-10-23 18:50:35 -0700489 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800490 * Indicates whether VT is provisioned on slot.
491 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700492 public boolean isVtProvisionedOnDevice() {
493 if (getBooleanCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -0800494 CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL)) {
495 return isVtProvisioned();
496 }
497
498 return true;
499 }
500
501 /**
Etan Cohenea2b5832014-10-23 18:50:35 -0700502 * Returns a platform configuration for VT which may override the user setting.
503 *
504 * Note: VT presumes that VoLTE is enabled (these are configuration settings
505 * which must be done correctly).
Brad Ebinger16417b42017-03-07 13:48:50 -0800506 *
507 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700508 * {@link #isVtEnabledByPlatform()} instead.
Etan Cohenea2b5832014-10-23 18:50:35 -0700509 */
Etan Cohenb651fa52014-10-22 10:51:29 -0700510 public static boolean isVtEnabledByPlatform(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700511 ImsManager mgr = ImsManager.getInstance(context,
512 SubscriptionManager.getDefaultVoicePhoneId());
513 if (mgr != null) {
514 return mgr.isVtEnabledByPlatform();
Etan Cohenea2b5832014-10-23 18:50:35 -0700515 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700516 loge("isVtEnabledByPlatform: ImsManager null, returning default value.");
517 return false;
Etan Cohen45b5f312014-08-19 15:55:08 -0700518 }
519
Etan Cohena00c9192014-12-23 15:02:29 -0800520 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800521 * Returns a platform configuration for VT which may override the user setting.
522 *
523 * Note: VT presumes that VoLTE is enabled (these are configuration settings
524 * which must be done correctly).
525 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700526 public boolean isVtEnabledByPlatform() {
Malcolm Chen18837ff2017-10-25 17:05:41 -0700527 // We first read the per slot value. If doesn't exist, we read the general value. If still
528 // doesn't exist, we use the hardcoded default value.
529 if (SystemProperties.getInt(PROPERTY_DBG_VT_AVAIL_OVERRIDE +
530 Integer.toString(mPhoneId), SYSTEM_PROPERTY_NOT_SET) == 1 ||
531 SystemProperties.getInt(
532 PROPERTY_DBG_VT_AVAIL_OVERRIDE, SYSTEM_PROPERTY_NOT_SET) == 1) {
Brad Ebinger16417b42017-03-07 13:48:50 -0800533 return true;
534 }
535
536 return mContext.getResources().getBoolean(
537 com.android.internal.R.bool.config_device_vt_available) &&
Malcolm Chen212ca652017-09-28 17:28:45 -0700538 getBooleanCarrierConfig(CarrierConfigManager.KEY_CARRIER_VT_AVAILABLE_BOOL) &&
Brad Ebinger479f52c2017-08-28 13:19:22 -0700539 isGbaValid();
Brad Ebinger16417b42017-03-07 13:48:50 -0800540 }
541
542 /**
Etan Cohena7d32e82015-05-04 18:02:09 -0700543 * Returns the user configuration of VT setting
Brad Ebinger16417b42017-03-07 13:48:50 -0800544 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700545 * {@link #isVtEnabledByUser()} instead.
Etan Cohena7d32e82015-05-04 18:02:09 -0700546 */
547 public static boolean isVtEnabledByUser(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700548 ImsManager mgr = ImsManager.getInstance(context,
549 SubscriptionManager.getDefaultVoicePhoneId());
550 if (mgr != null) {
551 return mgr.isVtEnabledByUser();
552 }
553 loge("isVtEnabledByUser: ImsManager null, returning default value.");
554 return false;
Etan Cohena7d32e82015-05-04 18:02:09 -0700555 }
556
557 /**
Malcolm Chen212ca652017-09-28 17:28:45 -0700558 * Returns the user configuration of VT setting per slot. If not set, it
559 * returns true as default value.
Brad Ebinger16417b42017-03-07 13:48:50 -0800560 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700561 public boolean isVtEnabledByUser() {
Malcolm Chen212ca652017-09-28 17:28:45 -0700562 int setting = SubscriptionManager.getIntegerSubscriptionProperty(
563 getSubId(), SubscriptionManager.VT_IMS_ENABLED,
564 SUB_PROPERTY_NOT_INITIALIZED, mContext);
565
566 // If it's never set, by default we return true.
manabu, shimoda96aee542017-10-06 15:39:36 +0900567 return (setting == SUB_PROPERTY_NOT_INITIALIZED
568 || setting == ImsConfig.FeatureValueConstants.ON);
Brad Ebinger16417b42017-03-07 13:48:50 -0800569 }
570
571 /**
Etan Cohena7d32e82015-05-04 18:02:09 -0700572 * Change persistent VT enabled setting
Brad Ebinger16417b42017-03-07 13:48:50 -0800573 *
Brad Ebinger479f52c2017-08-28 13:19:22 -0700574 * @deprecated Does not support MSIM devices. Please use {@link #setVtSetting(boolean)} instead.
Etan Cohena7d32e82015-05-04 18:02:09 -0700575 */
576 public static void setVtSetting(Context context, boolean enabled) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700577 ImsManager mgr = ImsManager.getInstance(context,
Etan Cohena7d32e82015-05-04 18:02:09 -0700578 SubscriptionManager.getDefaultVoicePhoneId());
Brad Ebinger479f52c2017-08-28 13:19:22 -0700579 if (mgr != null) {
580 mgr.setVtSetting(enabled);
Etan Cohena7d32e82015-05-04 18:02:09 -0700581 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700582 loge("setVtSetting: ImsManager null, can not set value.");
Etan Cohena7d32e82015-05-04 18:02:09 -0700583 }
584
Brad Ebinger16417b42017-03-07 13:48:50 -0800585 /**
586 * Change persistent VT enabled setting for slot.
587 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700588 public void setVtSetting(boolean enabled) {
Malcolm Chen212ca652017-09-28 17:28:45 -0700589 SubscriptionManager.setSubscriptionProperty(getSubId(),
590 SubscriptionManager.VT_IMS_ENABLED,
591 booleanToPropertyString(enabled));
Brad Ebinger16417b42017-03-07 13:48:50 -0800592 try {
593 ImsConfig config = getConfigInterface();
594 config.setFeatureValue(ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_LTE,
595 TelephonyManager.NETWORK_TYPE_LTE,
596 enabled ? ImsConfig.FeatureValueConstants.ON
597 : ImsConfig.FeatureValueConstants.OFF,
598 mImsConfigListener);
599
600 if (enabled) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700601 log("setVtSetting(b) : turnOnIms");
Brad Ebinger16417b42017-03-07 13:48:50 -0800602 turnOnIms();
Brad Ebinger479f52c2017-08-28 13:19:22 -0700603 } else if (isVolteEnabledByPlatform()
604 && (!isVolteEnabledByPlatform()
605 || !isEnhanced4gLteModeSettingEnabledByUser())) {
606 log("setVtSetting(b) : imsServiceAllowTurnOff -> turnOffIms");
Brad Ebinger16417b42017-03-07 13:48:50 -0800607 turnOffIms();
608 }
609 } catch (ImsException e) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700610 loge("setVtSetting(b): ", e);
Brad Ebinger16417b42017-03-07 13:48:50 -0800611 }
612 }
613
614 /**
Meng Wang9352c432016-06-08 14:22:20 -0700615 * Returns whether turning off ims is allowed by platform.
616 * The platform property may override the carrier config.
Brad Ebinger16417b42017-03-07 13:48:50 -0800617 *
618 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700619 * {@link #isTurnOffImsAllowedByPlatform()} instead.
Meng Wang9352c432016-06-08 14:22:20 -0700620 */
621 private static boolean isTurnOffImsAllowedByPlatform(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700622 ImsManager mgr = ImsManager.getInstance(context,
623 SubscriptionManager.getDefaultVoicePhoneId());
624 if (mgr != null) {
625 return mgr.isTurnOffImsAllowedByPlatform();
Meng Wang9352c432016-06-08 14:22:20 -0700626 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700627 loge("isTurnOffImsAllowedByPlatform: ImsManager null, returning default value.");
628 return true;
Meng Wang9352c432016-06-08 14:22:20 -0700629 }
630
Etan Cohena7d32e82015-05-04 18:02:09 -0700631 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800632 * Returns whether turning off ims is allowed by platform.
633 * The platform property may override the carrier config.
634 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700635 private boolean isTurnOffImsAllowedByPlatform() {
Malcolm Chen18837ff2017-10-25 17:05:41 -0700636 // We first read the per slot value. If doesn't exist, we read the general value. If still
637 // doesn't exist, we use the hardcoded default value.
638 if (SystemProperties.getInt(PROPERTY_DBG_ALLOW_IMS_OFF_OVERRIDE +
639 Integer.toString(mPhoneId), SYSTEM_PROPERTY_NOT_SET) == 1 ||
640 SystemProperties.getInt(
641 PROPERTY_DBG_ALLOW_IMS_OFF_OVERRIDE, SYSTEM_PROPERTY_NOT_SET) == 1) {
Brad Ebinger16417b42017-03-07 13:48:50 -0800642 return true;
643 }
Malcolm Chen18837ff2017-10-25 17:05:41 -0700644
Brad Ebinger479f52c2017-08-28 13:19:22 -0700645 return getBooleanCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -0800646 CarrierConfigManager.KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL);
647 }
648
649 /**
Etan Cohena00c9192014-12-23 15:02:29 -0800650 * Returns the user configuration of WFC setting
Brad Ebinger16417b42017-03-07 13:48:50 -0800651 *
652 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700653 * {@link #isWfcEnabledByUser()} instead.
Etan Cohena00c9192014-12-23 15:02:29 -0800654 */
655 public static boolean isWfcEnabledByUser(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700656 ImsManager mgr = ImsManager.getInstance(context,
657 SubscriptionManager.getDefaultVoicePhoneId());
658 if (mgr != null) {
659 return mgr.isWfcEnabledByUser();
660 }
661 loge("isWfcEnabledByUser: ImsManager null, returning default value.");
662 return true;
Etan Cohena00c9192014-12-23 15:02:29 -0800663 }
664
665 /**
Malcolm Chen212ca652017-09-28 17:28:45 -0700666 * Returns the user configuration of WFC setting for slot. If not set, it
667 * queries CarrierConfig value as default.
Brad Ebinger16417b42017-03-07 13:48:50 -0800668 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700669 public boolean isWfcEnabledByUser() {
Malcolm Chen212ca652017-09-28 17:28:45 -0700670 int setting = SubscriptionManager.getIntegerSubscriptionProperty(
671 getSubId(), SubscriptionManager.WFC_IMS_ENABLED,
672 SUB_PROPERTY_NOT_INITIALIZED, mContext);
673
674 // SUB_PROPERTY_NOT_INITIALIZED indicates it's never set in sub db.
675 if (setting == SUB_PROPERTY_NOT_INITIALIZED) {
676 return getBooleanCarrierConfig(
677 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL);
678 } else {
manabu, shimoda96aee542017-10-06 15:39:36 +0900679 return setting == ImsConfig.FeatureValueConstants.ON;
Malcolm Chen212ca652017-09-28 17:28:45 -0700680 }
Brad Ebinger16417b42017-03-07 13:48:50 -0800681 }
682
683 /**
684 * Change persistent WFC enabled setting.
685 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700686 * {@link #setWfcSetting} instead.
Etan Cohena00c9192014-12-23 15:02:29 -0800687 */
688 public static void setWfcSetting(Context context, boolean enabled) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700689 ImsManager mgr = ImsManager.getInstance(context,
Etan Cohena00c9192014-12-23 15:02:29 -0800690 SubscriptionManager.getDefaultVoicePhoneId());
Brad Ebinger479f52c2017-08-28 13:19:22 -0700691 if (mgr != null) {
692 mgr.setWfcSetting(enabled);
Etan Cohena00c9192014-12-23 15:02:29 -0800693 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700694 loge("setWfcSetting: ImsManager null, can not set value.");
Etan Cohena00c9192014-12-23 15:02:29 -0800695 }
696
697 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800698 * Change persistent WFC enabled setting for slot.
699 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700700 public void setWfcSetting(boolean enabled) {
Malcolm Chen212ca652017-09-28 17:28:45 -0700701 SubscriptionManager.setSubscriptionProperty(getSubId(),
702 SubscriptionManager.WFC_IMS_ENABLED, booleanToPropertyString(enabled));
Brad Ebinger16417b42017-03-07 13:48:50 -0800703
Brad Ebinger479f52c2017-08-28 13:19:22 -0700704 setWfcNonPersistent(enabled, getWfcMode());
Meng Wang51c09072017-03-27 10:47:45 -0700705 }
706
707 /**
708 * Non-persistently change WFC enabled setting and WFC mode for slot
709 *
710 * @param wfcMode The WFC preference if WFC is enabled
711 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700712 public void setWfcNonPersistent(boolean enabled, int wfcMode) {
Meng Wang51c09072017-03-27 10:47:45 -0700713 int imsFeatureValue =
714 enabled ? ImsConfig.FeatureValueConstants.ON : ImsConfig.FeatureValueConstants.OFF;
715 // Force IMS to register over LTE when turning off WFC
716 int imsWfcModeFeatureValue =
717 enabled ? wfcMode : ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED;
718
Brad Ebinger16417b42017-03-07 13:48:50 -0800719 try {
720 ImsConfig config = getConfigInterface();
721 config.setFeatureValue(ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_WIFI,
722 TelephonyManager.NETWORK_TYPE_IWLAN,
Meng Wang51c09072017-03-27 10:47:45 -0700723 imsFeatureValue,
Brad Ebinger16417b42017-03-07 13:48:50 -0800724 mImsConfigListener);
725
726 if (enabled) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700727 log("setWfcSetting() : turnOnIms");
Brad Ebinger16417b42017-03-07 13:48:50 -0800728 turnOnIms();
Brad Ebinger479f52c2017-08-28 13:19:22 -0700729 } else if (isTurnOffImsAllowedByPlatform()
730 && (!isVolteEnabledByPlatform()
731 || !isEnhanced4gLteModeSettingEnabledByUser())) {
732 log("setWfcSetting() : imsServiceAllowTurnOff -> turnOffIms");
Brad Ebinger16417b42017-03-07 13:48:50 -0800733 turnOffIms();
734 }
735
Brad Ebinger479f52c2017-08-28 13:19:22 -0700736 setWfcModeInternal(imsWfcModeFeatureValue);
Brad Ebinger16417b42017-03-07 13:48:50 -0800737 } catch (ImsException e) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700738 loge("setWfcSetting(): ", e);
Brad Ebinger16417b42017-03-07 13:48:50 -0800739 }
740 }
741
742 /**
743 * Returns the user configuration of WFC preference setting.
744 *
Malcolm Chen212ca652017-09-28 17:28:45 -0700745 * @deprecated Doesn't support MSIM devices. Use {@link #getWfcMode(boolean roaming)} instead.
Etan Cohena00c9192014-12-23 15:02:29 -0800746 */
747 public static int getWfcMode(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700748 ImsManager mgr = ImsManager.getInstance(context,
749 SubscriptionManager.getDefaultVoicePhoneId());
750 if (mgr != null) {
751 return mgr.getWfcMode();
752 }
753 loge("getWfcMode: ImsManager null, returning default value.");
754 return ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY;
Etan Cohena00c9192014-12-23 15:02:29 -0800755 }
756
757 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800758 * Returns the user configuration of WFC preference setting
Malcolm Chen212ca652017-09-28 17:28:45 -0700759 * @deprecated. Use {@link #getWfcMode(boolean roaming)} instead.
Brad Ebinger16417b42017-03-07 13:48:50 -0800760 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700761 public int getWfcMode() {
Malcolm Chen212ca652017-09-28 17:28:45 -0700762 return getWfcMode(false);
Brad Ebinger16417b42017-03-07 13:48:50 -0800763 }
764
765 /**
766 * Change persistent WFC preference setting.
767 *
Brad Ebinger479f52c2017-08-28 13:19:22 -0700768 * @deprecated Doesn't support MSIM devices. Use {@link #setWfcMode(int)} instead.
Etan Cohena00c9192014-12-23 15:02:29 -0800769 */
770 public static void setWfcMode(Context context, int wfcMode) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700771 ImsManager mgr = ImsManager.getInstance(context,
772 SubscriptionManager.getDefaultVoicePhoneId());
773 if (mgr != null) {
774 mgr.setWfcMode(wfcMode);
775 }
776 loge("setWfcMode: ImsManager null, can not set value.");
Pavel Zhamaitsiak9e6eca22015-03-16 15:30:53 -0700777 }
778
Meng Wang37477012016-09-20 09:59:56 -0700779 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800780 * Change persistent WFC preference setting for slot.
781 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700782 public void setWfcMode(int wfcMode) {
783 if (DBG) log("setWfcMode(i) - setting=" + wfcMode);
Malcolm Chen212ca652017-09-28 17:28:45 -0700784
785 SubscriptionManager.setSubscriptionProperty(getSubId(),
786 SubscriptionManager.WFC_IMS_MODE, Integer.toString(wfcMode));
Brad Ebinger16417b42017-03-07 13:48:50 -0800787
Brad Ebinger479f52c2017-08-28 13:19:22 -0700788 setWfcModeInternal(wfcMode);
Brad Ebinger16417b42017-03-07 13:48:50 -0800789 }
790
791 /**
Suresh Koleti76491082017-04-21 18:39:50 +0530792 * Changes the WFC mode to its default value for Carriers with non-editable WFC settings.
793 */
794 private void updateDefaultWfcMode() {
795 if (DBG) log("updateDefaultWfcMode");
Brad Ebinger479f52c2017-08-28 13:19:22 -0700796 if (!getBooleanCarrierConfig(CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL)) {
797 setWfcMode(getIntCarrierConfig(
Suresh Koleti76491082017-04-21 18:39:50 +0530798 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT));
799 }
800 }
801
802 /**
Meng Wang37477012016-09-20 09:59:56 -0700803 * Returns the user configuration of WFC preference setting
804 *
805 * @param roaming {@code false} for home network setting, {@code true} for roaming setting
Brad Ebinger16417b42017-03-07 13:48:50 -0800806 *
Brad Ebinger479f52c2017-08-28 13:19:22 -0700807 * @deprecated Doesn't support MSIM devices. Use {@link #getWfcMode(boolean)} instead.
Meng Wang37477012016-09-20 09:59:56 -0700808 */
809 public static int getWfcMode(Context context, boolean roaming) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700810 ImsManager mgr = ImsManager.getInstance(context,
811 SubscriptionManager.getDefaultVoicePhoneId());
812 if (mgr != null) {
813 return mgr.getWfcMode(roaming);
Meng Wang37477012016-09-20 09:59:56 -0700814 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700815 loge("getWfcMode: ImsManager null, returning default value.");
816 return ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY;
Meng Wang37477012016-09-20 09:59:56 -0700817 }
818
819 /**
Malcolm Chen212ca652017-09-28 17:28:45 -0700820 * Returns the user configuration of WFC preference setting for slot. If not set, it
821 * queries CarrierConfig value as default.
Brad Ebinger16417b42017-03-07 13:48:50 -0800822 *
823 * @param roaming {@code false} for home network setting, {@code true} for roaming setting
824 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700825 public int getWfcMode(boolean roaming) {
Brad Ebinger16417b42017-03-07 13:48:50 -0800826 int setting = 0;
827 if (!roaming) {
Malcolm Chen212ca652017-09-28 17:28:45 -0700828 setting = SubscriptionManager.getIntegerSubscriptionProperty(
829 getSubId(), SubscriptionManager.WFC_IMS_MODE,
830 SUB_PROPERTY_NOT_INITIALIZED, mContext);
831
832 // SUB_PROPERTY_NOT_INITIALIZED indicates it's never set in sub db.
833 if (setting == SUB_PROPERTY_NOT_INITIALIZED) {
834 setting = getIntCarrierConfig(
835 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT);
836 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700837 if (DBG) log("getWfcMode - setting=" + setting);
Brad Ebinger16417b42017-03-07 13:48:50 -0800838 } else {
Malcolm Chen212ca652017-09-28 17:28:45 -0700839 setting = SubscriptionManager.getIntegerSubscriptionProperty(
840 getSubId(), SubscriptionManager.WFC_IMS_ROAMING_MODE,
841 SUB_PROPERTY_NOT_INITIALIZED, mContext);
842
843 // SUB_PROPERTY_NOT_INITIALIZED indicates it's never set in sub db.
844 if (setting == SUB_PROPERTY_NOT_INITIALIZED) {
845 setting = getIntCarrierConfig(
846 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_MODE_INT);
847 }
848
Brad Ebinger479f52c2017-08-28 13:19:22 -0700849 if (DBG) log("getWfcMode (roaming) - setting=" + setting);
Brad Ebinger16417b42017-03-07 13:48:50 -0800850 }
851 return setting;
852 }
853
854 /**
Meng Wang37477012016-09-20 09:59:56 -0700855 * Change persistent WFC preference setting
856 *
857 * @param roaming {@code false} for home network setting, {@code true} for roaming setting
Brad Ebinger16417b42017-03-07 13:48:50 -0800858 *
Brad Ebinger479f52c2017-08-28 13:19:22 -0700859 * @deprecated Doesn't support MSIM devices. Please use {@link #setWfcMode(int, boolean)}
860 * instead.
Meng Wang37477012016-09-20 09:59:56 -0700861 */
862 public static void setWfcMode(Context context, int wfcMode, boolean roaming) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700863 ImsManager mgr = ImsManager.getInstance(context,
864 SubscriptionManager.getDefaultVoicePhoneId());
865 if (mgr != null) {
866 mgr.setWfcMode(wfcMode, roaming);
Meng Wang37477012016-09-20 09:59:56 -0700867 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700868 loge("setWfcMode: ImsManager null, can not set value.");
Meng Wang37477012016-09-20 09:59:56 -0700869 }
870
Brad Ebinger16417b42017-03-07 13:48:50 -0800871 /**
872 * Change persistent WFC preference setting
873 *
874 * @param roaming {@code false} for home network setting, {@code true} for roaming setting
875 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700876 public void setWfcMode(int wfcMode, boolean roaming) {
Brad Ebinger16417b42017-03-07 13:48:50 -0800877 if (!roaming) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700878 if (DBG) log("setWfcMode(i,b) - setting=" + wfcMode);
Malcolm Chen212ca652017-09-28 17:28:45 -0700879 SubscriptionManager.setSubscriptionProperty(getSubId(),
880 SubscriptionManager.WFC_IMS_MODE, Integer.toString(wfcMode));
Brad Ebinger16417b42017-03-07 13:48:50 -0800881 } else {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700882 if (DBG) log("setWfcMode(i,b) (roaming) - setting=" + wfcMode);
Malcolm Chen212ca652017-09-28 17:28:45 -0700883 SubscriptionManager.setSubscriptionProperty(getSubId(),
884 SubscriptionManager.WFC_IMS_ROAMING_MODE, Integer.toString(wfcMode));
Brad Ebinger16417b42017-03-07 13:48:50 -0800885 }
886
Brad Ebinger479f52c2017-08-28 13:19:22 -0700887 TelephonyManager tm = (TelephonyManager)
888 mContext.getSystemService(Context.TELEPHONY_SERVICE);
889 if (roaming == tm.isNetworkRoaming(getSubId())) {
890 setWfcModeInternal(wfcMode);
891 }
892 }
893
894 private int getSubId() {
Brad Ebinger16417b42017-03-07 13:48:50 -0800895 int[] subIds = SubscriptionManager.getSubId(mPhoneId);
896 int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
897 if (subIds != null && subIds.length >= 1) {
898 subId = subIds[0];
899 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700900 return subId;
Brad Ebinger16417b42017-03-07 13:48:50 -0800901 }
902
Pavel Zhamaitsiak9e6eca22015-03-16 15:30:53 -0700903 private static void setWfcModeInternal(Context context, int wfcMode) {
Etan Cohena00c9192014-12-23 15:02:29 -0800904 final ImsManager imsManager = ImsManager.getInstance(context,
905 SubscriptionManager.getDefaultVoicePhoneId());
906 if (imsManager != null) {
907 final int value = wfcMode;
Pavel Zhamaitsiak47aeacf2016-03-30 18:54:55 -0700908 Thread thread = new Thread(new Runnable() {
Etan Cohena00c9192014-12-23 15:02:29 -0800909 public void run() {
910 try {
911 imsManager.getConfigInterface().setProvisionedValue(
912 ImsConfig.ConfigConstants.VOICE_OVER_WIFI_MODE,
913 value);
914 } catch (ImsException e) {
915 // do nothing
916 }
917 }
918 });
Pavel Zhamaitsiak47aeacf2016-03-30 18:54:55 -0700919 thread.start();
Etan Cohena00c9192014-12-23 15:02:29 -0800920 }
921 }
922
Brad Ebinger479f52c2017-08-28 13:19:22 -0700923 private void setWfcModeInternal(int wfcMode) {
Brad Ebinger16417b42017-03-07 13:48:50 -0800924 final int value = wfcMode;
925 Thread thread = new Thread(() -> {
Malcolm Chen212ca652017-09-28 17:28:45 -0700926 try {
927 getConfigInterface().setProvisionedValue(
928 ImsConfig.ConfigConstants.VOICE_OVER_WIFI_MODE, value);
929 } catch (ImsException e) {
930 // do nothing
931 }
Brad Ebinger16417b42017-03-07 13:48:50 -0800932 });
933 thread.start();
934 }
935
Etan Cohena00c9192014-12-23 15:02:29 -0800936 /**
937 * Returns the user configuration of WFC roaming setting
Brad Ebinger16417b42017-03-07 13:48:50 -0800938 *
939 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700940 * {@link #isWfcRoamingEnabledByUser()} instead.
Etan Cohena00c9192014-12-23 15:02:29 -0800941 */
942 public static boolean isWfcRoamingEnabledByUser(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700943 ImsManager mgr = ImsManager.getInstance(context,
944 SubscriptionManager.getDefaultVoicePhoneId());
945 if (mgr != null) {
946 return mgr.isWfcRoamingEnabledByUser();
947 }
948 loge("isWfcRoamingEnabledByUser: ImsManager null, returning default value.");
949 return false;
Etan Cohena00c9192014-12-23 15:02:29 -0800950 }
951
952 /**
Malcolm Chen212ca652017-09-28 17:28:45 -0700953 * Returns the user configuration of WFC roaming setting for slot. If not set, it
954 * queries CarrierConfig value as default.
Brad Ebinger16417b42017-03-07 13:48:50 -0800955 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700956 public boolean isWfcRoamingEnabledByUser() {
Malcolm Chen212ca652017-09-28 17:28:45 -0700957 int setting = SubscriptionManager.getIntegerSubscriptionProperty(
958 getSubId(), SubscriptionManager.WFC_IMS_ROAMING_ENABLED,
959 SUB_PROPERTY_NOT_INITIALIZED, mContext);
960 if (setting == SUB_PROPERTY_NOT_INITIALIZED) {
961 return getBooleanCarrierConfig(
962 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_ENABLED_BOOL);
963 } else {
manabu, shimoda96aee542017-10-06 15:39:36 +0900964 return setting == ImsConfig.FeatureValueConstants.ON;
Malcolm Chen212ca652017-09-28 17:28:45 -0700965 }
Brad Ebinger16417b42017-03-07 13:48:50 -0800966 }
967
968 /**
Etan Cohena00c9192014-12-23 15:02:29 -0800969 * Change persistent WFC roaming enabled setting
970 */
971 public static void setWfcRoamingSetting(Context context, boolean enabled) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700972 ImsManager mgr = ImsManager.getInstance(context,
Etan Cohena00c9192014-12-23 15:02:29 -0800973 SubscriptionManager.getDefaultVoicePhoneId());
Brad Ebinger479f52c2017-08-28 13:19:22 -0700974 if (mgr != null) {
975 mgr.setWfcRoamingSetting(enabled);
Etan Cohena00c9192014-12-23 15:02:29 -0800976 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700977 loge("setWfcRoamingSetting: ImsManager null, value not set.");
Etan Cohena00c9192014-12-23 15:02:29 -0800978 }
979
980 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800981 * Change persistent WFC roaming enabled setting
982 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700983 public void setWfcRoamingSetting(boolean enabled) {
Malcolm Chen212ca652017-09-28 17:28:45 -0700984 SubscriptionManager.setSubscriptionProperty(getSubId(),
985 SubscriptionManager.WFC_IMS_ROAMING_ENABLED, booleanToPropertyString(enabled)
986 );
Brad Ebinger16417b42017-03-07 13:48:50 -0800987
988 setWfcRoamingSettingInternal(enabled);
989 }
990
991 private void setWfcRoamingSettingInternal(boolean enabled) {
992 final int value = enabled
993 ? ImsConfig.FeatureValueConstants.ON
994 : ImsConfig.FeatureValueConstants.OFF;
995 Thread thread = new Thread(() -> {
Malcolm Chen212ca652017-09-28 17:28:45 -0700996 try {
997 getConfigInterface().setProvisionedValue(
998 ImsConfig.ConfigConstants.VOICE_OVER_WIFI_ROAMING, value);
999 } catch (ImsException e) {
1000 // do nothing
1001 }
Brad Ebinger16417b42017-03-07 13:48:50 -08001002 });
1003 thread.start();
1004 }
1005
1006 /**
Etan Cohena00c9192014-12-23 15:02:29 -08001007 * Returns a platform configuration for WFC which may override the user
1008 * setting. Note: WFC presumes that VoLTE is enabled (these are
1009 * configuration settings which must be done correctly).
Brad Ebinger16417b42017-03-07 13:48:50 -08001010 *
Brad Ebinger479f52c2017-08-28 13:19:22 -07001011 * @deprecated Doesn't work for MSIM devices. Use {@link #isWfcEnabledByPlatform()}
Brad Ebinger16417b42017-03-07 13:48:50 -08001012 * instead.
Etan Cohena00c9192014-12-23 15:02:29 -08001013 */
1014 public static boolean isWfcEnabledByPlatform(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001015 ImsManager mgr = ImsManager.getInstance(context,
1016 SubscriptionManager.getDefaultVoicePhoneId());
1017 if (mgr != null) {
1018 return mgr.isWfcEnabledByPlatform();
Etan Cohena00c9192014-12-23 15:02:29 -08001019 }
Brad Ebinger479f52c2017-08-28 13:19:22 -07001020 loge("isWfcEnabledByPlatform: ImsManager null, returning default value.");
1021 return false;
Pavel Zhamaitsiak57911d12015-10-20 14:26:34 -07001022 }
1023
1024 /**
Brad Ebinger16417b42017-03-07 13:48:50 -08001025 * Returns a platform configuration for WFC which may override the user
1026 * setting per slot. Note: WFC presumes that VoLTE is enabled (these are
1027 * configuration settings which must be done correctly).
1028 */
Brad Ebinger479f52c2017-08-28 13:19:22 -07001029 public boolean isWfcEnabledByPlatform() {
Malcolm Chen18837ff2017-10-25 17:05:41 -07001030 // We first read the per slot value. If doesn't exist, we read the general value. If still
1031 // doesn't exist, we use the hardcoded default value.
1032 if (SystemProperties.getInt(PROPERTY_DBG_WFC_AVAIL_OVERRIDE +
1033 Integer.toString(mPhoneId), SYSTEM_PROPERTY_NOT_SET) == 1 ||
1034 SystemProperties.getInt(
1035 PROPERTY_DBG_WFC_AVAIL_OVERRIDE, SYSTEM_PROPERTY_NOT_SET) == 1) {
Brad Ebinger16417b42017-03-07 13:48:50 -08001036 return true;
1037 }
1038
1039 return mContext.getResources().getBoolean(
1040 com.android.internal.R.bool.config_device_wfc_ims_available) &&
Brad Ebinger479f52c2017-08-28 13:19:22 -07001041 getBooleanCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -08001042 CarrierConfigManager.KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL) &&
Brad Ebinger479f52c2017-08-28 13:19:22 -07001043 isGbaValid();
Etan Cohena00c9192014-12-23 15:02:29 -08001044 }
1045
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001046 /**
Brad Ebinger16417b42017-03-07 13:48:50 -08001047 * If carrier requires that IMS is only available if GBA capable SIM is used,
1048 * then this function checks GBA bit in EF IST.
1049 *
1050 * Format of EF IST is defined in 3GPP TS 31.103 (Section 4.2.7).
1051 */
Brad Ebinger479f52c2017-08-28 13:19:22 -07001052 private boolean isGbaValid() {
1053 if (getBooleanCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -08001054 CarrierConfigManager.KEY_CARRIER_IMS_GBA_REQUIRED_BOOL)) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001055 final TelephonyManager telephonyManager = new TelephonyManager(mContext, getSubId());
Brad Ebinger16417b42017-03-07 13:48:50 -08001056 String efIst = telephonyManager.getIsimIst();
1057 if (efIst == null) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001058 loge("isGbaValid - ISF is NULL");
Brad Ebinger16417b42017-03-07 13:48:50 -08001059 return true;
1060 }
1061 boolean result = efIst != null && efIst.length() > 1 &&
1062 (0x02 & (byte)efIst.charAt(1)) != 0;
Brad Ebinger479f52c2017-08-28 13:19:22 -07001063 if (DBG) log("isGbaValid - GBA capable=" + result + ", ISF=" + efIst);
Brad Ebinger16417b42017-03-07 13:48:50 -08001064 return result;
1065 }
1066 return true;
1067 }
1068
1069 /**
Malcolm Chen18837ff2017-10-25 17:05:41 -07001070 * Will return with config value or throw an ImsException if we receive an error from
1071 * ImsConfig for that value.
1072 */
1073 private boolean getProvisionedBool(ImsConfig config, int item) throws ImsException {
1074 int value = config.getProvisionedValue(item);
1075 if (value == ImsConfig.OperationStatusConstants.UNKNOWN) {
1076 throw new ImsException("getProvisionedBool failed with error for item: " + item,
1077 ImsReasonInfo.CODE_LOCAL_INTERNAL_ERROR);
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -07001078 }
Malcolm Chen18837ff2017-10-25 17:05:41 -07001079 return config.getProvisionedValue(item) == ImsConfig.FeatureValueConstants.ON;
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -07001080 }
1081
1082 /**
Malcolm Chen18837ff2017-10-25 17:05:41 -07001083 * Will return with config value or return false if we receive an error from
1084 * ImsConfig for that value.
Brad Ebingerbe6cb672017-08-25 14:55:00 -07001085 */
Malcolm Chen18837ff2017-10-25 17:05:41 -07001086 private boolean getProvisionedBoolNoException(int item) {
1087 try {
1088 ImsConfig config = getConfigInterface();
1089 return getProvisionedBool(config, item);
1090 } catch (ImsException ex) {
1091 return false;
Brad Ebingerbe6cb672017-08-25 14:55:00 -07001092 }
1093 }
1094
1095 /**
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001096 * Sync carrier config and user settings with ImsConfig.
1097 *
1098 * @param context for the manager object
1099 * @param phoneId phone id
1100 * @param force update
Brad Ebinger16417b42017-03-07 13:48:50 -08001101 *
Brad Ebinger479f52c2017-08-28 13:19:22 -07001102 * @deprecated Doesn't support MSIM devices. Use {@link #updateImsServiceConfig(boolean)}
1103 * instead.
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001104 */
1105 public static void updateImsServiceConfig(Context context, int phoneId, boolean force) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001106 ImsManager mgr = ImsManager.getInstance(context, phoneId);
1107 if (mgr != null) {
1108 mgr.updateImsServiceConfig(force);
Pavel Zhamaitsiakfc202992016-03-29 18:07:38 -07001109 }
Brad Ebinger479f52c2017-08-28 13:19:22 -07001110 loge("updateImsServiceConfig: ImsManager null, returning without update.");
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001111 }
1112
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -07001113 /**
Brad Ebinger16417b42017-03-07 13:48:50 -08001114 * Sync carrier config and user settings with ImsConfig.
1115 *
Brad Ebinger16417b42017-03-07 13:48:50 -08001116 * @param force update
1117 */
Brad Ebinger479f52c2017-08-28 13:19:22 -07001118 public void updateImsServiceConfig(boolean force) {
Brad Ebinger16417b42017-03-07 13:48:50 -08001119 if (!force) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001120 TelephonyManager tm = new TelephonyManager(mContext, getSubId());
1121 if (tm.getSimState() != TelephonyManager.SIM_STATE_READY) {
1122 log("updateImsServiceConfig: SIM not ready");
Brad Ebinger16417b42017-03-07 13:48:50 -08001123 // Don't disable IMS if SIM is not ready
1124 return;
1125 }
1126 }
1127
1128 if (!mConfigUpdated || force) {
1129 try {
Brad Ebinger16417b42017-03-07 13:48:50 -08001130 // TODO: Extend ImsConfig API and set all feature values in single function call.
1131
1132 // Note: currently the order of updates is set to produce different order of
1133 // setFeatureValue() function calls from setAdvanced4GMode(). This is done to
1134 // differentiate this code path from vendor code perspective.
1135 boolean isImsUsed = updateVolteFeatureValue();
1136 isImsUsed |= updateWfcFeatureAndProvisionedValues();
1137 isImsUsed |= updateVideoCallFeatureValue();
1138
Brad Ebinger479f52c2017-08-28 13:19:22 -07001139 if (isImsUsed || !isTurnOffImsAllowedByPlatform()) {
Brad Ebinger16417b42017-03-07 13:48:50 -08001140 // Turn on IMS if it is used.
1141 // Also, if turning off is not allowed for current carrier,
1142 // we need to turn IMS on because it might be turned off before
1143 // phone switched to current carrier.
Brad Ebinger479f52c2017-08-28 13:19:22 -07001144 log("updateImsServiceConfig: turnOnIms");
Brad Ebinger16417b42017-03-07 13:48:50 -08001145 turnOnIms();
1146 } else {
1147 // Turn off IMS if it is not used AND turning off is allowed for carrier.
Brad Ebinger479f52c2017-08-28 13:19:22 -07001148 log("updateImsServiceConfig: turnOffIms");
Brad Ebinger16417b42017-03-07 13:48:50 -08001149 turnOffIms();
1150 }
1151
1152 mConfigUpdated = true;
1153 } catch (ImsException e) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001154 loge("updateImsServiceConfig: ", e);
Brad Ebinger16417b42017-03-07 13:48:50 -08001155 mConfigUpdated = false;
1156 }
1157 }
1158 }
1159
1160 /**
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -07001161 * Update VoLTE config
1162 * @return whether feature is On
1163 * @throws ImsException
1164 */
1165 private boolean updateVolteFeatureValue() throws ImsException {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001166 boolean available = isVolteEnabledByPlatform();
1167 boolean enabled = isEnhanced4gLteModeSettingEnabledByUser();
1168 boolean isNonTty = isNonTtyOrTtyOnVolteEnabled();
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -08001169 boolean isFeatureOn = available && enabled && isNonTty;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001170
1171 log("updateVolteFeatureValue: available = " + available
1172 + ", enabled = " + enabled
1173 + ", nonTTY = " + isNonTty);
1174
1175 getConfigInterface().setFeatureValue(
1176 ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE,
1177 TelephonyManager.NETWORK_TYPE_LTE,
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -08001178 isFeatureOn ?
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001179 ImsConfig.FeatureValueConstants.ON :
1180 ImsConfig.FeatureValueConstants.OFF,
Pavel Zhamaitsiakf4b90322016-01-26 14:34:09 -08001181 mImsConfigListener);
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -07001182
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -08001183 return isFeatureOn;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001184 }
1185
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -07001186 /**
Jack Yu643ffe42016-07-08 14:25:46 -07001187 * Update video call over LTE config
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -07001188 * @return whether feature is On
1189 * @throws ImsException
1190 */
1191 private boolean updateVideoCallFeatureValue() throws ImsException {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001192 boolean available = isVtEnabledByPlatform();
1193 boolean enabled = isVtEnabledByUser();
1194 boolean isNonTty = isNonTtyOrTtyOnVolteEnabled();
Amit Mahajan24f7b162016-07-21 16:33:53 -07001195 boolean isDataEnabled = isDataEnabled();
Brad Ebinger479f52c2017-08-28 13:19:22 -07001196 boolean ignoreDataEnabledChanged = getBooleanCarrierConfig(
Jack Yu57781852016-11-16 17:20:38 -08001197 CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS);
Jack Yu643ffe42016-07-08 14:25:46 -07001198
Jack Yu57781852016-11-16 17:20:38 -08001199 boolean isFeatureOn = available && enabled && isNonTty
1200 && (ignoreDataEnabledChanged || isDataEnabled);
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001201
1202 log("updateVideoCallFeatureValue: available = " + available
1203 + ", enabled = " + enabled
Jack Yu643ffe42016-07-08 14:25:46 -07001204 + ", nonTTY = " + isNonTty
Amit Mahajan24f7b162016-07-21 16:33:53 -07001205 + ", data enabled = " + isDataEnabled);
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001206
1207 getConfigInterface().setFeatureValue(
1208 ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_LTE,
1209 TelephonyManager.NETWORK_TYPE_LTE,
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -08001210 isFeatureOn ?
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001211 ImsConfig.FeatureValueConstants.ON :
1212 ImsConfig.FeatureValueConstants.OFF,
Pavel Zhamaitsiakf4b90322016-01-26 14:34:09 -08001213 mImsConfigListener);
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -07001214
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -08001215 return isFeatureOn;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001216 }
1217
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -07001218 /**
1219 * Update WFC config
1220 * @return whether feature is On
1221 * @throws ImsException
1222 */
1223 private boolean updateWfcFeatureAndProvisionedValues() throws ImsException {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001224 TelephonyManager tm = new TelephonyManager(mContext, getSubId());
1225 boolean isNetworkRoaming = tm.isNetworkRoaming();
1226 boolean available = isWfcEnabledByPlatform();
1227 boolean enabled = isWfcEnabledByUser();
Suresh Koleti76491082017-04-21 18:39:50 +05301228 updateDefaultWfcMode();
Brad Ebinger479f52c2017-08-28 13:19:22 -07001229 int mode = getWfcMode(isNetworkRoaming);
1230 boolean roaming = isWfcRoamingEnabledByUser();
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -08001231 boolean isFeatureOn = available && enabled;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001232
1233 log("updateWfcFeatureAndProvisionedValues: available = " + available
1234 + ", enabled = " + enabled
1235 + ", mode = " + mode
1236 + ", roaming = " + roaming);
1237
1238 getConfigInterface().setFeatureValue(
Pavel Zhamaitsiake6f99432015-09-11 10:29:30 -07001239 ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_WIFI,
1240 TelephonyManager.NETWORK_TYPE_IWLAN,
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -08001241 isFeatureOn ?
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001242 ImsConfig.FeatureValueConstants.ON :
1243 ImsConfig.FeatureValueConstants.OFF,
Pavel Zhamaitsiakf4b90322016-01-26 14:34:09 -08001244 mImsConfigListener);
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001245
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -08001246 if (!isFeatureOn) {
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001247 mode = ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED;
1248 roaming = false;
1249 }
1250 setWfcModeInternal(mContext, mode);
Brad Ebinger16417b42017-03-07 13:48:50 -08001251 setWfcRoamingSettingInternal(roaming);
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -07001252
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -08001253 return isFeatureOn;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001254 }
1255
Brad Ebinger16780ff2017-01-26 11:18:21 -08001256 /**
Brad Ebinger479f52c2017-08-28 13:19:22 -07001257 * Do NOT use this directly, instead use {@link #getInstance(Context, int)}.
Brad Ebinger16780ff2017-01-26 11:18:21 -08001258 */
1259 @VisibleForTesting
1260 public ImsManager(Context context, int phoneId) {
Wink Savilleef36ef62014-06-11 08:39:38 -07001261 mContext = context;
Etan Cohenabbd7882014-09-26 22:35:35 -07001262 mPhoneId = phoneId;
Brad Ebinger16780ff2017-01-26 11:18:21 -08001263 mConfigDynamicBind = mContext.getResources().getBoolean(
1264 com.android.internal.R.bool.config_dynamic_bind_ims);
Brad Ebinger16417b42017-03-07 13:48:50 -08001265 mConfigManager = (CarrierConfigManager) context.getSystemService(
1266 Context.CARRIER_CONFIG_SERVICE);
Brad Ebinger16780ff2017-01-26 11:18:21 -08001267 createImsService();
1268 }
1269
1270 /**
Brad Ebinger16780ff2017-01-26 11:18:21 -08001271 * @return Whether or not ImsManager is configured to Dynamically bind or not to support legacy
1272 * devices.
1273 */
1274 public boolean isDynamicBinding() {
1275 return mConfigDynamicBind;
Wink Savilleef36ef62014-06-11 08:39:38 -07001276 }
1277
Etan Cohenf4311122015-02-26 17:47:13 -08001278 /*
Brad Ebingerff097922017-06-19 15:43:08 -07001279 * Returns a flag indicating whether the IMS service is available. If it is not available,
1280 * it will try to connect before reporting failure.
Etan Cohenf4311122015-02-26 17:47:13 -08001281 */
1282 public boolean isServiceAvailable() {
Brad Ebingerff097922017-06-19 15:43:08 -07001283 connectIfServiceIsAvailable();
Brad Ebinger16780ff2017-01-26 11:18:21 -08001284 // mImsServiceProxy will always create an ImsServiceProxy.
1285 return mImsServiceProxy.isBinderAlive();
Etan Cohenf4311122015-02-26 17:47:13 -08001286 }
1287
Suresh Koleticc3139c2017-11-03 18:23:57 +05301288 /*
1289 * Returns a flag indicating whether the IMS service is ready to send requests to lower layers.
1290 */
1291 public boolean isServiceReady() {
1292 connectIfServiceIsAvailable();
1293 return mImsServiceProxy.isBinderReady();
1294 }
1295
Brad Ebingerff097922017-06-19 15:43:08 -07001296 /**
1297 * If the service is available, try to reconnect.
1298 */
1299 public void connectIfServiceIsAvailable() {
1300 if (mImsServiceProxy == null || !mImsServiceProxy.isBinderAlive()) {
1301 createImsService();
1302 }
1303 }
1304
Pavel Zhamaitsiakf4b90322016-01-26 14:34:09 -08001305 public void setImsConfigListener(ImsConfigListener listener) {
1306 mImsConfigListener = listener;
1307 }
1308
Brad Ebingerb10b61e2017-04-18 11:45:26 -07001309
1310 /**
1311 * Adds a callback for status changed events if the binder is already available. If it is not,
1312 * this method will throw an ImsException.
1313 */
Brad Ebinger44fd8af2017-12-14 14:24:02 -08001314 public void addNotifyStatusChangedCallbackIfAvailable(ImsServiceProxy.IFeatureUpdate c)
Brad Ebingerb10b61e2017-04-18 11:45:26 -07001315 throws ImsException {
1316 if (!mImsServiceProxy.isBinderAlive()) {
1317 throw new ImsException("Binder is not active!",
1318 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1319 }
Brad Ebinger16780ff2017-01-26 11:18:21 -08001320 if (c != null) {
1321 mStatusCallbacks.add(c);
1322 }
1323 }
1324
Brad Ebinger44fd8af2017-12-14 14:24:02 -08001325 public void removeNotifyStatusChangedCallback(ImsServiceProxy.IFeatureUpdate c) {
1326 if (c != null) {
1327 mStatusCallbacks.remove(c);
1328 } else {
1329 Log.w(TAG, "removeNotifyStatusChangedCallback: callback is null!");
1330 }
1331 }
1332
Wink Savilleef36ef62014-06-11 08:39:38 -07001333 /**
1334 * Opens the IMS service for making calls and/or receiving generic IMS calls.
1335 * The caller may make subsquent calls through {@link #makeCall}.
1336 * The IMS service will register the device to the operator's network with the credentials
1337 * (from ISIM) periodically in order to receive calls from the operator's network.
1338 * When the IMS service receives a new call, it will send out an intent with
1339 * the provided action string.
1340 * The intent contains a call ID extra {@link getCallId} and it can be used to take a call.
1341 *
1342 * @param serviceClass a service class specified in {@link ImsServiceClass}
1343 * For VoLTE service, it MUST be a {@link ImsServiceClass#MMTEL}.
1344 * @param incomingCallPendingIntent When an incoming call is received,
1345 * the IMS service will call {@link PendingIntent#send(Context, int, Intent)} to
1346 * send back the intent to the caller with {@link #INCOMING_CALL_RESULT_CODE}
1347 * as the result code and the intent to fill in the call ID; It cannot be null
1348 * @param listener To listen to IMS registration events; It cannot be null
1349 * @return identifier (greater than 0) for the specified service
1350 * @throws NullPointerException if {@code incomingCallPendingIntent}
1351 * or {@code listener} is null
1352 * @throws ImsException if calling the IMS service results in an error
1353 * @see #getCallId
Brad Ebinger16780ff2017-01-26 11:18:21 -08001354 * @see #getImsSessionId
Wink Savilleef36ef62014-06-11 08:39:38 -07001355 */
1356 public int open(int serviceClass, PendingIntent incomingCallPendingIntent,
1357 ImsConnectionStateListener listener) throws ImsException {
1358 checkAndThrowExceptionIfServiceUnavailable();
1359
1360 if (incomingCallPendingIntent == null) {
1361 throw new NullPointerException("incomingCallPendingIntent can't be null");
1362 }
1363
1364 if (listener == null) {
1365 throw new NullPointerException("listener can't be null");
1366 }
1367
1368 int result = 0;
1369
1370 try {
Brad Ebinger57b11892017-06-13 16:21:35 -07001371 // Register a stub implementation of the ImsRegistrationListener. There is the
1372 // possibility that if we use the real implementation of the ImsRegistrationListener,
1373 // it will be added twice.
1374 // TODO: Remove ImsRegistrationListener from startSession API (b/62588776)
Brad Ebinger16780ff2017-01-26 11:18:21 -08001375 result = mImsServiceProxy.startSession(incomingCallPendingIntent,
Brad Ebinger57b11892017-06-13 16:21:35 -07001376 new ImsRegistrationListenerBase());
1377 addRegistrationListener(listener);
1378 log("open: Session started and registration listener added.");
Wink Savilleef36ef62014-06-11 08:39:38 -07001379 } catch (RemoteException e) {
1380 throw new ImsException("open()", e,
1381 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1382 }
1383
1384 if (result <= 0) {
1385 // If the return value is a minus value,
1386 // it means that an error occurred in the service.
1387 // So, it needs to convert to the reason code specified in ImsReasonInfo.
1388 throw new ImsException("open()", (result * (-1)));
1389 }
1390
1391 return result;
1392 }
1393
1394 /**
Pavel Zhamaitsiakce410172016-04-15 10:55:56 -07001395 * Adds registration listener to the IMS service.
1396 *
1397 * @param serviceClass a service class specified in {@link ImsServiceClass}
1398 * For VoLTE service, it MUST be a {@link ImsServiceClass#MMTEL}.
1399 * @param listener To listen to IMS registration events; It cannot be null
1400 * @throws NullPointerException if {@code listener} is null
1401 * @throws ImsException if calling the IMS service results in an error
Brad Ebinger9a0280c2017-06-01 15:58:48 -07001402 *
1403 * @deprecated Use {@link #addRegistrationListener(ImsConnectionStateListener)} instead.
Pavel Zhamaitsiakce410172016-04-15 10:55:56 -07001404 */
1405 public void addRegistrationListener(int serviceClass, ImsConnectionStateListener listener)
1406 throws ImsException {
Brad Ebinger9a0280c2017-06-01 15:58:48 -07001407 addRegistrationListener(listener);
1408 }
1409
1410 /**
1411 * Adds registration listener to the IMS service.
1412 *
1413 * @param listener To listen to IMS registration events; It cannot be null
1414 * @throws NullPointerException if {@code listener} is null
1415 * @throws ImsException if calling the IMS service results in an error
1416 */
Brad Ebinger44fd8af2017-12-14 14:24:02 -08001417 public void addRegistrationListener(ImsConnectionStateListener listener) throws ImsException {
Pavel Zhamaitsiakce410172016-04-15 10:55:56 -07001418 if (listener == null) {
1419 throw new NullPointerException("listener can't be null");
1420 }
Brad Ebinger57b11892017-06-13 16:21:35 -07001421 // We only want this Proxy registered once.
Brad Ebinger9a0280c2017-06-01 15:58:48 -07001422 synchronized (mHasRegisteredLock) {
1423 if (!mHasRegisteredForProxy) {
1424 try {
Brad Ebinger57b11892017-06-13 16:21:35 -07001425 checkAndThrowExceptionIfServiceUnavailable();
Brad Ebinger44fd8af2017-12-14 14:24:02 -08001426 // TODO: Remove once new MmTelFeature is merged in
1427 mImsServiceProxy.addRegistrationListener(mImsRegistrationListenerProxy);
1428 mImsServiceProxy.getRegistration().addRegistrationCallback(
1429 mRegistrationCallback);
1430 log("Registration Callback/Listener registered.");
Brad Ebinger9a0280c2017-06-01 15:58:48 -07001431 // Only record if there isn't a RemoteException.
1432 mHasRegisteredForProxy = true;
1433 } catch (RemoteException e) {
1434 throw new ImsException("addRegistrationListener()", e,
1435 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1436 }
1437 }
1438 }
1439 synchronized (mRegistrationListeners) {
Brad Ebinger57b11892017-06-13 16:21:35 -07001440 log("Local registration listener added: " + listener);
Brad Ebinger9a0280c2017-06-01 15:58:48 -07001441 mRegistrationListeners.add(listener);
Pavel Zhamaitsiakce410172016-04-15 10:55:56 -07001442 }
1443 }
1444
1445 /**
Brad Ebinger16780ff2017-01-26 11:18:21 -08001446 * Removes the registration listener from the IMS service.
1447 *
Brad Ebinger16780ff2017-01-26 11:18:21 -08001448 * @param listener Previously registered listener that will be removed. Can not be null.
1449 * @throws NullPointerException if {@code listener} is null
1450 * @throws ImsException if calling the IMS service results in an error
1451 * instead.
1452 */
Brad Ebingerb5f30c72017-02-17 14:54:31 -08001453 public void removeRegistrationListener(ImsConnectionStateListener listener)
Brad Ebinger16780ff2017-01-26 11:18:21 -08001454 throws ImsException {
Brad Ebinger16780ff2017-01-26 11:18:21 -08001455 if (listener == null) {
1456 throw new NullPointerException("listener can't be null");
1457 }
1458
Brad Ebinger9a0280c2017-06-01 15:58:48 -07001459 synchronized (mRegistrationListeners) {
Brad Ebinger57b11892017-06-13 16:21:35 -07001460 log("Local registration listener removed: " + listener);
Brad Ebinger9a0280c2017-06-01 15:58:48 -07001461 mRegistrationListeners.remove(listener);
Brad Ebinger16780ff2017-01-26 11:18:21 -08001462 }
1463 }
1464
1465 /**
Wink Savilleef36ef62014-06-11 08:39:38 -07001466 * Closes the specified service ({@link ImsServiceClass}) not to make/receive calls.
1467 * All the resources that were allocated to the service are also released.
1468 *
Brad Ebinger16780ff2017-01-26 11:18:21 -08001469 * @param sessionId a session id to be closed which is obtained from {@link ImsManager#open}
Wink Savilleef36ef62014-06-11 08:39:38 -07001470 * @throws ImsException if calling the IMS service results in an error
1471 */
Brad Ebinger16780ff2017-01-26 11:18:21 -08001472 public void close(int sessionId) throws ImsException {
Wink Savilleef36ef62014-06-11 08:39:38 -07001473 checkAndThrowExceptionIfServiceUnavailable();
1474
1475 try {
Brad Ebinger16780ff2017-01-26 11:18:21 -08001476 mImsServiceProxy.endSession(sessionId);
Wink Savilleef36ef62014-06-11 08:39:38 -07001477 } catch (RemoteException e) {
1478 throw new ImsException("close()", e,
1479 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1480 } finally {
1481 mUt = null;
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -05001482 mConfig = null;
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -07001483 mEcbm = null;
Tyler Gunn4d128b62016-04-13 15:44:38 -07001484 mMultiEndpoint = null;
Wink Savilleef36ef62014-06-11 08:39:38 -07001485 }
1486 }
1487
1488 /**
1489 * Gets the configuration interface to provision / withdraw the supplementary service settings.
1490 *
Wink Savilleef36ef62014-06-11 08:39:38 -07001491 * @return the Ut interface instance
1492 * @throws ImsException if getting the Ut interface results in an error
1493 */
Brad Ebingerb5f30c72017-02-17 14:54:31 -08001494 public ImsUtInterface getSupplementaryServiceConfiguration()
Wink Savilleef36ef62014-06-11 08:39:38 -07001495 throws ImsException {
Brad Ebinger16780ff2017-01-26 11:18:21 -08001496 // FIXME: manage the multiple Ut interfaces based on the session id
Brad Ebinger138b4a62017-06-20 16:29:50 -07001497 if (mUt != null && mUt.isBinderAlive()) {
1498 return mUt;
Wink Savilleef36ef62014-06-11 08:39:38 -07001499 }
1500
Brad Ebinger138b4a62017-06-20 16:29:50 -07001501 checkAndThrowExceptionIfServiceUnavailable();
1502 try {
1503 IImsUt iUt = mImsServiceProxy.getUtInterface();
1504
1505 if (iUt == null) {
1506 throw new ImsException("getSupplementaryServiceConfiguration()",
1507 ImsReasonInfo.CODE_UT_NOT_SUPPORTED);
1508 }
1509
1510 mUt = new ImsUt(iUt);
1511 } catch (RemoteException e) {
1512 throw new ImsException("getSupplementaryServiceConfiguration()", e,
1513 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1514 }
Wink Savilleef36ef62014-06-11 08:39:38 -07001515 return mUt;
1516 }
1517
1518 /**
1519 * Checks if the IMS service has successfully registered to the IMS network
1520 * with the specified service & call type.
1521 *
Wink Savilleef36ef62014-06-11 08:39:38 -07001522 * @param serviceType a service type that is specified in {@link ImsCallProfile}
1523 * {@link ImsCallProfile#SERVICE_TYPE_NORMAL}
1524 * {@link ImsCallProfile#SERVICE_TYPE_EMERGENCY}
1525 * @param callType a call type that is specified in {@link ImsCallProfile}
1526 * {@link ImsCallProfile#CALL_TYPE_VOICE_N_VIDEO}
1527 * {@link ImsCallProfile#CALL_TYPE_VOICE}
1528 * {@link ImsCallProfile#CALL_TYPE_VT}
1529 * {@link ImsCallProfile#CALL_TYPE_VS}
1530 * @return true if the specified service id is connected to the IMS network;
1531 * false otherwise
1532 * @throws ImsException if calling the IMS service results in an error
1533 */
Brad Ebingerb5f30c72017-02-17 14:54:31 -08001534 public boolean isConnected(int serviceType, int callType)
Wink Savilleef36ef62014-06-11 08:39:38 -07001535 throws ImsException {
1536 checkAndThrowExceptionIfServiceUnavailable();
1537
1538 try {
Brad Ebingerb5f30c72017-02-17 14:54:31 -08001539 return mImsServiceProxy.isConnected(serviceType, callType);
Wink Savilleef36ef62014-06-11 08:39:38 -07001540 } catch (RemoteException e) {
1541 throw new ImsException("isServiceConnected()", e,
1542 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1543 }
1544 }
1545
1546 /**
1547 * Checks if the specified IMS service is opend.
1548 *
Wink Savilleef36ef62014-06-11 08:39:38 -07001549 * @return true if the specified service id is opened; false otherwise
1550 * @throws ImsException if calling the IMS service results in an error
1551 */
Brad Ebingerb5f30c72017-02-17 14:54:31 -08001552 public boolean isOpened() throws ImsException {
Wink Savilleef36ef62014-06-11 08:39:38 -07001553 checkAndThrowExceptionIfServiceUnavailable();
1554
1555 try {
Brad Ebingerb5f30c72017-02-17 14:54:31 -08001556 return mImsServiceProxy.isOpened();
Wink Savilleef36ef62014-06-11 08:39:38 -07001557 } catch (RemoteException e) {
1558 throw new ImsException("isOpened()", e,
1559 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1560 }
1561 }
1562
1563 /**
1564 * Creates a {@link ImsCallProfile} from the service capabilities & IMS registration state.
1565 *
Brad Ebinger16780ff2017-01-26 11:18:21 -08001566 * @param sessionId a session id which is obtained from {@link ImsManager#open}
Wink Savilleef36ef62014-06-11 08:39:38 -07001567 * @param serviceType a service type that is specified in {@link ImsCallProfile}
1568 * {@link ImsCallProfile#SERVICE_TYPE_NONE}
1569 * {@link ImsCallProfile#SERVICE_TYPE_NORMAL}
1570 * {@link ImsCallProfile#SERVICE_TYPE_EMERGENCY}
1571 * @param callType a call type that is specified in {@link ImsCallProfile}
1572 * {@link ImsCallProfile#CALL_TYPE_VOICE}
1573 * {@link ImsCallProfile#CALL_TYPE_VT}
1574 * {@link ImsCallProfile#CALL_TYPE_VT_TX}
1575 * {@link ImsCallProfile#CALL_TYPE_VT_RX}
1576 * {@link ImsCallProfile#CALL_TYPE_VT_NODIR}
1577 * {@link ImsCallProfile#CALL_TYPE_VS}
1578 * {@link ImsCallProfile#CALL_TYPE_VS_TX}
1579 * {@link ImsCallProfile#CALL_TYPE_VS_RX}
1580 * @return a {@link ImsCallProfile} object
1581 * @throws ImsException if calling the IMS service results in an error
1582 */
Brad Ebingerb5f30c72017-02-17 14:54:31 -08001583 public ImsCallProfile createCallProfile(int sessionId, int serviceType, int callType)
1584 throws ImsException {
Wink Savilleef36ef62014-06-11 08:39:38 -07001585 checkAndThrowExceptionIfServiceUnavailable();
1586
1587 try {
Brad Ebinger16780ff2017-01-26 11:18:21 -08001588 return mImsServiceProxy.createCallProfile(sessionId, serviceType, callType);
Wink Savilleef36ef62014-06-11 08:39:38 -07001589 } catch (RemoteException e) {
1590 throw new ImsException("createCallProfile()", e,
1591 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1592 }
1593 }
1594
1595 /**
1596 * Creates a {@link ImsCall} to make a call.
1597 *
Brad Ebinger16780ff2017-01-26 11:18:21 -08001598 * @param sessionId a session id which is obtained from {@link ImsManager#open}
Wink Savilleef36ef62014-06-11 08:39:38 -07001599 * @param profile a call profile to make the call
1600 * (it contains service type, call type, media information, etc.)
1601 * @param participants participants to invite the conference call
1602 * @param listener listen to the call events from {@link ImsCall}
1603 * @return a {@link ImsCall} object
1604 * @throws ImsException if calling the IMS service results in an error
1605 */
Brad Ebinger16780ff2017-01-26 11:18:21 -08001606 public ImsCall makeCall(int sessionId, ImsCallProfile profile, String[] callees,
Wink Savilleef36ef62014-06-11 08:39:38 -07001607 ImsCall.Listener listener) throws ImsException {
1608 if (DBG) {
Brad Ebinger16780ff2017-01-26 11:18:21 -08001609 log("makeCall :: sessionId=" + sessionId
fionaxu7b3107c2016-07-06 14:04:06 -07001610 + ", profile=" + profile);
Wink Savilleef36ef62014-06-11 08:39:38 -07001611 }
1612
1613 checkAndThrowExceptionIfServiceUnavailable();
1614
1615 ImsCall call = new ImsCall(mContext, profile);
1616
1617 call.setListener(listener);
Brad Ebinger16780ff2017-01-26 11:18:21 -08001618 ImsCallSession session = createCallSession(sessionId, profile);
Wink Savilleef36ef62014-06-11 08:39:38 -07001619
1620 if ((callees != null) && (callees.length == 1)) {
1621 call.start(session, callees[0]);
1622 } else {
1623 call.start(session, callees);
1624 }
1625
1626 return call;
1627 }
1628
1629 /**
1630 * Creates a {@link ImsCall} to take an incoming call.
1631 *
Brad Ebinger16780ff2017-01-26 11:18:21 -08001632 * @param sessionId a session id which is obtained from {@link ImsManager#open}
Wink Savilleef36ef62014-06-11 08:39:38 -07001633 * @param incomingCallIntent the incoming call broadcast intent
1634 * @param listener to listen to the call events from {@link ImsCall}
1635 * @return a {@link ImsCall} object
1636 * @throws ImsException if calling the IMS service results in an error
1637 */
Brad Ebinger16780ff2017-01-26 11:18:21 -08001638 public ImsCall takeCall(int sessionId, Intent incomingCallIntent,
Wink Savilleef36ef62014-06-11 08:39:38 -07001639 ImsCall.Listener listener) throws ImsException {
1640 if (DBG) {
Brad Ebinger16780ff2017-01-26 11:18:21 -08001641 log("takeCall :: sessionId=" + sessionId
Wink Savilleef36ef62014-06-11 08:39:38 -07001642 + ", incomingCall=" + incomingCallIntent);
1643 }
1644
1645 checkAndThrowExceptionIfServiceUnavailable();
1646
1647 if (incomingCallIntent == null) {
1648 throw new ImsException("Can't retrieve session with null intent",
1649 ImsReasonInfo.CODE_LOCAL_ILLEGAL_ARGUMENT);
1650 }
1651
Brad Ebinger16780ff2017-01-26 11:18:21 -08001652 int incomingServiceId = getImsSessionId(incomingCallIntent);
Wink Savilleef36ef62014-06-11 08:39:38 -07001653
Brad Ebinger16780ff2017-01-26 11:18:21 -08001654 if (sessionId != incomingServiceId) {
Wink Savilleef36ef62014-06-11 08:39:38 -07001655 throw new ImsException("Service id is mismatched in the incoming call intent",
1656 ImsReasonInfo.CODE_LOCAL_ILLEGAL_ARGUMENT);
1657 }
1658
1659 String callId = getCallId(incomingCallIntent);
1660
1661 if (callId == null) {
1662 throw new ImsException("Call ID missing in the incoming call intent",
1663 ImsReasonInfo.CODE_LOCAL_ILLEGAL_ARGUMENT);
1664 }
1665
1666 try {
Brad Ebinger16780ff2017-01-26 11:18:21 -08001667 IImsCallSession session = mImsServiceProxy.getPendingCallSession(sessionId, callId);
Wink Savilleef36ef62014-06-11 08:39:38 -07001668
1669 if (session == null) {
1670 throw new ImsException("No pending session for the call",
1671 ImsReasonInfo.CODE_LOCAL_NO_PENDING_CALL);
1672 }
1673
1674 ImsCall call = new ImsCall(mContext, session.getCallProfile());
1675
1676 call.attachSession(new ImsCallSession(session));
1677 call.setListener(listener);
1678
1679 return call;
1680 } catch (Throwable t) {
1681 throw new ImsException("takeCall()", t, ImsReasonInfo.CODE_UNSPECIFIED);
1682 }
1683 }
1684
1685 /**
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -05001686 * Gets the config interface to get/set service/capability parameters.
1687 *
1688 * @return the ImsConfig instance.
1689 * @throws ImsException if getting the setting interface results in an error.
1690 */
1691 public ImsConfig getConfigInterface() throws ImsException {
Brad Ebinger138b4a62017-06-20 16:29:50 -07001692 if (mConfig != null && mConfig.isBinderAlive()) {
1693 return mConfig;
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -05001694 }
Brad Ebinger138b4a62017-06-20 16:29:50 -07001695
1696 checkAndThrowExceptionIfServiceUnavailable();
1697 try {
1698 IImsConfig config = mImsServiceProxy.getConfigInterface();
1699 if (config == null) {
1700 throw new ImsException("getConfigInterface()",
1701 ImsReasonInfo.CODE_LOCAL_SERVICE_UNAVAILABLE);
1702 }
1703 mConfig = new ImsConfig(config, mContext);
1704 } catch (RemoteException e) {
1705 throw new ImsException("getConfigInterface()", e,
1706 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1707 }
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -05001708 return mConfig;
1709 }
1710
Hall Liue511a202017-08-17 15:49:58 -07001711 /**
1712 * Set the TTY mode. This is the actual tty mode (varies depending on peripheral status)
1713 */
1714 public void setTtyMode(int ttyMode) throws ImsException {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001715 if (!getBooleanCarrierConfig(
Hall Liue511a202017-08-17 15:49:58 -07001716 CarrierConfigManager.KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL)) {
1717 setAdvanced4GMode((ttyMode == TelecomManager.TTY_MODE_OFF) &&
Brad Ebinger479f52c2017-08-28 13:19:22 -07001718 isEnhanced4gLteModeSettingEnabledByUser());
Hall Liue511a202017-08-17 15:49:58 -07001719 }
1720 }
1721
1722 /**
1723 * Sets the UI TTY mode. This is the preferred TTY mode that the user sets in the call
1724 * settings screen.
1725 */
Brad Ebingerb5f30c72017-02-17 14:54:31 -08001726 public void setUiTTYMode(Context context, int uiTtyMode, Message onComplete)
Shriram Ganeshc403b7b2014-08-14 14:18:57 +05301727 throws ImsException {
1728
Etan Cohen82f78122014-12-15 10:10:14 -08001729 checkAndThrowExceptionIfServiceUnavailable();
Shriram Ganeshc403b7b2014-08-14 14:18:57 +05301730
Etan Cohen82f78122014-12-15 10:10:14 -08001731 try {
Brad Ebingerb5f30c72017-02-17 14:54:31 -08001732 mImsServiceProxy.setUiTTYMode(uiTtyMode, onComplete);
Etan Cohen82f78122014-12-15 10:10:14 -08001733 } catch (RemoteException e) {
1734 throw new ImsException("setTTYMode()", e,
1735 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1736 }
Shriram Ganeshc403b7b2014-08-14 14:18:57 +05301737 }
1738
Naveen Kalla525c3a22017-02-06 14:46:42 -08001739 private ImsReasonInfo makeACopy(ImsReasonInfo imsReasonInfo) {
1740 Parcel p = Parcel.obtain();
1741 imsReasonInfo.writeToParcel(p, 0);
1742 p.setDataPosition(0);
1743 ImsReasonInfo clonedReasonInfo = ImsReasonInfo.CREATOR.createFromParcel(p);
1744 p.recycle();
1745 return clonedReasonInfo;
1746 }
1747
1748 /**
1749 * Get Recent IMS Disconnect Reasons.
1750 *
1751 * @return ArrayList of ImsReasonInfo objects. MAX size of the arraylist
1752 * is MAX_RECENT_DISCONNECT_REASONS. The objects are in the
1753 * chronological order.
1754 */
1755 public ArrayList<ImsReasonInfo> getRecentImsDisconnectReasons() {
1756 ArrayList<ImsReasonInfo> disconnectReasons = new ArrayList<>();
1757
1758 for (ImsReasonInfo reason : mRecentDisconnectReasons) {
1759 disconnectReasons.add(makeACopy(reason));
1760 }
1761 return disconnectReasons;
1762 }
Brad Ebinger16417b42017-03-07 13:48:50 -08001763
Brad Ebinger16780ff2017-01-26 11:18:21 -08001764 public int getImsServiceStatus() throws ImsException {
Brad Ebinger16780ff2017-01-26 11:18:21 -08001765 return mImsServiceProxy.getFeatureStatus();
1766 }
Naveen Kalla525c3a22017-02-06 14:46:42 -08001767
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -05001768 /**
Junda Liue7663c02015-06-23 11:16:26 -07001769 * Get the boolean config from carrier config manager.
1770 *
Brad Ebinger16417b42017-03-07 13:48:50 -08001771 * @param key config key defined in CarrierConfigManager
1772 * @return boolean value of corresponding key.
1773 */
Brad Ebinger479f52c2017-08-28 13:19:22 -07001774 private boolean getBooleanCarrierConfig(String key) {
Brad Ebinger16417b42017-03-07 13:48:50 -08001775 int[] subIds = SubscriptionManager.getSubId(mPhoneId);
1776 int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1777 if (subIds != null && subIds.length >= 1) {
1778 subId = subIds[0];
1779 }
1780 PersistableBundle b = null;
1781 if (mConfigManager != null) {
1782 // If an invalid subId is used, this bundle will contain default values.
1783 b = mConfigManager.getConfigForSubId(subId);
1784 }
1785 if (b != null) {
1786 return b.getBoolean(key);
1787 } else {
1788 // Return static default defined in CarrierConfigManager.
1789 return CarrierConfigManager.getDefaultConfig().getBoolean(key);
1790 }
1791 }
1792
1793 /**
fionaxu5803ef02016-03-08 11:48:48 -08001794 * Get the int config from carrier config manager.
1795 *
Brad Ebinger16417b42017-03-07 13:48:50 -08001796 * @param key config key defined in CarrierConfigManager
1797 * @return integer value of corresponding key.
1798 */
Brad Ebinger479f52c2017-08-28 13:19:22 -07001799 private int getIntCarrierConfig(String key) {
Brad Ebinger16417b42017-03-07 13:48:50 -08001800 int[] subIds = SubscriptionManager.getSubId(mPhoneId);
1801 int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1802 if (subIds != null && subIds.length >= 1) {
1803 subId = subIds[0];
1804 }
1805 PersistableBundle b = null;
1806 if (mConfigManager != null) {
1807 // If an invalid subId is used, this bundle will contain default values.
1808 b = mConfigManager.getConfigForSubId(subId);
1809 }
1810 if (b != null) {
1811 return b.getInt(key);
1812 } else {
1813 // Return static default defined in CarrierConfigManager.
1814 return CarrierConfigManager.getDefaultConfig().getInt(key);
1815 }
1816 }
1817
1818 /**
Wink Savilleef36ef62014-06-11 08:39:38 -07001819 * Gets the call ID from the specified incoming call broadcast intent.
1820 *
1821 * @param incomingCallIntent the incoming call broadcast intent
1822 * @return the call ID or null if the intent does not contain it
1823 */
1824 private static String getCallId(Intent incomingCallIntent) {
1825 if (incomingCallIntent == null) {
1826 return null;
1827 }
1828
1829 return incomingCallIntent.getStringExtra(EXTRA_CALL_ID);
1830 }
1831
1832 /**
1833 * Gets the service type from the specified incoming call broadcast intent.
1834 *
1835 * @param incomingCallIntent the incoming call broadcast intent
Brad Ebinger16780ff2017-01-26 11:18:21 -08001836 * @return the session identifier or -1 if the intent does not contain it
Wink Savilleef36ef62014-06-11 08:39:38 -07001837 */
Brad Ebinger16780ff2017-01-26 11:18:21 -08001838 private static int getImsSessionId(Intent incomingCallIntent) {
Wink Savilleef36ef62014-06-11 08:39:38 -07001839 if (incomingCallIntent == null) {
1840 return (-1);
1841 }
1842
1843 return incomingCallIntent.getIntExtra(EXTRA_SERVICE_ID, -1);
1844 }
1845
1846 /**
Brad Ebingerb10b61e2017-04-18 11:45:26 -07001847 * Checks to see if the ImsService Binder is connected. If it is not, we try to create the
1848 * connection again.
Wink Savilleef36ef62014-06-11 08:39:38 -07001849 */
1850 private void checkAndThrowExceptionIfServiceUnavailable()
1851 throws ImsException {
Brad Ebinger16780ff2017-01-26 11:18:21 -08001852 if (mImsServiceProxy == null || !mImsServiceProxy.isBinderAlive()) {
1853 createImsService();
Wink Savilleef36ef62014-06-11 08:39:38 -07001854
Brad Ebinger16780ff2017-01-26 11:18:21 -08001855 if (mImsServiceProxy == null) {
Wink Savilleef36ef62014-06-11 08:39:38 -07001856 throw new ImsException("Service is unavailable",
1857 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1858 }
1859 }
1860 }
1861
Brad Ebinger16780ff2017-01-26 11:18:21 -08001862 /**
1863 * Binds the IMS service to make/receive the call. Supports two methods of exposing an
1864 * ImsService:
1865 * 1) com.android.ims.ImsService implementation in ServiceManager (deprecated).
1866 * 2) android.telephony.ims.ImsService implementation through ImsResolver.
1867 */
1868 private void createImsService() {
1869 if (!mConfigDynamicBind) {
Brad Ebinger44fd8af2017-12-14 14:24:02 -08001870 // Deprecated method of binding
Brad Ebinger16780ff2017-01-26 11:18:21 -08001871 Rlog.i(TAG, "Creating ImsService using ServiceManager");
Brad Ebinger44fd8af2017-12-14 14:24:02 -08001872 mImsServiceProxy = ImsServiceProxyCompat.create(mPhoneId, mDeathRecipient);
Brad Ebinger16780ff2017-01-26 11:18:21 -08001873 } else {
1874 Rlog.i(TAG, "Creating ImsService using ImsResolver");
Brad Ebinger44fd8af2017-12-14 14:24:02 -08001875 mImsServiceProxy = ImsServiceProxy.create(mContext, mPhoneId);
Brad Ebinger16780ff2017-01-26 11:18:21 -08001876 }
Brad Ebinger44fd8af2017-12-14 14:24:02 -08001877 // Forwarding interface to tell mStatusCallbacks that the Proxy is unavailable.
1878 mImsServiceProxy.setStatusCallback(new ImsServiceProxy.IFeatureUpdate() {
1879 @Override
1880 public void notifyStateChanged() {
1881 mStatusCallbacks.forEach(ImsServiceProxy.IFeatureUpdate::notifyStateChanged);
1882 }
1883
1884 @Override
1885 public void notifyUnavailable() {
1886 mStatusCallbacks.forEach(ImsServiceProxy.IFeatureUpdate::notifyUnavailable);
1887 }
1888 });
Brad Ebinger9a0280c2017-06-01 15:58:48 -07001889 // We have created a new ImsService connection, signal for re-registration
1890 synchronized (mHasRegisteredLock) {
1891 mHasRegisteredForProxy = false;
1892 }
Etan Cohend7727462014-07-12 14:54:10 -07001893 }
1894
Wink Savilleef36ef62014-06-11 08:39:38 -07001895 /**
1896 * Creates a {@link ImsCallSession} with the specified call profile.
1897 * Use other methods, if applicable, instead of interacting with
1898 * {@link ImsCallSession} directly.
1899 *
1900 * @param serviceId a service id which is obtained from {@link ImsManager#open}
1901 * @param profile a call profile to make the call
1902 */
1903 private ImsCallSession createCallSession(int serviceId,
1904 ImsCallProfile profile) throws ImsException {
1905 try {
Brad Ebingerb10b61e2017-04-18 11:45:26 -07001906 // Throws an exception if the ImsService Feature is not ready to accept commands.
Brad Ebinger16780ff2017-01-26 11:18:21 -08001907 return new ImsCallSession(mImsServiceProxy.createCallSession(serviceId, profile, null));
Wink Savilleef36ef62014-06-11 08:39:38 -07001908 } catch (RemoteException e) {
Brad Ebingerb10b61e2017-04-18 11:45:26 -07001909 Rlog.w(TAG, "CreateCallSession: Error, remote exception: " + e.getMessage());
1910 throw new ImsException("createCallSession()", e,
1911 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1912
Wink Savilleef36ef62014-06-11 08:39:38 -07001913 }
1914 }
1915
Etan Cohena00c9192014-12-23 15:02:29 -08001916 private static void log(String s) {
Wink Savilleef36ef62014-06-11 08:39:38 -07001917 Rlog.d(TAG, s);
1918 }
1919
Etan Cohena00c9192014-12-23 15:02:29 -08001920 private static void loge(String s) {
Wink Savilleef36ef62014-06-11 08:39:38 -07001921 Rlog.e(TAG, s);
1922 }
1923
Etan Cohena00c9192014-12-23 15:02:29 -08001924 private static void loge(String s, Throwable t) {
Wink Savilleef36ef62014-06-11 08:39:38 -07001925 Rlog.e(TAG, s, t);
1926 }
1927
1928 /**
ram7da5a112014-07-16 20:59:27 +05301929 * Used for turning on IMS.if its off already
1930 */
Etan Cohen82f78122014-12-15 10:10:14 -08001931 private void turnOnIms() throws ImsException {
Etan Cohen0c9c09e2014-07-25 11:09:12 -07001932 checkAndThrowExceptionIfServiceUnavailable();
1933
ram7da5a112014-07-16 20:59:27 +05301934 try {
Brad Ebingerb5f30c72017-02-17 14:54:31 -08001935 mImsServiceProxy.turnOnIms();
ram7da5a112014-07-16 20:59:27 +05301936 } catch (RemoteException e) {
1937 throw new ImsException("turnOnIms() ", e, ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1938 }
1939 }
1940
Omkar Kolangade75f3ca32014-10-24 11:10:52 -07001941 private boolean isImsTurnOffAllowed() {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001942 return isTurnOffImsAllowedByPlatform()
1943 && (!isWfcEnabledByPlatform()
1944 || !isWfcEnabledByUser());
Omkar Kolangade75f3ca32014-10-24 11:10:52 -07001945 }
1946
Amit Mahajan9cba36d2016-08-11 10:17:23 -07001947 private void setLteFeatureValues(boolean turnOn) {
1948 log("setLteFeatureValues: " + turnOn);
Omkar Kolangade75f3ca32014-10-24 11:10:52 -07001949 try {
1950 ImsConfig config = getConfigInterface();
Amit Mahajan9cba36d2016-08-11 10:17:23 -07001951 if (config != null) {
Omkar Kolangade75f3ca32014-10-24 11:10:52 -07001952 config.setFeatureValue(ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE,
Pavel Zhamaitsiakf4b90322016-01-26 14:34:09 -08001953 TelephonyManager.NETWORK_TYPE_LTE, turnOn ? 1 : 0, mImsConfigListener);
Pavel Zhamaitsiakff29b9d2016-04-15 12:16:57 -07001954
Brad Ebinger479f52c2017-08-28 13:19:22 -07001955 if (isVolteEnabledByPlatform()) {
1956 boolean ignoreDataEnabledChanged = getBooleanCarrierConfig(
Jack Yu57781852016-11-16 17:20:38 -08001957 CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS);
Brad Ebinger479f52c2017-08-28 13:19:22 -07001958 boolean enableViLte = turnOn && isVtEnabledByUser() &&
Jack Yu57781852016-11-16 17:20:38 -08001959 (ignoreDataEnabledChanged || isDataEnabled());
Pavel Zhamaitsiakff29b9d2016-04-15 12:16:57 -07001960 config.setFeatureValue(ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_LTE,
1961 TelephonyManager.NETWORK_TYPE_LTE,
1962 enableViLte ? 1 : 0,
1963 mImsConfigListener);
1964 }
Etan Cohenb651fa52014-10-22 10:51:29 -07001965 }
Omkar Kolangade75f3ca32014-10-24 11:10:52 -07001966 } catch (ImsException e) {
Amit Mahajan9cba36d2016-08-11 10:17:23 -07001967 loge("setLteFeatureValues: exception ", e);
Etan Cohencfc784d2014-08-07 18:40:31 -07001968 }
Amit Mahajan9cba36d2016-08-11 10:17:23 -07001969 }
1970
1971 private void setAdvanced4GMode(boolean turnOn) throws ImsException {
1972 checkAndThrowExceptionIfServiceUnavailable();
1973
1974 // if turnOn: first set feature values then call turnOnIms()
1975 // if turnOff: only set feature values if IMS turn off is not allowed. If turn off is
1976 // allowed, first call turnOffIms() then set feature values
Etan Cohencfc784d2014-08-07 18:40:31 -07001977 if (turnOn) {
Amit Mahajan9cba36d2016-08-11 10:17:23 -07001978 setLteFeatureValues(turnOn);
1979 log("setAdvanced4GMode: turnOnIms");
Etan Cohencfc784d2014-08-07 18:40:31 -07001980 turnOnIms();
Amit Mahajan9cba36d2016-08-11 10:17:23 -07001981 } else {
1982 if (isImsTurnOffAllowed()) {
1983 log("setAdvanced4GMode: turnOffIms");
1984 turnOffIms();
1985 }
1986 setLteFeatureValues(turnOn);
Etan Cohencfc784d2014-08-07 18:40:31 -07001987 }
1988 }
1989
ram7da5a112014-07-16 20:59:27 +05301990 /**
1991 * Used for turning off IMS completely in order to make the device CSFB'ed.
1992 * Once turned off, all calls will be over CS.
1993 */
Etan Cohen82f78122014-12-15 10:10:14 -08001994 private void turnOffIms() throws ImsException {
Etan Cohen0c9c09e2014-07-25 11:09:12 -07001995 checkAndThrowExceptionIfServiceUnavailable();
1996
ram7da5a112014-07-16 20:59:27 +05301997 try {
Brad Ebingerb5f30c72017-02-17 14:54:31 -08001998 mImsServiceProxy.turnOffIms();
ram7da5a112014-07-16 20:59:27 +05301999 } catch (RemoteException e) {
2000 throw new ImsException("turnOffIms() ", e, ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
2001 }
2002 }
2003
Naveen Kalla525c3a22017-02-06 14:46:42 -08002004 private void addToRecentDisconnectReasons(ImsReasonInfo reason) {
2005 if (reason == null) return;
2006 while (mRecentDisconnectReasons.size() >= MAX_RECENT_DISCONNECT_REASONS) {
2007 mRecentDisconnectReasons.removeFirst();
2008 }
2009 mRecentDisconnectReasons.addLast(reason);
2010 }
2011
ram7da5a112014-07-16 20:59:27 +05302012 /**
Wink Savilleef36ef62014-06-11 08:39:38 -07002013 * Death recipient class for monitoring IMS service.
2014 */
2015 private class ImsServiceDeathRecipient implements IBinder.DeathRecipient {
2016 @Override
2017 public void binderDied() {
Brad Ebinger16780ff2017-01-26 11:18:21 -08002018 mImsServiceProxy = null;
Wink Savilleef36ef62014-06-11 08:39:38 -07002019 mUt = null;
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -05002020 mConfig = null;
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -07002021 mEcbm = null;
Tyler Gunn4d128b62016-04-13 15:44:38 -07002022 mMultiEndpoint = null;
Wink Savilleef36ef62014-06-11 08:39:38 -07002023 }
2024 }
2025
2026 /**
Brad Ebinger57b11892017-06-13 16:21:35 -07002027 * Stub implementation of the Registration listener that provides no functionality.
2028 */
2029 private class ImsRegistrationListenerBase extends IImsRegistrationListener.Stub {
2030
2031 @Override
2032 public void registrationConnected() throws RemoteException {
2033 }
2034
2035 @Override
2036 public void registrationProgressing() throws RemoteException {
2037 }
2038
2039 @Override
2040 public void registrationConnectedWithRadioTech(int imsRadioTech) throws RemoteException {
2041 }
2042
2043 @Override
2044 public void registrationProgressingWithRadioTech(int imsRadioTech) throws RemoteException {
2045 }
2046
2047 @Override
2048 public void registrationDisconnected(ImsReasonInfo imsReasonInfo) throws RemoteException {
2049 }
2050
2051 @Override
2052 public void registrationResumed() throws RemoteException {
2053 }
2054
2055 @Override
2056 public void registrationSuspended() throws RemoteException {
2057 }
2058
2059 @Override
2060 public void registrationServiceCapabilityChanged(int serviceClass, int event)
2061 throws RemoteException {
2062 }
2063
2064 @Override
2065 public void registrationFeatureCapabilityChanged(int serviceClass, int[] enabledFeatures,
2066 int[] disabledFeatures) throws RemoteException {
2067 }
2068
2069 @Override
2070 public void voiceMessageCountUpdate(int count) throws RemoteException {
2071 }
2072
2073 @Override
2074 public void registrationAssociatedUriChanged(Uri[] uris) throws RemoteException {
2075 }
2076
2077 @Override
2078 public void registrationChangeFailed(int targetAccessTech, ImsReasonInfo imsReasonInfo)
2079 throws RemoteException {
2080 }
2081 }
2082
2083 /**
Wink Savilleef36ef62014-06-11 08:39:38 -07002084 * Adapter class for {@link IImsRegistrationListener}.
2085 */
Naveen Kalla196fd3b2017-02-14 14:55:24 -08002086 private class ImsRegistrationListenerProxy extends IImsRegistrationListener.Stub {
Wink Savilleef36ef62014-06-11 08:39:38 -07002087
Omkar Kolangadea7ced642015-05-04 17:55:13 -07002088 @Deprecated
Wink Savilleef36ef62014-06-11 08:39:38 -07002089 public void registrationConnected() {
2090 if (DBG) {
2091 log("registrationConnected ::");
2092 }
2093
Brad Ebinger9a0280c2017-06-01 15:58:48 -07002094 synchronized (mRegistrationListeners) {
2095 mRegistrationListeners.forEach(l -> l.onImsConnected(
2096 ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN));
Wink Savilleef36ef62014-06-11 08:39:38 -07002097 }
2098 }
2099
Omkar Kolangadea7ced642015-05-04 17:55:13 -07002100 @Deprecated
Rekha Kumar14631742015-02-04 10:47:00 -08002101 public void registrationProgressing() {
Wink Savilleef36ef62014-06-11 08:39:38 -07002102 if (DBG) {
Rekha Kumar14631742015-02-04 10:47:00 -08002103 log("registrationProgressing ::");
Wink Savilleef36ef62014-06-11 08:39:38 -07002104 }
2105
Brad Ebinger9a0280c2017-06-01 15:58:48 -07002106 synchronized (mRegistrationListeners) {
2107 mRegistrationListeners.forEach(l -> l.onImsProgressing(
2108 ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN));
Rekha Kumar14631742015-02-04 10:47:00 -08002109 }
2110 }
2111
2112 @Override
Omkar Kolangadea7ced642015-05-04 17:55:13 -07002113 public void registrationConnectedWithRadioTech(int imsRadioTech) {
2114 // Note: imsRadioTech value maps to RIL_RADIO_TECHNOLOGY
2115 // values in ServiceState.java.
2116 if (DBG) {
2117 log("registrationConnectedWithRadioTech :: imsRadioTech=" + imsRadioTech);
2118 }
2119
Brad Ebinger9a0280c2017-06-01 15:58:48 -07002120 synchronized (mRegistrationListeners) {
2121 mRegistrationListeners.forEach(l -> l.onImsConnected(imsRadioTech));
Omkar Kolangadea7ced642015-05-04 17:55:13 -07002122 }
2123 }
2124
2125 @Override
2126 public void registrationProgressingWithRadioTech(int imsRadioTech) {
2127 // Note: imsRadioTech value maps to RIL_RADIO_TECHNOLOGY
2128 // values in ServiceState.java.
2129 if (DBG) {
2130 log("registrationProgressingWithRadioTech :: imsRadioTech=" + imsRadioTech);
2131 }
2132
Brad Ebinger9a0280c2017-06-01 15:58:48 -07002133 synchronized (mRegistrationListeners) {
2134 mRegistrationListeners.forEach(l -> l.onImsProgressing(imsRadioTech));
Omkar Kolangadea7ced642015-05-04 17:55:13 -07002135 }
2136 }
2137
2138 @Override
Rekha Kumar14631742015-02-04 10:47:00 -08002139 public void registrationDisconnected(ImsReasonInfo imsReasonInfo) {
2140 if (DBG) {
2141 log("registrationDisconnected :: imsReasonInfo" + imsReasonInfo);
2142 }
2143
Naveen Kalla525c3a22017-02-06 14:46:42 -08002144 addToRecentDisconnectReasons(imsReasonInfo);
Brad Ebinger9a0280c2017-06-01 15:58:48 -07002145 synchronized (mRegistrationListeners) {
2146 mRegistrationListeners.forEach(l -> l.onImsDisconnected(imsReasonInfo));
Wink Savilleef36ef62014-06-11 08:39:38 -07002147 }
2148 }
2149
2150 @Override
2151 public void registrationResumed() {
2152 if (DBG) {
2153 log("registrationResumed ::");
2154 }
2155
Brad Ebinger9a0280c2017-06-01 15:58:48 -07002156 synchronized (mRegistrationListeners) {
2157 mRegistrationListeners.forEach(ImsConnectionStateListener::onImsResumed);
Wink Savilleef36ef62014-06-11 08:39:38 -07002158 }
2159 }
2160
2161 @Override
2162 public void registrationSuspended() {
2163 if (DBG) {
2164 log("registrationSuspended ::");
2165 }
2166
Brad Ebinger9a0280c2017-06-01 15:58:48 -07002167 synchronized (mRegistrationListeners) {
2168 mRegistrationListeners.forEach(ImsConnectionStateListener::onImsSuspended);
Wink Savilleef36ef62014-06-11 08:39:38 -07002169 }
2170 }
2171
2172 @Override
2173 public void registrationServiceCapabilityChanged(int serviceClass, int event) {
2174 log("registrationServiceCapabilityChanged :: serviceClass=" +
2175 serviceClass + ", event=" + event);
2176
Brad Ebinger9a0280c2017-06-01 15:58:48 -07002177 synchronized (mRegistrationListeners) {
2178 mRegistrationListeners.forEach(l -> l.onImsConnected(
2179 ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN));
Wink Savilleef36ef62014-06-11 08:39:38 -07002180 }
2181 }
ram7da5a112014-07-16 20:59:27 +05302182
2183 @Override
2184 public void registrationFeatureCapabilityChanged(int serviceClass,
2185 int[] enabledFeatures, int[] disabledFeatures) {
2186 log("registrationFeatureCapabilityChanged :: serviceClass=" +
2187 serviceClass);
Brad Ebinger9a0280c2017-06-01 15:58:48 -07002188
2189 synchronized (mRegistrationListeners) {
2190 mRegistrationListeners.forEach(l -> l.onFeatureCapabilityChanged(serviceClass,
2191 enabledFeatures, disabledFeatures));
Libin.Tang@motorola.come2296782014-08-19 14:20:01 -05002192 }
ram7da5a112014-07-16 20:59:27 +05302193 }
2194
Shriram Ganeshd3adfad2015-05-31 10:06:15 -07002195 @Override
2196 public void voiceMessageCountUpdate(int count) {
2197 log("voiceMessageCountUpdate :: count=" + count);
2198
Brad Ebinger9a0280c2017-06-01 15:58:48 -07002199 synchronized (mRegistrationListeners) {
2200 mRegistrationListeners.forEach(l -> l.onVoiceMessageCountChanged(count));
Shriram Ganeshd3adfad2015-05-31 10:06:15 -07002201 }
2202 }
2203
Pavel Zhamaitsiak4de9cbb2016-02-11 17:21:05 -08002204 @Override
2205 public void registrationAssociatedUriChanged(Uri[] uris) {
2206 if (DBG) log("registrationAssociatedUriChanged ::");
2207
Brad Ebinger9a0280c2017-06-01 15:58:48 -07002208 synchronized (mRegistrationListeners) {
2209 mRegistrationListeners.forEach(l -> l.registrationAssociatedUriChanged(uris));
Pavel Zhamaitsiak4de9cbb2016-02-11 17:21:05 -08002210 }
2211 }
Meng Wangbb98b9b2016-12-07 16:27:15 -08002212
2213 @Override
2214 public void registrationChangeFailed(int targetAccessTech, ImsReasonInfo imsReasonInfo) {
2215 if (DBG) log("registrationChangeFailed :: targetAccessTech=" + targetAccessTech +
2216 ", imsReasonInfo=" + imsReasonInfo);
2217
Brad Ebinger9a0280c2017-06-01 15:58:48 -07002218 synchronized (mRegistrationListeners) {
2219 mRegistrationListeners.forEach(l -> l.onRegistrationChangeFailed(targetAccessTech,
2220 imsReasonInfo));
Meng Wangbb98b9b2016-12-07 16:27:15 -08002221 }
2222 }
Wink Savilleef36ef62014-06-11 08:39:38 -07002223 }
Tyler Gunn4d128b62016-04-13 15:44:38 -07002224
Brad Ebinger44fd8af2017-12-14 14:24:02 -08002225 // New API for Registration, uses ImsConnectionStateListener for backwards compatibility with
2226 // deprecated APIs.
2227 private class ImsRegistrationCallback extends IImsRegistrationCallback.Stub {
2228
2229 @Override
2230 public void onRegistered(int imsRadioTech) {
2231 if (DBG) log("onRegistered ::");
2232
2233 synchronized (mRegistrationListeners) {
2234 mRegistrationListeners.forEach(l -> l.onRegistered(imsRadioTech));
2235 }
2236 }
2237
2238 @Override
2239 public void onRegistering(int imsRadioTech) {
2240 if (DBG) log("onRegistering ::");
2241
2242 synchronized (mRegistrationListeners) {
2243 mRegistrationListeners.forEach(l -> l.onRegistering(imsRadioTech));
2244 }
2245 }
2246
2247 @Override
2248 public void onDeregistered(ImsReasonInfo imsReasonInfo) {
2249 if (DBG) log("onDeregistered ::");
2250
2251 synchronized (mRegistrationListeners) {
2252 mRegistrationListeners.forEach(l -> l.onDeregistered(imsReasonInfo));
2253 }
2254 }
2255
2256 @Override
2257 public void onTechnologyChangeFailed(int targetRadioTech, ImsReasonInfo imsReasonInfo) {
2258 if (DBG) log("onTechnologyChangeFailed :: targetAccessTech=" + targetRadioTech +
2259 ", imsReasonInfo=" + imsReasonInfo);
2260
2261 synchronized (mRegistrationListeners) {
2262 mRegistrationListeners.forEach(l -> l.onTechnologyChangeFailed(targetRadioTech,
2263 imsReasonInfo));
2264 }
2265 }
2266
2267 @Override
2268 public void onSubscriberAssociatedUriChanged(Uri[] uris) {
2269 if (DBG) log("onSubscriberAssociatedUriChanged");
2270 synchronized (mRegistrationListeners) {
2271 mRegistrationListeners.forEach(l -> l.onSubscriberAssociatedUriChanged(uris));
2272 }
2273 }
2274 }
2275
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -07002276 /**
2277 * Gets the ECBM interface to request ECBM exit.
2278 *
2279 * @param serviceId a service id which is obtained from {@link ImsManager#open}
2280 * @return the ECBM interface instance
2281 * @throws ImsException if getting the ECBM interface results in an error
2282 */
2283 public ImsEcbm getEcbmInterface(int serviceId) throws ImsException {
Brad Ebinger138b4a62017-06-20 16:29:50 -07002284 if (mEcbm != null && mEcbm.isBinderAlive()) {
2285 return mEcbm;
2286 }
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -07002287
Brad Ebinger138b4a62017-06-20 16:29:50 -07002288 checkAndThrowExceptionIfServiceUnavailable();
2289 try {
2290 IImsEcbm iEcbm = mImsServiceProxy.getEcbmInterface();
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -07002291
Brad Ebinger138b4a62017-06-20 16:29:50 -07002292 if (iEcbm == null) {
2293 throw new ImsException("getEcbmInterface()",
2294 ImsReasonInfo.CODE_ECBM_NOT_SUPPORTED);
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -07002295 }
Brad Ebinger138b4a62017-06-20 16:29:50 -07002296 mEcbm = new ImsEcbm(iEcbm);
2297 } catch (RemoteException e) {
2298 throw new ImsException("getEcbmInterface()", e,
2299 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -07002300 }
2301 return mEcbm;
2302 }
Pavel Zhamaitsiak8c065f52015-11-10 14:36:44 -08002303
2304 /**
Tyler Gunn4d128b62016-04-13 15:44:38 -07002305 * Gets the Multi-Endpoint interface to subscribe to multi-enpoint notifications..
2306 *
2307 * @param serviceId a service id which is obtained from {@link ImsManager#open}
2308 * @return the multi-endpoint interface instance
2309 * @throws ImsException if getting the multi-endpoint interface results in an error
2310 */
2311 public ImsMultiEndpoint getMultiEndpointInterface(int serviceId) throws ImsException {
Brad Ebinger138b4a62017-06-20 16:29:50 -07002312 if (mMultiEndpoint != null && mMultiEndpoint.isBinderAlive()) {
2313 return mMultiEndpoint;
Tyler Gunn4d128b62016-04-13 15:44:38 -07002314 }
Brad Ebinger138b4a62017-06-20 16:29:50 -07002315
2316 checkAndThrowExceptionIfServiceUnavailable();
2317 try {
2318 IImsMultiEndpoint iImsMultiEndpoint = mImsServiceProxy.getMultiEndpointInterface();
2319
2320 if (iImsMultiEndpoint == null) {
2321 throw new ImsException("getMultiEndpointInterface()",
2322 ImsReasonInfo.CODE_MULTIENDPOINT_NOT_SUPPORTED);
2323 }
2324 mMultiEndpoint = new ImsMultiEndpoint(iImsMultiEndpoint);
2325 } catch (RemoteException e) {
2326 throw new ImsException("getMultiEndpointInterface()", e,
2327 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
2328 }
2329
Tyler Gunn4d128b62016-04-13 15:44:38 -07002330 return mMultiEndpoint;
2331 }
2332
2333 /**
Pavel Zhamaitsiak8c065f52015-11-10 14:36:44 -08002334 * Resets ImsManager settings back to factory defaults.
2335 *
Brad Ebinger479f52c2017-08-28 13:19:22 -07002336 * @deprecated Doesn't support MSIM devices. Use {@link #factoryReset()} instead.
Brad Ebinger16417b42017-03-07 13:48:50 -08002337 *
Pavel Zhamaitsiak8c065f52015-11-10 14:36:44 -08002338 * @hide
2339 */
2340 public static void factoryReset(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07002341 ImsManager mgr = ImsManager.getInstance(context,
2342 SubscriptionManager.getDefaultVoicePhoneId());
2343 if (mgr != null) {
2344 mgr.factoryReset();
2345 }
2346 loge("factoryReset: ImsManager null.");
Pavel Zhamaitsiak8c065f52015-11-10 14:36:44 -08002347 }
Jack Yu2f102bd2015-12-28 15:31:48 -08002348
Brad Ebinger16417b42017-03-07 13:48:50 -08002349 /**
2350 * Resets ImsManager settings back to factory defaults.
2351 *
2352 * @hide
2353 */
Brad Ebinger479f52c2017-08-28 13:19:22 -07002354 public void factoryReset() {
Brad Ebinger16417b42017-03-07 13:48:50 -08002355 // Set VoLTE to default
Malcolm Chen212ca652017-09-28 17:28:45 -07002356 SubscriptionManager.setSubscriptionProperty(getSubId(),
manabu, shimoda96aee542017-10-06 15:39:36 +09002357 SubscriptionManager.ENHANCED_4G_MODE_ENABLED,
2358 booleanToPropertyString(getBooleanCarrierConfig(
2359 CarrierConfigManager.KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL)));
Brad Ebinger16417b42017-03-07 13:48:50 -08002360
2361 // Set VoWiFi to default
Malcolm Chen212ca652017-09-28 17:28:45 -07002362 SubscriptionManager.setSubscriptionProperty(getSubId(),
2363 SubscriptionManager.WFC_IMS_ENABLED,
2364 booleanToPropertyString(getBooleanCarrierConfig(
2365 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL)));
Brad Ebinger16417b42017-03-07 13:48:50 -08002366
2367 // Set VoWiFi mode to default
Malcolm Chen212ca652017-09-28 17:28:45 -07002368 SubscriptionManager.setSubscriptionProperty(getSubId(),
2369 SubscriptionManager.WFC_IMS_MODE,
2370 Integer.toString(getIntCarrierConfig(
2371 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT)));
Brad Ebinger16417b42017-03-07 13:48:50 -08002372
2373 // Set VoWiFi roaming to default
Malcolm Chen212ca652017-09-28 17:28:45 -07002374 SubscriptionManager.setSubscriptionProperty(getSubId(),
2375 SubscriptionManager.WFC_IMS_ROAMING_ENABLED,
2376 booleanToPropertyString(getBooleanCarrierConfig(
2377 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_ENABLED_BOOL)));
Brad Ebinger16417b42017-03-07 13:48:50 -08002378
2379 // Set VT to default
Malcolm Chen212ca652017-09-28 17:28:45 -07002380 SubscriptionManager.setSubscriptionProperty(getSubId(),
2381 SubscriptionManager.VT_IMS_ENABLED, booleanToPropertyString(true));
Brad Ebinger16417b42017-03-07 13:48:50 -08002382
2383 // Push settings to ImsConfig
Brad Ebinger479f52c2017-08-28 13:19:22 -07002384 updateImsServiceConfig(true);
Brad Ebinger16417b42017-03-07 13:48:50 -08002385 }
2386
Amit Mahajan24f7b162016-07-21 16:33:53 -07002387 private boolean isDataEnabled() {
Malcolm Chend0ef12c2017-12-20 11:38:25 -08002388 return new TelephonyManager(mContext, getSubId()).isMobileDataEnabled();
Amit Mahajan24f7b162016-07-21 16:33:53 -07002389 }
2390
2391 private boolean isVolteProvisioned() {
Malcolm Chen18837ff2017-10-25 17:05:41 -07002392 return getProvisionedBoolNoException(
2393 ImsConfig.ConfigConstants.VLT_SETTING_ENABLED);
Amit Mahajan24f7b162016-07-21 16:33:53 -07002394 }
2395
2396 private boolean isWfcProvisioned() {
Malcolm Chen18837ff2017-10-25 17:05:41 -07002397 return getProvisionedBoolNoException(
2398 ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED);
Amit Mahajan24f7b162016-07-21 16:33:53 -07002399 }
2400
2401 private boolean isVtProvisioned() {
Malcolm Chen18837ff2017-10-25 17:05:41 -07002402 return getProvisionedBoolNoException(
2403 ImsConfig.ConfigConstants.LVC_SETTING_ENABLED);
Jack Yu643ffe42016-07-08 14:25:46 -07002404 }
2405
Malcolm Chen212ca652017-09-28 17:28:45 -07002406 private static String booleanToPropertyString(boolean bool) {
2407 return bool ? "1" : "0";
2408 }
2409
2410
Jack Yu2f102bd2015-12-28 15:31:48 -08002411 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2412 pw.println("ImsManager:");
2413 pw.println(" mPhoneId = " + mPhoneId);
2414 pw.println(" mConfigUpdated = " + mConfigUpdated);
Brad Ebinger16780ff2017-01-26 11:18:21 -08002415 pw.println(" mImsServiceProxy = " + mImsServiceProxy);
Amit Mahajan24f7b162016-07-21 16:33:53 -07002416 pw.println(" mDataEnabled = " + isDataEnabled());
Brad Ebinger479f52c2017-08-28 13:19:22 -07002417 pw.println(" ignoreDataEnabledChanged = " + getBooleanCarrierConfig(
Jack Yu57781852016-11-16 17:20:38 -08002418 CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS));
Jack Yu2f102bd2015-12-28 15:31:48 -08002419
Brad Ebinger479f52c2017-08-28 13:19:22 -07002420 pw.println(" isGbaValid = " + isGbaValid());
Jack Yu2f102bd2015-12-28 15:31:48 -08002421 pw.println(" isImsTurnOffAllowed = " + isImsTurnOffAllowed());
Brad Ebinger479f52c2017-08-28 13:19:22 -07002422 pw.println(" isNonTtyOrTtyOnVolteEnabled = " + isNonTtyOrTtyOnVolteEnabled());
Jack Yu2f102bd2015-12-28 15:31:48 -08002423
Brad Ebinger479f52c2017-08-28 13:19:22 -07002424 pw.println(" isVolteEnabledByPlatform = " + isVolteEnabledByPlatform());
2425 pw.println(" isVolteProvisionedOnDevice = " + isVolteProvisionedOnDevice());
Jack Yu2f102bd2015-12-28 15:31:48 -08002426 pw.println(" isEnhanced4gLteModeSettingEnabledByUser = " +
Brad Ebinger479f52c2017-08-28 13:19:22 -07002427 isEnhanced4gLteModeSettingEnabledByUser());
2428 pw.println(" isVtEnabledByPlatform = " + isVtEnabledByPlatform());
2429 pw.println(" isVtEnabledByUser = " + isVtEnabledByUser());
Jack Yu2f102bd2015-12-28 15:31:48 -08002430
Brad Ebinger479f52c2017-08-28 13:19:22 -07002431 pw.println(" isWfcEnabledByPlatform = " + isWfcEnabledByPlatform());
2432 pw.println(" isWfcEnabledByUser = " + isWfcEnabledByUser());
2433 pw.println(" getWfcMode = " + getWfcMode());
2434 pw.println(" isWfcRoamingEnabledByUser = " + isWfcRoamingEnabledByUser());
Jack Yu2f102bd2015-12-28 15:31:48 -08002435
Brad Ebinger479f52c2017-08-28 13:19:22 -07002436 pw.println(" isVtProvisionedOnDevice = " + isVtProvisionedOnDevice());
2437 pw.println(" isWfcProvisionedOnDevice = " + isWfcProvisionedOnDevice());
Jack Yu2f102bd2015-12-28 15:31:48 -08002438 pw.flush();
2439 }
Wink Savilleef36ef62014-06-11 08:39:38 -07002440}