blob: 789137812dcbbbfe6a194c68491b14c106042af7 [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
Brad Ebinger936a7d12018-01-16 09:36:56 -080019import android.annotation.Nullable;
Wink Savilleef36ef62014-06-11 08:39:38 -070020import android.app.PendingIntent;
21import android.content.Context;
Brad Ebinger936a7d12018-01-16 09:36:56 -080022import android.os.Bundle;
Brad Ebinger6ddf28e2018-02-21 16:07:23 -080023import android.os.Handler;
Wink Savilleef36ef62014-06-11 08:39:38 -070024import android.os.IBinder;
Brad Ebinger6ddf28e2018-02-21 16:07:23 -080025import android.os.Looper;
Wink Savilleef36ef62014-06-11 08:39:38 -070026import android.os.Message;
Naveen Kalla525c3a22017-02-06 14:46:42 -080027import android.os.Parcel;
Jonathan Basseri2acea6f2015-07-01 15:00:38 -070028import android.os.PersistableBundle;
Wink Savilleef36ef62014-06-11 08:39:38 -070029import android.os.RemoteException;
Etan Cohenaf55a402014-09-04 22:34:41 -070030import android.os.SystemProperties;
Etan Cohen82f78122014-12-15 10:10:14 -080031import android.telecom.TelecomManager;
Junda Liue7663c02015-06-23 11:16:26 -070032import android.telephony.CarrierConfigManager;
Mohamed Abdalkader415e6de2018-01-19 19:48:31 -080033import android.telephony.ims.stub.ImsRegistrationImplBase;
Wink Savilleef36ef62014-06-11 08:39:38 -070034import android.telephony.Rlog;
Etan Cohen82f78122014-12-15 10:10:14 -080035import android.telephony.SubscriptionManager;
Etan Cohencfc784d2014-08-07 18:40:31 -070036import android.telephony.TelephonyManager;
Brad Ebingered690772018-01-23 13:41:32 -080037import android.telephony.ims.ImsCallProfile;
38import android.telephony.ims.ImsReasonInfo;
Brad Ebinger936a7d12018-01-16 09:36:56 -080039import android.telephony.ims.aidl.IImsConfig;
40import android.telephony.ims.aidl.IImsSmsListener;
41import android.telephony.ims.feature.CapabilityChangeRequest;
42import android.telephony.ims.feature.ImsFeature;
43import android.telephony.ims.feature.MmTelFeature;
Hall Liue511a202017-08-17 15:49:58 -070044import android.util.Log;
Wink Savilleef36ef62014-06-11 08:39:38 -070045
46import com.android.ims.internal.IImsCallSession;
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -070047import com.android.ims.internal.IImsEcbm;
Tyler Gunn4d128b62016-04-13 15:44:38 -070048import com.android.ims.internal.IImsMultiEndpoint;
Wink Savilleef36ef62014-06-11 08:39:38 -070049import com.android.ims.internal.IImsUt;
Brad Ebingered690772018-01-23 13:41:32 -080050import android.telephony.ims.ImsCallSession;
Brad Ebinger16780ff2017-01-26 11:18:21 -080051import com.android.internal.annotations.VisibleForTesting;
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -050052
Jack Yu2f102bd2015-12-28 15:31:48 -080053import java.io.FileDescriptor;
54import java.io.PrintWriter;
Naveen Kalla525c3a22017-02-06 14:46:42 -080055import java.util.ArrayList;
Etan Cohend7727462014-07-12 14:54:10 -070056import java.util.HashMap;
Brad Ebinger16780ff2017-01-26 11:18:21 -080057import java.util.Set;
Malcolm Chen45904b52017-10-25 17:05:41 -070058import java.util.concurrent.ConcurrentLinkedDeque;
Brad Ebinger0e170c72017-12-14 14:24:02 -080059import java.util.concurrent.CopyOnWriteArraySet;
Etan Cohend7727462014-07-12 14:54:10 -070060
Wink Savilleef36ef62014-06-11 08:39:38 -070061/**
62 * Provides APIs for IMS services, such as initiating IMS calls, and provides access to
63 * the operator's IMS network. This class is the starting point for any IMS actions.
64 * You can acquire an instance of it with {@link #getInstance getInstance()}.</p>
65 * <p>The APIs in this class allows you to:</p>
66 *
67 * @hide
68 */
69public class ImsManager {
Etan Cohen19604c02014-08-11 14:32:57 -070070
Etan Cohenaf55a402014-09-04 22:34:41 -070071 /*
72 * Debug flag to override configuration flag
73 */
Etan Cohenb651fa52014-10-22 10:51:29 -070074 public static final String PROPERTY_DBG_VOLTE_AVAIL_OVERRIDE = "persist.dbg.volte_avail_ovr";
75 public static final int PROPERTY_DBG_VOLTE_AVAIL_OVERRIDE_DEFAULT = 0;
Etan Cohenea2b5832014-10-23 18:50:35 -070076 public static final String PROPERTY_DBG_VT_AVAIL_OVERRIDE = "persist.dbg.vt_avail_ovr";
77 public static final int PROPERTY_DBG_VT_AVAIL_OVERRIDE_DEFAULT = 0;
Etan Cohena00c9192014-12-23 15:02:29 -080078 public static final String PROPERTY_DBG_WFC_AVAIL_OVERRIDE = "persist.dbg.wfc_avail_ovr";
79 public static final int PROPERTY_DBG_WFC_AVAIL_OVERRIDE_DEFAULT = 0;
Meng Wang9352c432016-06-08 14:22:20 -070080 public static final String PROPERTY_DBG_ALLOW_IMS_OFF_OVERRIDE = "persist.dbg.allow_ims_off";
81 public static final int PROPERTY_DBG_ALLOW_IMS_OFF_OVERRIDE_DEFAULT = 0;
Etan Cohenaf55a402014-09-04 22:34:41 -070082
Wink Savilleef36ef62014-06-11 08:39:38 -070083 /**
Wink Savilleef36ef62014-06-11 08:39:38 -070084 * The result code to be sent back with the incoming call {@link PendingIntent}.
Brad Ebinger936a7d12018-01-16 09:36:56 -080085 * @see #open(MmTelFeature.Listener)
Wink Savilleef36ef62014-06-11 08:39:38 -070086 */
87 public static final int INCOMING_CALL_RESULT_CODE = 101;
88
89 /**
90 * Key to retrieve the call ID from an incoming call intent.
Brad Ebinger936a7d12018-01-16 09:36:56 -080091 * @see #open(MmTelFeature.Listener)
Wink Savilleef36ef62014-06-11 08:39:38 -070092 */
93 public static final String EXTRA_CALL_ID = "android:imsCallID";
94
95 /**
96 * Action to broadcast when ImsService is up.
97 * Internal use only.
Brad Ebinger16780ff2017-01-26 11:18:21 -080098 * @deprecated
Wink Savilleef36ef62014-06-11 08:39:38 -070099 * @hide
100 */
101 public static final String ACTION_IMS_SERVICE_UP =
102 "com.android.ims.IMS_SERVICE_UP";
103
104 /**
105 * Action to broadcast when ImsService is down.
106 * Internal use only.
Brad Ebinger16780ff2017-01-26 11:18:21 -0800107 * @deprecated
Wink Savilleef36ef62014-06-11 08:39:38 -0700108 * @hide
109 */
110 public static final String ACTION_IMS_SERVICE_DOWN =
111 "com.android.ims.IMS_SERVICE_DOWN";
112
113 /**
Pavel Zhamaitsiak0c2f15c2015-03-12 15:37:54 -0700114 * Action to broadcast when ImsService registration fails.
115 * Internal use only.
116 * @hide
117 */
118 public static final String ACTION_IMS_REGISTRATION_ERROR =
119 "com.android.ims.REGISTRATION_ERROR";
120
121 /**
Etan Cohend7727462014-07-12 14:54:10 -0700122 * Part of the ACTION_IMS_SERVICE_UP or _DOWN intents.
Etan Cohenabbd7882014-09-26 22:35:35 -0700123 * A long value; the phone ID corresponding to the IMS service coming up or down.
Etan Cohend7727462014-07-12 14:54:10 -0700124 * Internal use only.
125 * @hide
126 */
Etan Cohenabbd7882014-09-26 22:35:35 -0700127 public static final String EXTRA_PHONE_ID = "android:phone_id";
Etan Cohend7727462014-07-12 14:54:10 -0700128
129 /**
Wink Savilleef36ef62014-06-11 08:39:38 -0700130 * Action for the incoming call intent for the Phone app.
131 * Internal use only.
132 * @hide
133 */
134 public static final String ACTION_IMS_INCOMING_CALL =
135 "com.android.ims.IMS_INCOMING_CALL";
136
137 /**
138 * Part of the ACTION_IMS_INCOMING_CALL intents.
139 * An integer value; service identifier obtained from {@link ImsManager#open}.
140 * Internal use only.
141 * @hide
142 */
143 public static final String EXTRA_SERVICE_ID = "android:imsServiceId";
144
145 /**
146 * Part of the ACTION_IMS_INCOMING_CALL intents.
147 * An boolean value; Flag to indicate that the incoming call is a normal call or call for USSD.
148 * The value "true" indicates that the incoming call is for USSD.
149 * Internal use only.
150 * @hide
151 */
152 public static final String EXTRA_USSD = "android:ussd";
153
Shriram Ganeshd3adfad2015-05-31 10:06:15 -0700154 /**
155 * Part of the ACTION_IMS_INCOMING_CALL intents.
156 * A boolean value; Flag to indicate whether the call is an unknown
157 * dialing call. Such calls are originated by sending commands (like
158 * AT commands) directly to modem without Android involvement.
159 * Even though they are not incoming calls, they are propagated
160 * to Phone app using same ACTION_IMS_INCOMING_CALL intent.
161 * Internal use only.
162 * @hide
163 */
Anju Mathapati9c033792015-06-16 16:33:16 -0700164 public static final String EXTRA_IS_UNKNOWN_CALL = "android:isUnknown";
Shriram Ganeshd3adfad2015-05-31 10:06:15 -0700165
Malcolm Chen45904b52017-10-25 17:05:41 -0700166 private static final int SYSTEM_PROPERTY_NOT_SET = -1;
167
168 // -1 indicates a subscriptionProperty value that is never set.
169 private static final int SUB_PROPERTY_NOT_INITIALIZED = -1;
170
Wink Savilleef36ef62014-06-11 08:39:38 -0700171 private static final String TAG = "ImsManager";
172 private static final boolean DBG = true;
173
Brad Ebinger6ddf28e2018-02-21 16:07:23 -0800174 /**
175 * Helper class for managing a connection to the ImsManager when the ImsService is unavailable
176 * or switches to another service.
177 */
178 public static class Connector extends Handler {
179 // Initial condition for ims connection retry.
180 private static final int IMS_RETRY_STARTING_TIMEOUT_MS = 500; // ms
181 // Ceiling bitshift amount for service query timeout, calculated as:
182 // 2^mImsServiceRetryCount * IMS_RETRY_STARTING_TIMEOUT_MS, where
183 // mImsServiceRetryCount ∊ [0, CEILING_SERVICE_RETRY_COUNT].
184 private static final int CEILING_SERVICE_RETRY_COUNT = 6;
185
186 private final Runnable mGetServiceRunnable = () -> {
187 try {
188 getImsService();
189 } catch (ImsException e) {
190 retryGetImsService();
191 }
192 };
193
194 public interface Listener {
195 /**
196 * ImsManager is connected to the underlying IMS implementation.
197 */
198 void connectionReady(ImsManager manager) throws ImsException;
199
200 /**
201 * The underlying IMS implementation is unavailable and can not be used to communicate.
202 */
203 void connectionUnavailable();
204 }
205
206 @VisibleForTesting
207 public interface RetryTimeout {
208 int get();
209 }
210
211 // Callback fires when ImsManager MMTel Feature changes state
212 private MmTelFeatureConnection.IFeatureUpdate mNotifyStatusChangedCallback =
213 new MmTelFeatureConnection.IFeatureUpdate() {
214 @Override
215 public void notifyStateChanged() {
216 try {
217 int status = ImsFeature.STATE_UNAVAILABLE;
218 synchronized (mLock) {
219 if (mImsManager != null) {
220 status = mImsManager.getImsServiceState();
221 }
222 }
223 log("Status Changed: " + status);
224 switch (status) {
225 case ImsFeature.STATE_READY: {
226 notifyReady();
227 break;
228 }
229 case ImsFeature.STATE_INITIALIZING:
230 // fall through
231 case ImsFeature.STATE_UNAVAILABLE: {
232 notifyNotReady();
233 break;
234 }
235 default: {
236 Log.w(TAG, "Unexpected State!");
237 }
238 }
239 } catch (ImsException e) {
240 // Could not get the ImsService, retry!
241 notifyNotReady();
242 retryGetImsService();
243 }
244 }
245
246 @Override
247 public void notifyUnavailable() {
248 notifyNotReady();
249 retryGetImsService();
250 }
251 };
252
253 private final Context mContext;
254 private final int mPhoneId;
255 private final Listener mListener;
256 private final Object mLock = new Object();
257
258 private int mRetryCount = 0;
259 private ImsManager mImsManager;
260
261 @VisibleForTesting
262 public RetryTimeout mRetryTimeout = () -> {
263 synchronized (mLock) {
264 int timeout = (1 << mRetryCount) * IMS_RETRY_STARTING_TIMEOUT_MS;
265 if (mRetryCount <= CEILING_SERVICE_RETRY_COUNT) {
266 mRetryCount++;
267 }
268 return timeout;
269 }
270 };
271
272 public Connector(Context context, int phoneId, Listener listener) {
273 mContext = context;
274 mPhoneId = phoneId;
275 mListener = listener;
276 }
277
278 public Connector(Context context, int phoneId, Listener listener, Looper looper) {
279 super(looper);
280 mContext = context;
281 mPhoneId = phoneId;
282 mListener= listener;
283 }
284
285 /**
286 * Start the creation of a connection to the underlying ImsService implementation. When the
287 * service is connected, {@link Listener#connectionReady(ImsManager)} will be called with
288 * an active ImsManager instance.
289 */
290 public void connect() {
291 mRetryCount = 0;
292 // Send a message to connect to the Ims Service and open a connection through
293 // getImsService().
294 post(mGetServiceRunnable);
295 }
296
297 /**
298 * Disconnect from the ImsService Implementation and clean up. When this is complete,
299 * {@link Listener#connectionUnavailable()} will be called one last time.
300 */
301 public void disconnect() {
302 removeCallbacks(mGetServiceRunnable);
303 synchronized (mLock) {
304 if (mImsManager != null) {
305 mImsManager.removeNotifyStatusChangedCallback(mNotifyStatusChangedCallback);
306 }
307 }
308 notifyNotReady();
309 }
310
311 private void retryGetImsService() {
312 synchronized (mLock) {
313 // remove callback so we do not receive updates from old ImsServiceProxy when
314 // switching between ImsServices.
315 mImsManager.removeNotifyStatusChangedCallback(mNotifyStatusChangedCallback);
316 //Leave mImsManager as null, then CallStateException will be thrown when dialing
317 mImsManager = null;
318 }
319 // Exponential backoff during retry, limited to 32 seconds.
320 loge("Connector: Retrying getting ImsService...");
321 removeCallbacks(mGetServiceRunnable);
322 postDelayed(mGetServiceRunnable, mRetryTimeout.get());
323 }
324
325 private void getImsService() throws ImsException {
326 if (DBG) log("Connector: getImsService");
327 synchronized (mLock) {
328 mImsManager = ImsManager.getInstance(mContext, mPhoneId);
329 // Adding to set, will be safe adding multiple times. If the ImsService is not
330 // active yet, this method will throw an ImsException.
331 mImsManager.addNotifyStatusChangedCallbackIfAvailable(mNotifyStatusChangedCallback);
332 }
333 // Wait for ImsService.STATE_READY to start listening for calls.
334 // Call the callback right away for compatibility with older devices that do not use
335 // states.
336 mNotifyStatusChangedCallback.notifyStateChanged();
337 }
338
339 private void notifyReady() throws ImsException {
340 ImsManager manager;
341 synchronized (mLock) {
342 mRetryCount = 0;
343 manager = mImsManager;
344 }
345 mListener.connectionReady(manager);
346 }
347
348 private void notifyNotReady() {
349 mListener.connectionUnavailable();
350 }
351 }
352
Wink Saville1e5a38a2014-10-23 10:24:46 -0700353 private static HashMap<Integer, ImsManager> sImsManagerInstances =
354 new HashMap<Integer, ImsManager>();
Etan Cohend7727462014-07-12 14:54:10 -0700355
Wink Savilleef36ef62014-06-11 08:39:38 -0700356 private Context mContext;
Brad Ebinger16417b42017-03-07 13:48:50 -0800357 private CarrierConfigManager mConfigManager;
Etan Cohenabbd7882014-09-26 22:35:35 -0700358 private int mPhoneId;
Brad Ebinger16780ff2017-01-26 11:18:21 -0800359 private final boolean mConfigDynamicBind;
Brad Ebinger936a7d12018-01-16 09:36:56 -0800360 private @Nullable MmTelFeatureConnection mMmTelFeatureConnection = null;
Wink Savilleef36ef62014-06-11 08:39:38 -0700361 private ImsServiceDeathRecipient mDeathRecipient = new ImsServiceDeathRecipient();
362 // Ut interface for the supplementary service configuration
363 private ImsUt mUt = null;
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -0500364 // Interface to get/set ims config items
365 private ImsConfig mConfig = null;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -0700366 private boolean mConfigUpdated = false;
Wink Savilleef36ef62014-06-11 08:39:38 -0700367
Pavel Zhamaitsiakf4b90322016-01-26 14:34:09 -0800368 private ImsConfigListener mImsConfigListener;
369
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -0700370 // ECBM interface
371 private ImsEcbm mEcbm = null;
372
Tyler Gunn4d128b62016-04-13 15:44:38 -0700373 private ImsMultiEndpoint mMultiEndpoint = null;
374
Brad Ebinger936a7d12018-01-16 09:36:56 -0800375 private Set<MmTelFeatureConnection.IFeatureUpdate> mStatusCallbacks =
376 new CopyOnWriteArraySet<>();
Brad Ebinger16780ff2017-01-26 11:18:21 -0800377
Amit Mahajan24f7b162016-07-21 16:33:53 -0700378 public static final String TRUE = "true";
379 public static final String FALSE = "false";
Jack Yu643ffe42016-07-08 14:25:46 -0700380
Naveen Kalla525c3a22017-02-06 14:46:42 -0800381 // mRecentDisconnectReasons stores the last 16 disconnect reasons
382 private static final int MAX_RECENT_DISCONNECT_REASONS = 16;
383 private ConcurrentLinkedDeque<ImsReasonInfo> mRecentDisconnectReasons =
384 new ConcurrentLinkedDeque<>();
385
Wink Savilleef36ef62014-06-11 08:39:38 -0700386 /**
387 * Gets a manager instance.
388 *
389 * @param context application context for creating the manager object
Etan Cohenabbd7882014-09-26 22:35:35 -0700390 * @param phoneId the phone ID for the IMS Service
391 * @return the manager instance corresponding to the phoneId
Wink Savilleef36ef62014-06-11 08:39:38 -0700392 */
Etan Cohenabbd7882014-09-26 22:35:35 -0700393 public static ImsManager getInstance(Context context, int phoneId) {
Etan Cohend7727462014-07-12 14:54:10 -0700394 synchronized (sImsManagerInstances) {
Naveen Kalla525c3a22017-02-06 14:46:42 -0800395 if (sImsManagerInstances.containsKey(phoneId)) {
Brad Ebingerff097922017-06-19 15:43:08 -0700396 ImsManager m = sImsManagerInstances.get(phoneId);
397 // May be null for some tests
398 if (m != null) {
399 m.connectIfServiceIsAvailable();
400 }
401 return m;
Naveen Kalla525c3a22017-02-06 14:46:42 -0800402 }
Wink Savilleef36ef62014-06-11 08:39:38 -0700403
Etan Cohenabbd7882014-09-26 22:35:35 -0700404 ImsManager mgr = new ImsManager(context, phoneId);
405 sImsManagerInstances.put(phoneId, mgr);
Etan Cohend7727462014-07-12 14:54:10 -0700406
407 return mgr;
408 }
Wink Savilleef36ef62014-06-11 08:39:38 -0700409 }
410
Etan Cohen45b5f312014-08-19 15:55:08 -0700411 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800412 * Returns the user configuration of Enhanced 4G LTE Mode setting.
413 *
414 * @deprecated Doesn't support MSIM devices. Use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700415 * {@link #isEnhanced4gLteModeSettingEnabledByUser()} instead.
Etan Cohen45b5f312014-08-19 15:55:08 -0700416 */
417 public static boolean isEnhanced4gLteModeSettingEnabledByUser(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700418 ImsManager mgr = ImsManager.getInstance(context,
419 SubscriptionManager.getDefaultVoicePhoneId());
420 if (mgr != null) {
421 return mgr.isEnhanced4gLteModeSettingEnabledByUser();
Sungmin Choi2f1af952016-02-01 17:15:35 +0900422 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700423 loge("isEnhanced4gLteModeSettingEnabledByUser: ImsManager null, returning default value.");
424 return false;
Etan Cohen45b5f312014-08-19 15:55:08 -0700425 }
426
427 /**
manabu, shimoda2335b702017-10-06 15:39:36 +0900428 * Returns the user configuration of Enhanced 4G LTE Mode setting for slot. If the option is
429 * not editable ({@link CarrierConfigManager#KEY_EDITABLE_ENHANCED_4G_LTE_BOOL} is false),
430 * this method will return default value specified by
431 * {@link CarrierConfigManager#KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL}.
Brad Ebinger16417b42017-03-07 13:48:50 -0800432 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700433 public boolean isEnhanced4gLteModeSettingEnabledByUser() {
Malcolm Chen201d2312017-09-28 17:28:45 -0700434 int setting = SubscriptionManager.getIntegerSubscriptionProperty(
435 getSubId(), SubscriptionManager.ENHANCED_4G_MODE_ENABLED,
436 SUB_PROPERTY_NOT_INITIALIZED, mContext);
437 boolean onByDefault = getBooleanCarrierConfig(
438 CarrierConfigManager.KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL);
439
440 // If Enhanced 4G LTE Mode is uneditable or not initialized, we use the default value
441 if (!getBooleanCarrierConfig(CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL)
442 || setting == SUB_PROPERTY_NOT_INITIALIZED) {
443 return onByDefault;
444 } else {
445 return (setting == ImsConfig.FeatureValueConstants.ON);
Brad Ebinger16417b42017-03-07 13:48:50 -0800446 }
Brad Ebinger16417b42017-03-07 13:48:50 -0800447 }
448
449 /**
450 * Change persistent Enhanced 4G LTE Mode setting.
451 *
Brad Ebinger479f52c2017-08-28 13:19:22 -0700452 * @deprecated Doesn't support MSIM devices. Use {@link #setEnhanced4gLteModeSetting(boolean)}
Brad Ebinger16417b42017-03-07 13:48:50 -0800453 * instead.
Etan Cohen82f78122014-12-15 10:10:14 -0800454 */
455 public static void setEnhanced4gLteModeSetting(Context context, boolean enabled) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700456 ImsManager mgr = ImsManager.getInstance(context,
457 SubscriptionManager.getDefaultVoicePhoneId());
458 if (mgr != null) {
459 mgr.setEnhanced4gLteModeSetting(enabled);
Etan Cohen82f78122014-12-15 10:10:14 -0800460 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700461 loge("setEnhanced4gLteModeSetting: ImsManager null, value not set.");
Etan Cohen82f78122014-12-15 10:10:14 -0800462 }
463
464 /**
manabu, shimoda2335b702017-10-06 15:39:36 +0900465 * Change persistent Enhanced 4G LTE Mode setting. If the option is not editable
Brad Ebinger16417b42017-03-07 13:48:50 -0800466 * ({@link CarrierConfigManager#KEY_EDITABLE_ENHANCED_4G_LTE_BOOL} is false), this method will
manabu, shimoda2335b702017-10-06 15:39:36 +0900467 * set the setting to the default value specified by
468 * {@link CarrierConfigManager#KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL}.
Brad Ebinger16417b42017-03-07 13:48:50 -0800469 *
470 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700471 public void setEnhanced4gLteModeSetting(boolean enabled) {
manabu, shimoda2335b702017-10-06 15:39:36 +0900472 // If editable=false, we must keep default advanced 4G mode.
473 if (!getBooleanCarrierConfig(CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL)) {
Malcolm Chen201d2312017-09-28 17:28:45 -0700474 enabled = getBooleanCarrierConfig(
475 CarrierConfigManager.KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL);
manabu, shimoda2335b702017-10-06 15:39:36 +0900476 }
Brad Ebinger16417b42017-03-07 13:48:50 -0800477
Malcolm Chen201d2312017-09-28 17:28:45 -0700478 int prevSetting = SubscriptionManager.getIntegerSubscriptionProperty(
479 getSubId(), SubscriptionManager.ENHANCED_4G_MODE_ENABLED,
480 SUB_PROPERTY_NOT_INITIALIZED, mContext);
Brad Ebinger16417b42017-03-07 13:48:50 -0800481
Malcolm Chen201d2312017-09-28 17:28:45 -0700482 if (prevSetting != (enabled ?
483 ImsConfig.FeatureValueConstants.ON :
484 ImsConfig.FeatureValueConstants.OFF)) {
485 SubscriptionManager.setSubscriptionProperty(getSubId(),
486 SubscriptionManager.ENHANCED_4G_MODE_ENABLED, booleanToPropertyString(enabled));
487 if (isNonTtyOrTtyOnVolteEnabled()) {
488 try {
489 setAdvanced4GMode(enabled);
490 } catch (ImsException ie) {
491 // do nothing
492 }
Brad Ebinger16417b42017-03-07 13:48:50 -0800493 }
494 }
495 }
496
497 /**
Etan Cohen82f78122014-12-15 10:10:14 -0800498 * Indicates whether the call is non-TTY or if TTY - whether TTY on VoLTE is
499 * supported.
Brad Ebinger16417b42017-03-07 13:48:50 -0800500 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700501 * {@link #isNonTtyOrTtyOnVolteEnabled()} instead.
Etan Cohen82f78122014-12-15 10:10:14 -0800502 */
503 public static boolean isNonTtyOrTtyOnVolteEnabled(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700504 ImsManager mgr = ImsManager.getInstance(context,
505 SubscriptionManager.getDefaultVoicePhoneId());
506 if (mgr != null) {
507 return mgr.isNonTtyOrTtyOnVolteEnabled();
508 }
509 loge("isNonTtyOrTtyOnVolteEnabled: ImsManager null, returning default value.");
510 return false;
511 }
512
513 /**
514 * Indicates whether the call is non-TTY or if TTY - whether TTY on VoLTE is
515 * supported on a per slot basis.
516 */
517 public boolean isNonTtyOrTtyOnVolteEnabled() {
518 if (getBooleanCarrierConfig(
fionaxu5803ef02016-03-08 11:48:48 -0800519 CarrierConfigManager.KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL)) {
Etan Cohen82f78122014-12-15 10:10:14 -0800520 return true;
521 }
522
Brad Ebinger479f52c2017-08-28 13:19:22 -0700523 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
Hall Liue511a202017-08-17 15:49:58 -0700524 if (tm == null) {
525 Log.w(TAG, "isNonTtyOrTtyOnVolteEnabled: telecom not available");
526 return true;
527 }
528 return tm.getCurrentTtyMode() == TelecomManager.TTY_MODE_OFF;
Etan Cohen82f78122014-12-15 10:10:14 -0800529 }
530
531 /**
Etan Cohenea2b5832014-10-23 18:50:35 -0700532 * Returns a platform configuration for VoLTE which may override the user setting.
Brad Ebinger16417b42017-03-07 13:48:50 -0800533 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700534 * {@link #isVolteEnabledByPlatform()} instead.
Etan Cohen45b5f312014-08-19 15:55:08 -0700535 */
Etan Cohenea2b5832014-10-23 18:50:35 -0700536 public static boolean isVolteEnabledByPlatform(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700537 ImsManager mgr = ImsManager.getInstance(context,
538 SubscriptionManager.getDefaultVoicePhoneId());
539 if (mgr != null) {
540 return mgr.isVolteEnabledByPlatform();
Etan Cohenaf55a402014-09-04 22:34:41 -0700541 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700542 loge("isVolteEnabledByPlatform: ImsManager null, returning default value.");
543 return false;
Etan Cohenb5388a32014-11-26 11:57:47 -0800544 }
545
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -0700546 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800547 * Returns a platform configuration for VoLTE which may override the user setting on a per Slot
548 * basis.
549 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700550 public boolean isVolteEnabledByPlatform() {
Malcolm Chen45904b52017-10-25 17:05:41 -0700551 // We first read the per slot value. If doesn't exist, we read the general value. If still
552 // doesn't exist, we use the hardcoded default value.
553 if (SystemProperties.getInt(
554 PROPERTY_DBG_VOLTE_AVAIL_OVERRIDE + Integer.toString(mPhoneId),
555 SYSTEM_PROPERTY_NOT_SET) == 1 ||
556 SystemProperties.getInt(PROPERTY_DBG_VOLTE_AVAIL_OVERRIDE,
557 SYSTEM_PROPERTY_NOT_SET) == 1) {
Brad Ebinger16417b42017-03-07 13:48:50 -0800558 return true;
559 }
560
561 return mContext.getResources().getBoolean(
562 com.android.internal.R.bool.config_device_volte_available)
Malcolm Chen201d2312017-09-28 17:28:45 -0700563 && getBooleanCarrierConfig(CarrierConfigManager.KEY_CARRIER_VOLTE_AVAILABLE_BOOL)
Brad Ebinger479f52c2017-08-28 13:19:22 -0700564 && isGbaValid();
Brad Ebinger16417b42017-03-07 13:48:50 -0800565 }
566
567 /**
568 * Indicates whether VoLTE is provisioned on device.
569 *
570 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700571 * {@link #isVolteProvisionedOnDevice()} instead.
Etan Cohenb5388a32014-11-26 11:57:47 -0800572 */
573 public static boolean isVolteProvisionedOnDevice(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700574 ImsManager mgr = ImsManager.getInstance(context,
575 SubscriptionManager.getDefaultVoicePhoneId());
576 if (mgr != null) {
577 return mgr.isVolteProvisionedOnDevice();
Etan Cohenb5388a32014-11-26 11:57:47 -0800578 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700579 loge("isVolteProvisionedOnDevice: ImsManager null, returning default value.");
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -0700580 return true;
581 }
582
583 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800584 * Indicates whether VoLTE is provisioned on this slot.
585 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700586 public boolean isVolteProvisionedOnDevice() {
587 if (getBooleanCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -0800588 CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL)) {
589 return isVolteProvisioned();
590 }
591
592 return true;
593 }
594
595 /**
Meng Wang54fd41a2017-04-12 11:44:47 -0700596 * Indicates whether VoWifi is provisioned on device.
597 *
598 * When CarrierConfig KEY_CARRIER_VOLTE_OVERRIDE_WFC_PROVISIONING_BOOL is true, and VoLTE is not
599 * provisioned on device, this method returns false.
Brad Ebinger16417b42017-03-07 13:48:50 -0800600 *
601 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700602 * {@link #isWfcProvisionedOnDevice()} instead.
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -0700603 */
604 public static boolean isWfcProvisionedOnDevice(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700605 ImsManager mgr = ImsManager.getInstance(context,
606 SubscriptionManager.getDefaultVoicePhoneId());
607 if (mgr != null) {
608 return mgr.isWfcProvisionedOnDevice();
Meng Wang54fd41a2017-04-12 11:44:47 -0700609 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700610 loge("isWfcProvisionedOnDevice: ImsManager null, returning default value.");
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -0700611 return true;
612 }
613
614 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800615 * Indicates whether VoWifi is provisioned on slot.
Meng Wang54fd41a2017-04-12 11:44:47 -0700616 *
617 * When CarrierConfig KEY_CARRIER_VOLTE_OVERRIDE_WFC_PROVISIONING_BOOL is true, and VoLTE is not
618 * provisioned on device, this method returns false.
Brad Ebinger16417b42017-03-07 13:48:50 -0800619 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700620 public boolean isWfcProvisionedOnDevice() {
621 if (getBooleanCarrierConfig(
Meng Wang54fd41a2017-04-12 11:44:47 -0700622 CarrierConfigManager.KEY_CARRIER_VOLTE_OVERRIDE_WFC_PROVISIONING_BOOL)) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700623 if (!isVolteProvisionedOnDevice()) {
Meng Wang54fd41a2017-04-12 11:44:47 -0700624 return false;
625 }
626 }
627
Brad Ebinger479f52c2017-08-28 13:19:22 -0700628 if (getBooleanCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -0800629 CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL)) {
Meng Wang54fd41a2017-04-12 11:44:47 -0700630 return isWfcProvisioned();
Brad Ebinger16417b42017-03-07 13:48:50 -0800631 }
632
633 return true;
634 }
635
636 /**
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -0700637 * Indicates whether VT is provisioned on device
Brad Ebinger16417b42017-03-07 13:48:50 -0800638 *
639 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700640 * {@link #isVtProvisionedOnDevice()} instead.
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -0700641 */
642 public static boolean isVtProvisionedOnDevice(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700643 ImsManager mgr = ImsManager.getInstance(context,
644 SubscriptionManager.getDefaultVoicePhoneId());
645 if (mgr != null) {
646 return mgr.isVtProvisionedOnDevice();
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -0700647 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700648 loge("isVtProvisionedOnDevice: ImsManager null, returning default value.");
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -0700649 return true;
Etan Cohenb651fa52014-10-22 10:51:29 -0700650 }
651
Etan Cohenea2b5832014-10-23 18:50:35 -0700652 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800653 * Indicates whether VT is provisioned on slot.
654 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700655 public boolean isVtProvisionedOnDevice() {
656 if (getBooleanCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -0800657 CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL)) {
658 return isVtProvisioned();
659 }
660
661 return true;
662 }
663
664 /**
Etan Cohenea2b5832014-10-23 18:50:35 -0700665 * Returns a platform configuration for VT which may override the user setting.
666 *
667 * Note: VT presumes that VoLTE is enabled (these are configuration settings
668 * which must be done correctly).
Brad Ebinger16417b42017-03-07 13:48:50 -0800669 *
670 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700671 * {@link #isVtEnabledByPlatform()} instead.
Etan Cohenea2b5832014-10-23 18:50:35 -0700672 */
Etan Cohenb651fa52014-10-22 10:51:29 -0700673 public static boolean isVtEnabledByPlatform(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700674 ImsManager mgr = ImsManager.getInstance(context,
675 SubscriptionManager.getDefaultVoicePhoneId());
676 if (mgr != null) {
677 return mgr.isVtEnabledByPlatform();
Etan Cohenea2b5832014-10-23 18:50:35 -0700678 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700679 loge("isVtEnabledByPlatform: ImsManager null, returning default value.");
680 return false;
Etan Cohen45b5f312014-08-19 15:55:08 -0700681 }
682
Etan Cohena00c9192014-12-23 15:02:29 -0800683 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800684 * Returns a platform configuration for VT which may override the user setting.
685 *
686 * Note: VT presumes that VoLTE is enabled (these are configuration settings
687 * which must be done correctly).
688 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700689 public boolean isVtEnabledByPlatform() {
Malcolm Chen45904b52017-10-25 17:05:41 -0700690 // We first read the per slot value. If doesn't exist, we read the general value. If still
691 // doesn't exist, we use the hardcoded default value.
692 if (SystemProperties.getInt(PROPERTY_DBG_VT_AVAIL_OVERRIDE +
693 Integer.toString(mPhoneId), SYSTEM_PROPERTY_NOT_SET) == 1 ||
694 SystemProperties.getInt(
695 PROPERTY_DBG_VT_AVAIL_OVERRIDE, SYSTEM_PROPERTY_NOT_SET) == 1) {
Brad Ebinger16417b42017-03-07 13:48:50 -0800696 return true;
697 }
698
699 return mContext.getResources().getBoolean(
700 com.android.internal.R.bool.config_device_vt_available) &&
Malcolm Chen201d2312017-09-28 17:28:45 -0700701 getBooleanCarrierConfig(CarrierConfigManager.KEY_CARRIER_VT_AVAILABLE_BOOL) &&
Brad Ebinger479f52c2017-08-28 13:19:22 -0700702 isGbaValid();
Brad Ebinger16417b42017-03-07 13:48:50 -0800703 }
704
705 /**
Etan Cohena7d32e82015-05-04 18:02:09 -0700706 * Returns the user configuration of VT setting
Brad Ebinger16417b42017-03-07 13:48:50 -0800707 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700708 * {@link #isVtEnabledByUser()} instead.
Etan Cohena7d32e82015-05-04 18:02:09 -0700709 */
710 public static boolean isVtEnabledByUser(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700711 ImsManager mgr = ImsManager.getInstance(context,
712 SubscriptionManager.getDefaultVoicePhoneId());
713 if (mgr != null) {
714 return mgr.isVtEnabledByUser();
715 }
716 loge("isVtEnabledByUser: ImsManager null, returning default value.");
717 return false;
Etan Cohena7d32e82015-05-04 18:02:09 -0700718 }
719
720 /**
Malcolm Chen201d2312017-09-28 17:28:45 -0700721 * Returns the user configuration of VT setting per slot. If not set, it
722 * returns true as default value.
Brad Ebinger16417b42017-03-07 13:48:50 -0800723 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700724 public boolean isVtEnabledByUser() {
Malcolm Chen201d2312017-09-28 17:28:45 -0700725 int setting = SubscriptionManager.getIntegerSubscriptionProperty(
726 getSubId(), SubscriptionManager.VT_IMS_ENABLED,
727 SUB_PROPERTY_NOT_INITIALIZED, mContext);
728
729 // If it's never set, by default we return true.
730 return (setting == SUB_PROPERTY_NOT_INITIALIZED || setting == 1);
Brad Ebinger16417b42017-03-07 13:48:50 -0800731 }
732
733 /**
Etan Cohena7d32e82015-05-04 18:02:09 -0700734 * Change persistent VT enabled setting
Brad Ebinger16417b42017-03-07 13:48:50 -0800735 *
Brad Ebinger479f52c2017-08-28 13:19:22 -0700736 * @deprecated Does not support MSIM devices. Please use {@link #setVtSetting(boolean)} instead.
Etan Cohena7d32e82015-05-04 18:02:09 -0700737 */
738 public static void setVtSetting(Context context, boolean enabled) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700739 ImsManager mgr = ImsManager.getInstance(context,
Etan Cohena7d32e82015-05-04 18:02:09 -0700740 SubscriptionManager.getDefaultVoicePhoneId());
Brad Ebinger479f52c2017-08-28 13:19:22 -0700741 if (mgr != null) {
742 mgr.setVtSetting(enabled);
Etan Cohena7d32e82015-05-04 18:02:09 -0700743 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700744 loge("setVtSetting: ImsManager null, can not set value.");
Etan Cohena7d32e82015-05-04 18:02:09 -0700745 }
746
Brad Ebinger16417b42017-03-07 13:48:50 -0800747 /**
748 * Change persistent VT enabled setting for slot.
749 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700750 public void setVtSetting(boolean enabled) {
Brad Ebinger936a7d12018-01-16 09:36:56 -0800751 SubscriptionManager.setSubscriptionProperty(getSubId(), SubscriptionManager.VT_IMS_ENABLED,
Malcolm Chen201d2312017-09-28 17:28:45 -0700752 booleanToPropertyString(enabled));
Brad Ebinger936a7d12018-01-16 09:36:56 -0800753
Brad Ebinger16417b42017-03-07 13:48:50 -0800754 try {
Brad Ebinger936a7d12018-01-16 09:36:56 -0800755 changeMmTelCapability(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO,
756 ImsRegistrationImplBase.REGISTRATION_TECH_LTE, enabled);
Brad Ebinger16417b42017-03-07 13:48:50 -0800757
758 if (enabled) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700759 log("setVtSetting(b) : turnOnIms");
Brad Ebinger16417b42017-03-07 13:48:50 -0800760 turnOnIms();
Brad Ebinger479f52c2017-08-28 13:19:22 -0700761 } else if (isVolteEnabledByPlatform()
762 && (!isVolteEnabledByPlatform()
763 || !isEnhanced4gLteModeSettingEnabledByUser())) {
764 log("setVtSetting(b) : imsServiceAllowTurnOff -> turnOffIms");
Brad Ebinger16417b42017-03-07 13:48:50 -0800765 turnOffIms();
766 }
Brad Ebinger936a7d12018-01-16 09:36:56 -0800767 } catch (ImsException | RemoteException e) {
768 // The ImsService is down. Since the SubscriptionManager already recorded the user's
769 // preference, it will be resent in updateImsServiceConfig when the ImsPhoneCallTracker
770 // reconnects.
Brad Ebinger479f52c2017-08-28 13:19:22 -0700771 loge("setVtSetting(b): ", e);
Brad Ebinger16417b42017-03-07 13:48:50 -0800772 }
773 }
774
775 /**
Meng Wang9352c432016-06-08 14:22:20 -0700776 * Returns whether turning off ims is allowed by platform.
777 * The platform property may override the carrier config.
Brad Ebinger16417b42017-03-07 13:48:50 -0800778 *
779 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700780 * {@link #isTurnOffImsAllowedByPlatform()} instead.
Meng Wang9352c432016-06-08 14:22:20 -0700781 */
782 private static boolean isTurnOffImsAllowedByPlatform(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700783 ImsManager mgr = ImsManager.getInstance(context,
784 SubscriptionManager.getDefaultVoicePhoneId());
785 if (mgr != null) {
786 return mgr.isTurnOffImsAllowedByPlatform();
Meng Wang9352c432016-06-08 14:22:20 -0700787 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700788 loge("isTurnOffImsAllowedByPlatform: ImsManager null, returning default value.");
789 return true;
Meng Wang9352c432016-06-08 14:22:20 -0700790 }
791
Etan Cohena7d32e82015-05-04 18:02:09 -0700792 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800793 * Returns whether turning off ims is allowed by platform.
794 * The platform property may override the carrier config.
795 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700796 private boolean isTurnOffImsAllowedByPlatform() {
Malcolm Chen45904b52017-10-25 17:05:41 -0700797 // We first read the per slot value. If doesn't exist, we read the general value. If still
798 // doesn't exist, we use the hardcoded default value.
799 if (SystemProperties.getInt(PROPERTY_DBG_ALLOW_IMS_OFF_OVERRIDE +
800 Integer.toString(mPhoneId), SYSTEM_PROPERTY_NOT_SET) == 1 ||
801 SystemProperties.getInt(
802 PROPERTY_DBG_ALLOW_IMS_OFF_OVERRIDE, SYSTEM_PROPERTY_NOT_SET) == 1) {
Brad Ebinger16417b42017-03-07 13:48:50 -0800803 return true;
804 }
Malcolm Chen45904b52017-10-25 17:05:41 -0700805
Brad Ebinger479f52c2017-08-28 13:19:22 -0700806 return getBooleanCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -0800807 CarrierConfigManager.KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL);
808 }
809
810 /**
Etan Cohena00c9192014-12-23 15:02:29 -0800811 * Returns the user configuration of WFC setting
Brad Ebinger16417b42017-03-07 13:48:50 -0800812 *
813 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700814 * {@link #isWfcEnabledByUser()} instead.
Etan Cohena00c9192014-12-23 15:02:29 -0800815 */
816 public static boolean isWfcEnabledByUser(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700817 ImsManager mgr = ImsManager.getInstance(context,
818 SubscriptionManager.getDefaultVoicePhoneId());
819 if (mgr != null) {
820 return mgr.isWfcEnabledByUser();
821 }
822 loge("isWfcEnabledByUser: ImsManager null, returning default value.");
823 return true;
Etan Cohena00c9192014-12-23 15:02:29 -0800824 }
825
826 /**
Malcolm Chen201d2312017-09-28 17:28:45 -0700827 * Returns the user configuration of WFC setting for slot. If not set, it
828 * queries CarrierConfig value as default.
Brad Ebinger16417b42017-03-07 13:48:50 -0800829 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700830 public boolean isWfcEnabledByUser() {
Malcolm Chen201d2312017-09-28 17:28:45 -0700831 int setting = SubscriptionManager.getIntegerSubscriptionProperty(
832 getSubId(), SubscriptionManager.WFC_IMS_ENABLED,
833 SUB_PROPERTY_NOT_INITIALIZED, mContext);
834
835 // SUB_PROPERTY_NOT_INITIALIZED indicates it's never set in sub db.
836 if (setting == SUB_PROPERTY_NOT_INITIALIZED) {
837 return getBooleanCarrierConfig(
838 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL);
839 } else {
840 return setting == 1;
841 }
Brad Ebinger16417b42017-03-07 13:48:50 -0800842 }
843
844 /**
845 * Change persistent WFC enabled setting.
846 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700847 * {@link #setWfcSetting} instead.
Etan Cohena00c9192014-12-23 15:02:29 -0800848 */
849 public static void setWfcSetting(Context context, boolean enabled) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700850 ImsManager mgr = ImsManager.getInstance(context,
Etan Cohena00c9192014-12-23 15:02:29 -0800851 SubscriptionManager.getDefaultVoicePhoneId());
Brad Ebinger479f52c2017-08-28 13:19:22 -0700852 if (mgr != null) {
853 mgr.setWfcSetting(enabled);
Etan Cohena00c9192014-12-23 15:02:29 -0800854 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700855 loge("setWfcSetting: ImsManager null, can not set value.");
Etan Cohena00c9192014-12-23 15:02:29 -0800856 }
857
858 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800859 * Change persistent WFC enabled setting for slot.
860 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700861 public void setWfcSetting(boolean enabled) {
Malcolm Chen201d2312017-09-28 17:28:45 -0700862 SubscriptionManager.setSubscriptionProperty(getSubId(),
863 SubscriptionManager.WFC_IMS_ENABLED, booleanToPropertyString(enabled));
Brad Ebinger16417b42017-03-07 13:48:50 -0800864
Brad Ebinger479f52c2017-08-28 13:19:22 -0700865 setWfcNonPersistent(enabled, getWfcMode());
Meng Wang51c09072017-03-27 10:47:45 -0700866 }
867
868 /**
869 * Non-persistently change WFC enabled setting and WFC mode for slot
870 *
871 * @param wfcMode The WFC preference if WFC is enabled
872 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700873 public void setWfcNonPersistent(boolean enabled, int wfcMode) {
Meng Wang51c09072017-03-27 10:47:45 -0700874 // Force IMS to register over LTE when turning off WFC
875 int imsWfcModeFeatureValue =
876 enabled ? wfcMode : ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED;
877
Brad Ebinger16417b42017-03-07 13:48:50 -0800878 try {
Brad Ebinger936a7d12018-01-16 09:36:56 -0800879 changeMmTelCapability(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
880 ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN, enabled);
Brad Ebinger16417b42017-03-07 13:48:50 -0800881
882 if (enabled) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700883 log("setWfcSetting() : turnOnIms");
Brad Ebinger16417b42017-03-07 13:48:50 -0800884 turnOnIms();
Brad Ebinger479f52c2017-08-28 13:19:22 -0700885 } else if (isTurnOffImsAllowedByPlatform()
886 && (!isVolteEnabledByPlatform()
887 || !isEnhanced4gLteModeSettingEnabledByUser())) {
888 log("setWfcSetting() : imsServiceAllowTurnOff -> turnOffIms");
Brad Ebinger16417b42017-03-07 13:48:50 -0800889 turnOffIms();
890 }
891
Brad Ebinger479f52c2017-08-28 13:19:22 -0700892 setWfcModeInternal(imsWfcModeFeatureValue);
Brad Ebinger936a7d12018-01-16 09:36:56 -0800893 } catch (ImsException | RemoteException e) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700894 loge("setWfcSetting(): ", e);
Brad Ebinger16417b42017-03-07 13:48:50 -0800895 }
896 }
897
898 /**
899 * Returns the user configuration of WFC preference setting.
900 *
Malcolm Chen201d2312017-09-28 17:28:45 -0700901 * @deprecated Doesn't support MSIM devices. Use {@link #getWfcMode(boolean roaming)} instead.
Etan Cohena00c9192014-12-23 15:02:29 -0800902 */
903 public static int getWfcMode(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700904 ImsManager mgr = ImsManager.getInstance(context,
905 SubscriptionManager.getDefaultVoicePhoneId());
906 if (mgr != null) {
907 return mgr.getWfcMode();
908 }
909 loge("getWfcMode: ImsManager null, returning default value.");
910 return ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY;
Etan Cohena00c9192014-12-23 15:02:29 -0800911 }
912
913 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800914 * Returns the user configuration of WFC preference setting
Malcolm Chen201d2312017-09-28 17:28:45 -0700915 * @deprecated. Use {@link #getWfcMode(boolean roaming)} instead.
Brad Ebinger16417b42017-03-07 13:48:50 -0800916 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700917 public int getWfcMode() {
Malcolm Chen201d2312017-09-28 17:28:45 -0700918 return getWfcMode(false);
Brad Ebinger16417b42017-03-07 13:48:50 -0800919 }
920
921 /**
922 * Change persistent WFC preference setting.
923 *
Brad Ebinger479f52c2017-08-28 13:19:22 -0700924 * @deprecated Doesn't support MSIM devices. Use {@link #setWfcMode(int)} instead.
Etan Cohena00c9192014-12-23 15:02:29 -0800925 */
926 public static void setWfcMode(Context context, int wfcMode) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700927 ImsManager mgr = ImsManager.getInstance(context,
928 SubscriptionManager.getDefaultVoicePhoneId());
929 if (mgr != null) {
930 mgr.setWfcMode(wfcMode);
931 }
932 loge("setWfcMode: ImsManager null, can not set value.");
Pavel Zhamaitsiak9e6eca22015-03-16 15:30:53 -0700933 }
934
Meng Wang37477012016-09-20 09:59:56 -0700935 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800936 * Change persistent WFC preference setting for slot.
937 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700938 public void setWfcMode(int wfcMode) {
939 if (DBG) log("setWfcMode(i) - setting=" + wfcMode);
Malcolm Chen201d2312017-09-28 17:28:45 -0700940
941 SubscriptionManager.setSubscriptionProperty(getSubId(),
942 SubscriptionManager.WFC_IMS_MODE, Integer.toString(wfcMode));
Brad Ebinger16417b42017-03-07 13:48:50 -0800943
Brad Ebinger479f52c2017-08-28 13:19:22 -0700944 setWfcModeInternal(wfcMode);
Brad Ebinger16417b42017-03-07 13:48:50 -0800945 }
946
947 /**
Suresh Koleti76491082017-04-21 18:39:50 +0530948 * Changes the WFC mode to its default value for Carriers with non-editable WFC settings.
949 */
950 private void updateDefaultWfcMode() {
951 if (DBG) log("updateDefaultWfcMode");
Brad Ebinger479f52c2017-08-28 13:19:22 -0700952 if (!getBooleanCarrierConfig(CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL)) {
953 setWfcMode(getIntCarrierConfig(
Suresh Koleti76491082017-04-21 18:39:50 +0530954 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT));
955 }
956 }
957
958 /**
Meng Wang37477012016-09-20 09:59:56 -0700959 * Returns the user configuration of WFC preference setting
960 *
961 * @param roaming {@code false} for home network setting, {@code true} for roaming setting
Brad Ebinger16417b42017-03-07 13:48:50 -0800962 *
Brad Ebinger479f52c2017-08-28 13:19:22 -0700963 * @deprecated Doesn't support MSIM devices. Use {@link #getWfcMode(boolean)} instead.
Meng Wang37477012016-09-20 09:59:56 -0700964 */
965 public static int getWfcMode(Context context, boolean roaming) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700966 ImsManager mgr = ImsManager.getInstance(context,
967 SubscriptionManager.getDefaultVoicePhoneId());
968 if (mgr != null) {
969 return mgr.getWfcMode(roaming);
Meng Wang37477012016-09-20 09:59:56 -0700970 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700971 loge("getWfcMode: ImsManager null, returning default value.");
972 return ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY;
Meng Wang37477012016-09-20 09:59:56 -0700973 }
974
975 /**
Malcolm Chen201d2312017-09-28 17:28:45 -0700976 * Returns the user configuration of WFC preference setting for slot. If not set, it
977 * queries CarrierConfig value as default.
Brad Ebinger16417b42017-03-07 13:48:50 -0800978 *
979 * @param roaming {@code false} for home network setting, {@code true} for roaming setting
980 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700981 public int getWfcMode(boolean roaming) {
Brad Ebinger16417b42017-03-07 13:48:50 -0800982 int setting = 0;
983 if (!roaming) {
Malcolm Chen201d2312017-09-28 17:28:45 -0700984 setting = SubscriptionManager.getIntegerSubscriptionProperty(
985 getSubId(), SubscriptionManager.WFC_IMS_MODE,
986 SUB_PROPERTY_NOT_INITIALIZED, mContext);
987
988 // SUB_PROPERTY_NOT_INITIALIZED indicates it's never set in sub db.
989 if (setting == SUB_PROPERTY_NOT_INITIALIZED) {
990 setting = getIntCarrierConfig(
991 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT);
992 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700993 if (DBG) log("getWfcMode - setting=" + setting);
Brad Ebinger16417b42017-03-07 13:48:50 -0800994 } else {
Malcolm Chen201d2312017-09-28 17:28:45 -0700995 setting = SubscriptionManager.getIntegerSubscriptionProperty(
996 getSubId(), SubscriptionManager.WFC_IMS_ROAMING_MODE,
997 SUB_PROPERTY_NOT_INITIALIZED, mContext);
998
999 // SUB_PROPERTY_NOT_INITIALIZED indicates it's never set in sub db.
1000 if (setting == SUB_PROPERTY_NOT_INITIALIZED) {
1001 setting = getIntCarrierConfig(
1002 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_MODE_INT);
1003 }
1004
Brad Ebinger479f52c2017-08-28 13:19:22 -07001005 if (DBG) log("getWfcMode (roaming) - setting=" + setting);
Brad Ebinger16417b42017-03-07 13:48:50 -08001006 }
1007 return setting;
1008 }
1009
1010 /**
Meng Wang37477012016-09-20 09:59:56 -07001011 * Change persistent WFC preference setting
1012 *
1013 * @param roaming {@code false} for home network setting, {@code true} for roaming setting
Brad Ebinger16417b42017-03-07 13:48:50 -08001014 *
Brad Ebinger479f52c2017-08-28 13:19:22 -07001015 * @deprecated Doesn't support MSIM devices. Please use {@link #setWfcMode(int, boolean)}
1016 * instead.
Meng Wang37477012016-09-20 09:59:56 -07001017 */
1018 public static void setWfcMode(Context context, int wfcMode, boolean roaming) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001019 ImsManager mgr = ImsManager.getInstance(context,
1020 SubscriptionManager.getDefaultVoicePhoneId());
1021 if (mgr != null) {
1022 mgr.setWfcMode(wfcMode, roaming);
Meng Wang37477012016-09-20 09:59:56 -07001023 }
Brad Ebinger479f52c2017-08-28 13:19:22 -07001024 loge("setWfcMode: ImsManager null, can not set value.");
Meng Wang37477012016-09-20 09:59:56 -07001025 }
1026
Brad Ebinger16417b42017-03-07 13:48:50 -08001027 /**
1028 * Change persistent WFC preference setting
1029 *
1030 * @param roaming {@code false} for home network setting, {@code true} for roaming setting
1031 */
Brad Ebinger479f52c2017-08-28 13:19:22 -07001032 public void setWfcMode(int wfcMode, boolean roaming) {
Brad Ebinger16417b42017-03-07 13:48:50 -08001033 if (!roaming) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001034 if (DBG) log("setWfcMode(i,b) - setting=" + wfcMode);
Malcolm Chen201d2312017-09-28 17:28:45 -07001035 SubscriptionManager.setSubscriptionProperty(getSubId(),
1036 SubscriptionManager.WFC_IMS_MODE, Integer.toString(wfcMode));
Brad Ebinger16417b42017-03-07 13:48:50 -08001037 } else {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001038 if (DBG) log("setWfcMode(i,b) (roaming) - setting=" + wfcMode);
Malcolm Chen201d2312017-09-28 17:28:45 -07001039 SubscriptionManager.setSubscriptionProperty(getSubId(),
1040 SubscriptionManager.WFC_IMS_ROAMING_MODE, Integer.toString(wfcMode));
Brad Ebinger16417b42017-03-07 13:48:50 -08001041 }
1042
Brad Ebinger479f52c2017-08-28 13:19:22 -07001043 TelephonyManager tm = (TelephonyManager)
1044 mContext.getSystemService(Context.TELEPHONY_SERVICE);
1045 if (roaming == tm.isNetworkRoaming(getSubId())) {
1046 setWfcModeInternal(wfcMode);
1047 }
1048 }
1049
1050 private int getSubId() {
Brad Ebinger16417b42017-03-07 13:48:50 -08001051 int[] subIds = SubscriptionManager.getSubId(mPhoneId);
1052 int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1053 if (subIds != null && subIds.length >= 1) {
1054 subId = subIds[0];
1055 }
Brad Ebinger479f52c2017-08-28 13:19:22 -07001056 return subId;
Brad Ebinger16417b42017-03-07 13:48:50 -08001057 }
1058
Pavel Zhamaitsiak9e6eca22015-03-16 15:30:53 -07001059 private static void setWfcModeInternal(Context context, int wfcMode) {
Etan Cohena00c9192014-12-23 15:02:29 -08001060 final ImsManager imsManager = ImsManager.getInstance(context,
1061 SubscriptionManager.getDefaultVoicePhoneId());
1062 if (imsManager != null) {
1063 final int value = wfcMode;
Pavel Zhamaitsiak47aeacf2016-03-30 18:54:55 -07001064 Thread thread = new Thread(new Runnable() {
Etan Cohena00c9192014-12-23 15:02:29 -08001065 public void run() {
1066 try {
Brad Ebinger936a7d12018-01-16 09:36:56 -08001067 imsManager.getConfigInterface().setConfig(
Etan Cohena00c9192014-12-23 15:02:29 -08001068 ImsConfig.ConfigConstants.VOICE_OVER_WIFI_MODE,
1069 value);
1070 } catch (ImsException e) {
1071 // do nothing
1072 }
1073 }
1074 });
Pavel Zhamaitsiak47aeacf2016-03-30 18:54:55 -07001075 thread.start();
Etan Cohena00c9192014-12-23 15:02:29 -08001076 }
1077 }
1078
Brad Ebinger479f52c2017-08-28 13:19:22 -07001079 private void setWfcModeInternal(int wfcMode) {
Brad Ebinger16417b42017-03-07 13:48:50 -08001080 final int value = wfcMode;
1081 Thread thread = new Thread(() -> {
Malcolm Chen201d2312017-09-28 17:28:45 -07001082 try {
Brad Ebinger936a7d12018-01-16 09:36:56 -08001083 getConfigInterface().setConfig(
Malcolm Chen201d2312017-09-28 17:28:45 -07001084 ImsConfig.ConfigConstants.VOICE_OVER_WIFI_MODE, value);
1085 } catch (ImsException e) {
1086 // do nothing
1087 }
Brad Ebinger16417b42017-03-07 13:48:50 -08001088 });
1089 thread.start();
1090 }
1091
Etan Cohena00c9192014-12-23 15:02:29 -08001092 /**
1093 * Returns the user configuration of WFC roaming setting
Brad Ebinger16417b42017-03-07 13:48:50 -08001094 *
1095 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -07001096 * {@link #isWfcRoamingEnabledByUser()} instead.
Etan Cohena00c9192014-12-23 15:02:29 -08001097 */
1098 public static boolean isWfcRoamingEnabledByUser(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001099 ImsManager mgr = ImsManager.getInstance(context,
1100 SubscriptionManager.getDefaultVoicePhoneId());
1101 if (mgr != null) {
1102 return mgr.isWfcRoamingEnabledByUser();
1103 }
1104 loge("isWfcRoamingEnabledByUser: ImsManager null, returning default value.");
1105 return false;
Etan Cohena00c9192014-12-23 15:02:29 -08001106 }
1107
1108 /**
Malcolm Chen201d2312017-09-28 17:28:45 -07001109 * Returns the user configuration of WFC roaming setting for slot. If not set, it
1110 * queries CarrierConfig value as default.
Brad Ebinger16417b42017-03-07 13:48:50 -08001111 */
Brad Ebinger479f52c2017-08-28 13:19:22 -07001112 public boolean isWfcRoamingEnabledByUser() {
Malcolm Chen201d2312017-09-28 17:28:45 -07001113 int setting = SubscriptionManager.getIntegerSubscriptionProperty(
1114 getSubId(), SubscriptionManager.WFC_IMS_ROAMING_ENABLED,
1115 SUB_PROPERTY_NOT_INITIALIZED, mContext);
1116 if (setting == SUB_PROPERTY_NOT_INITIALIZED) {
1117 return getBooleanCarrierConfig(
1118 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_ENABLED_BOOL);
1119 } else {
1120 return (setting == 1);
1121 }
Brad Ebinger16417b42017-03-07 13:48:50 -08001122 }
1123
1124 /**
Etan Cohena00c9192014-12-23 15:02:29 -08001125 * Change persistent WFC roaming enabled setting
1126 */
1127 public static void setWfcRoamingSetting(Context context, boolean enabled) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001128 ImsManager mgr = ImsManager.getInstance(context,
Etan Cohena00c9192014-12-23 15:02:29 -08001129 SubscriptionManager.getDefaultVoicePhoneId());
Brad Ebinger479f52c2017-08-28 13:19:22 -07001130 if (mgr != null) {
1131 mgr.setWfcRoamingSetting(enabled);
Etan Cohena00c9192014-12-23 15:02:29 -08001132 }
Brad Ebinger479f52c2017-08-28 13:19:22 -07001133 loge("setWfcRoamingSetting: ImsManager null, value not set.");
Etan Cohena00c9192014-12-23 15:02:29 -08001134 }
1135
1136 /**
Brad Ebinger16417b42017-03-07 13:48:50 -08001137 * Change persistent WFC roaming enabled setting
1138 */
Brad Ebinger479f52c2017-08-28 13:19:22 -07001139 public void setWfcRoamingSetting(boolean enabled) {
Malcolm Chen201d2312017-09-28 17:28:45 -07001140 SubscriptionManager.setSubscriptionProperty(getSubId(),
1141 SubscriptionManager.WFC_IMS_ROAMING_ENABLED, booleanToPropertyString(enabled)
1142 );
Brad Ebinger16417b42017-03-07 13:48:50 -08001143
1144 setWfcRoamingSettingInternal(enabled);
1145 }
1146
1147 private void setWfcRoamingSettingInternal(boolean enabled) {
1148 final int value = enabled
1149 ? ImsConfig.FeatureValueConstants.ON
1150 : ImsConfig.FeatureValueConstants.OFF;
1151 Thread thread = new Thread(() -> {
Malcolm Chen201d2312017-09-28 17:28:45 -07001152 try {
Brad Ebinger936a7d12018-01-16 09:36:56 -08001153 getConfigInterface().setConfig(
Malcolm Chen201d2312017-09-28 17:28:45 -07001154 ImsConfig.ConfigConstants.VOICE_OVER_WIFI_ROAMING, value);
1155 } catch (ImsException e) {
1156 // do nothing
1157 }
Brad Ebinger16417b42017-03-07 13:48:50 -08001158 });
1159 thread.start();
1160 }
1161
1162 /**
Etan Cohena00c9192014-12-23 15:02:29 -08001163 * Returns a platform configuration for WFC which may override the user
1164 * setting. Note: WFC presumes that VoLTE is enabled (these are
1165 * configuration settings which must be done correctly).
Brad Ebinger16417b42017-03-07 13:48:50 -08001166 *
Brad Ebinger479f52c2017-08-28 13:19:22 -07001167 * @deprecated Doesn't work for MSIM devices. Use {@link #isWfcEnabledByPlatform()}
Brad Ebinger16417b42017-03-07 13:48:50 -08001168 * instead.
Etan Cohena00c9192014-12-23 15:02:29 -08001169 */
1170 public static boolean isWfcEnabledByPlatform(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001171 ImsManager mgr = ImsManager.getInstance(context,
1172 SubscriptionManager.getDefaultVoicePhoneId());
1173 if (mgr != null) {
1174 return mgr.isWfcEnabledByPlatform();
Etan Cohena00c9192014-12-23 15:02:29 -08001175 }
Brad Ebinger479f52c2017-08-28 13:19:22 -07001176 loge("isWfcEnabledByPlatform: ImsManager null, returning default value.");
1177 return false;
Pavel Zhamaitsiak57911d12015-10-20 14:26:34 -07001178 }
1179
1180 /**
Brad Ebinger16417b42017-03-07 13:48:50 -08001181 * Returns a platform configuration for WFC which may override the user
1182 * setting per slot. Note: WFC presumes that VoLTE is enabled (these are
1183 * configuration settings which must be done correctly).
1184 */
Brad Ebinger479f52c2017-08-28 13:19:22 -07001185 public boolean isWfcEnabledByPlatform() {
Malcolm Chen45904b52017-10-25 17:05:41 -07001186 // We first read the per slot value. If doesn't exist, we read the general value. If still
1187 // doesn't exist, we use the hardcoded default value.
1188 if (SystemProperties.getInt(PROPERTY_DBG_WFC_AVAIL_OVERRIDE +
1189 Integer.toString(mPhoneId), SYSTEM_PROPERTY_NOT_SET) == 1 ||
1190 SystemProperties.getInt(
1191 PROPERTY_DBG_WFC_AVAIL_OVERRIDE, SYSTEM_PROPERTY_NOT_SET) == 1) {
Brad Ebinger16417b42017-03-07 13:48:50 -08001192 return true;
1193 }
1194
1195 return mContext.getResources().getBoolean(
1196 com.android.internal.R.bool.config_device_wfc_ims_available) &&
Brad Ebinger479f52c2017-08-28 13:19:22 -07001197 getBooleanCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -08001198 CarrierConfigManager.KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL) &&
Brad Ebinger479f52c2017-08-28 13:19:22 -07001199 isGbaValid();
Etan Cohena00c9192014-12-23 15:02:29 -08001200 }
1201
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001202 /**
Brad Ebinger16417b42017-03-07 13:48:50 -08001203 * If carrier requires that IMS is only available if GBA capable SIM is used,
1204 * then this function checks GBA bit in EF IST.
1205 *
1206 * Format of EF IST is defined in 3GPP TS 31.103 (Section 4.2.7).
1207 */
Brad Ebinger479f52c2017-08-28 13:19:22 -07001208 private boolean isGbaValid() {
1209 if (getBooleanCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -08001210 CarrierConfigManager.KEY_CARRIER_IMS_GBA_REQUIRED_BOOL)) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001211 final TelephonyManager telephonyManager = new TelephonyManager(mContext, getSubId());
Brad Ebinger16417b42017-03-07 13:48:50 -08001212 String efIst = telephonyManager.getIsimIst();
1213 if (efIst == null) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001214 loge("isGbaValid - ISF is NULL");
Brad Ebinger16417b42017-03-07 13:48:50 -08001215 return true;
1216 }
1217 boolean result = efIst != null && efIst.length() > 1 &&
1218 (0x02 & (byte)efIst.charAt(1)) != 0;
Brad Ebinger479f52c2017-08-28 13:19:22 -07001219 if (DBG) log("isGbaValid - GBA capable=" + result + ", ISF=" + efIst);
Brad Ebinger16417b42017-03-07 13:48:50 -08001220 return result;
1221 }
1222 return true;
1223 }
1224
1225 /**
Malcolm Chen45904b52017-10-25 17:05:41 -07001226 * Will return with config value or throw an ImsException if we receive an error from
1227 * ImsConfig for that value.
1228 */
1229 private boolean getProvisionedBool(ImsConfig config, int item) throws ImsException {
1230 int value = config.getProvisionedValue(item);
1231 if (value == ImsConfig.OperationStatusConstants.UNKNOWN) {
1232 throw new ImsException("getProvisionedBool failed with error for item: " + item,
1233 ImsReasonInfo.CODE_LOCAL_INTERNAL_ERROR);
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -07001234 }
Malcolm Chen45904b52017-10-25 17:05:41 -07001235 return config.getProvisionedValue(item) == ImsConfig.FeatureValueConstants.ON;
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -07001236 }
1237
1238 /**
Malcolm Chen45904b52017-10-25 17:05:41 -07001239 * Will return with config value or return false if we receive an error from
1240 * ImsConfig for that value.
Brad Ebingerbe6cb672017-08-25 14:55:00 -07001241 */
Malcolm Chen45904b52017-10-25 17:05:41 -07001242 private boolean getProvisionedBoolNoException(int item) {
1243 try {
1244 ImsConfig config = getConfigInterface();
1245 return getProvisionedBool(config, item);
1246 } catch (ImsException ex) {
1247 return false;
Brad Ebingerbe6cb672017-08-25 14:55:00 -07001248 }
1249 }
1250
1251 /**
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001252 * Sync carrier config and user settings with ImsConfig.
1253 *
1254 * @param context for the manager object
1255 * @param phoneId phone id
1256 * @param force update
Brad Ebinger16417b42017-03-07 13:48:50 -08001257 *
Brad Ebinger479f52c2017-08-28 13:19:22 -07001258 * @deprecated Doesn't support MSIM devices. Use {@link #updateImsServiceConfig(boolean)}
1259 * instead.
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001260 */
1261 public static void updateImsServiceConfig(Context context, int phoneId, boolean force) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001262 ImsManager mgr = ImsManager.getInstance(context, phoneId);
1263 if (mgr != null) {
1264 mgr.updateImsServiceConfig(force);
Pavel Zhamaitsiakfc202992016-03-29 18:07:38 -07001265 }
Brad Ebinger479f52c2017-08-28 13:19:22 -07001266 loge("updateImsServiceConfig: ImsManager null, returning without update.");
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001267 }
1268
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -07001269 /**
Brad Ebinger16417b42017-03-07 13:48:50 -08001270 * Sync carrier config and user settings with ImsConfig.
1271 *
Brad Ebinger16417b42017-03-07 13:48:50 -08001272 * @param force update
1273 */
Brad Ebinger479f52c2017-08-28 13:19:22 -07001274 public void updateImsServiceConfig(boolean force) {
Brad Ebinger16417b42017-03-07 13:48:50 -08001275 if (!force) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001276 TelephonyManager tm = new TelephonyManager(mContext, getSubId());
1277 if (tm.getSimState() != TelephonyManager.SIM_STATE_READY) {
1278 log("updateImsServiceConfig: SIM not ready");
Brad Ebinger16417b42017-03-07 13:48:50 -08001279 // Don't disable IMS if SIM is not ready
1280 return;
1281 }
1282 }
1283
1284 if (!mConfigUpdated || force) {
1285 try {
Brad Ebinger16417b42017-03-07 13:48:50 -08001286 // TODO: Extend ImsConfig API and set all feature values in single function call.
1287
1288 // Note: currently the order of updates is set to produce different order of
Brad Ebinger936a7d12018-01-16 09:36:56 -08001289 // changeEnabledCapabilities() function calls from setAdvanced4GMode(). This is done
1290 // to differentiate this code path from vendor code perspective.
Brad Ebinger16417b42017-03-07 13:48:50 -08001291 boolean isImsUsed = updateVolteFeatureValue();
1292 isImsUsed |= updateWfcFeatureAndProvisionedValues();
1293 isImsUsed |= updateVideoCallFeatureValue();
1294
Brad Ebinger479f52c2017-08-28 13:19:22 -07001295 if (isImsUsed || !isTurnOffImsAllowedByPlatform()) {
Brad Ebinger16417b42017-03-07 13:48:50 -08001296 // Turn on IMS if it is used.
1297 // Also, if turning off is not allowed for current carrier,
1298 // we need to turn IMS on because it might be turned off before
1299 // phone switched to current carrier.
Brad Ebinger479f52c2017-08-28 13:19:22 -07001300 log("updateImsServiceConfig: turnOnIms");
Brad Ebinger16417b42017-03-07 13:48:50 -08001301 turnOnIms();
1302 } else {
1303 // Turn off IMS if it is not used AND turning off is allowed for carrier.
Brad Ebinger479f52c2017-08-28 13:19:22 -07001304 log("updateImsServiceConfig: turnOffIms");
Brad Ebinger16417b42017-03-07 13:48:50 -08001305 turnOffIms();
1306 }
1307
1308 mConfigUpdated = true;
Brad Ebinger936a7d12018-01-16 09:36:56 -08001309 } catch (ImsException | RemoteException e) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001310 loge("updateImsServiceConfig: ", e);
Brad Ebinger16417b42017-03-07 13:48:50 -08001311 mConfigUpdated = false;
1312 }
1313 }
1314 }
1315
1316 /**
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -07001317 * Update VoLTE config
1318 * @return whether feature is On
1319 * @throws ImsException
1320 */
Brad Ebinger936a7d12018-01-16 09:36:56 -08001321 private boolean updateVolteFeatureValue() throws RemoteException {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001322 boolean available = isVolteEnabledByPlatform();
1323 boolean enabled = isEnhanced4gLteModeSettingEnabledByUser();
1324 boolean isNonTty = isNonTtyOrTtyOnVolteEnabled();
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -08001325 boolean isFeatureOn = available && enabled && isNonTty;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001326
1327 log("updateVolteFeatureValue: available = " + available
1328 + ", enabled = " + enabled
1329 + ", nonTTY = " + isNonTty);
1330
Brad Ebinger936a7d12018-01-16 09:36:56 -08001331 changeMmTelCapability(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
1332 ImsRegistrationImplBase.REGISTRATION_TECH_LTE, isFeatureOn);
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -07001333
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -08001334 return isFeatureOn;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001335 }
1336
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -07001337 /**
Jack Yu643ffe42016-07-08 14:25:46 -07001338 * Update video call over LTE config
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -07001339 * @return whether feature is On
1340 * @throws ImsException
1341 */
Brad Ebinger936a7d12018-01-16 09:36:56 -08001342 private boolean updateVideoCallFeatureValue() throws RemoteException {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001343 boolean available = isVtEnabledByPlatform();
1344 boolean enabled = isVtEnabledByUser();
1345 boolean isNonTty = isNonTtyOrTtyOnVolteEnabled();
Amit Mahajan24f7b162016-07-21 16:33:53 -07001346 boolean isDataEnabled = isDataEnabled();
Brad Ebinger479f52c2017-08-28 13:19:22 -07001347 boolean ignoreDataEnabledChanged = getBooleanCarrierConfig(
Jack Yu57781852016-11-16 17:20:38 -08001348 CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS);
Jack Yu643ffe42016-07-08 14:25:46 -07001349
Jack Yu57781852016-11-16 17:20:38 -08001350 boolean isFeatureOn = available && enabled && isNonTty
1351 && (ignoreDataEnabledChanged || isDataEnabled);
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001352
1353 log("updateVideoCallFeatureValue: available = " + available
1354 + ", enabled = " + enabled
Jack Yu643ffe42016-07-08 14:25:46 -07001355 + ", nonTTY = " + isNonTty
Amit Mahajan24f7b162016-07-21 16:33:53 -07001356 + ", data enabled = " + isDataEnabled);
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001357
Brad Ebinger936a7d12018-01-16 09:36:56 -08001358 changeMmTelCapability(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO,
1359 ImsRegistrationImplBase.REGISTRATION_TECH_LTE, isFeatureOn);
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -07001360
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -08001361 return isFeatureOn;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001362 }
1363
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -07001364 /**
1365 * Update WFC config
1366 * @return whether feature is On
1367 * @throws ImsException
1368 */
Brad Ebinger936a7d12018-01-16 09:36:56 -08001369 private boolean updateWfcFeatureAndProvisionedValues() throws RemoteException {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001370 TelephonyManager tm = new TelephonyManager(mContext, getSubId());
1371 boolean isNetworkRoaming = tm.isNetworkRoaming();
1372 boolean available = isWfcEnabledByPlatform();
1373 boolean enabled = isWfcEnabledByUser();
Suresh Koleti76491082017-04-21 18:39:50 +05301374 updateDefaultWfcMode();
Brad Ebinger479f52c2017-08-28 13:19:22 -07001375 int mode = getWfcMode(isNetworkRoaming);
1376 boolean roaming = isWfcRoamingEnabledByUser();
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -08001377 boolean isFeatureOn = available && enabled;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001378
1379 log("updateWfcFeatureAndProvisionedValues: available = " + available
1380 + ", enabled = " + enabled
1381 + ", mode = " + mode
1382 + ", roaming = " + roaming);
1383
Brad Ebinger936a7d12018-01-16 09:36:56 -08001384 changeMmTelCapability(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
1385 ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN, isFeatureOn);
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001386
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -08001387 if (!isFeatureOn) {
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001388 mode = ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED;
1389 roaming = false;
1390 }
1391 setWfcModeInternal(mContext, mode);
Brad Ebinger16417b42017-03-07 13:48:50 -08001392 setWfcRoamingSettingInternal(roaming);
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -07001393
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -08001394 return isFeatureOn;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001395 }
1396
Brad Ebinger16780ff2017-01-26 11:18:21 -08001397 /**
Brad Ebinger479f52c2017-08-28 13:19:22 -07001398 * Do NOT use this directly, instead use {@link #getInstance(Context, int)}.
Brad Ebinger16780ff2017-01-26 11:18:21 -08001399 */
1400 @VisibleForTesting
1401 public ImsManager(Context context, int phoneId) {
Wink Savilleef36ef62014-06-11 08:39:38 -07001402 mContext = context;
Etan Cohenabbd7882014-09-26 22:35:35 -07001403 mPhoneId = phoneId;
Brad Ebinger16780ff2017-01-26 11:18:21 -08001404 mConfigDynamicBind = mContext.getResources().getBoolean(
1405 com.android.internal.R.bool.config_dynamic_bind_ims);
Brad Ebinger16417b42017-03-07 13:48:50 -08001406 mConfigManager = (CarrierConfigManager) context.getSystemService(
1407 Context.CARRIER_CONFIG_SERVICE);
Brad Ebinger16780ff2017-01-26 11:18:21 -08001408 createImsService();
1409 }
1410
1411 /**
Brad Ebinger16780ff2017-01-26 11:18:21 -08001412 * @return Whether or not ImsManager is configured to Dynamically bind or not to support legacy
1413 * devices.
1414 */
1415 public boolean isDynamicBinding() {
1416 return mConfigDynamicBind;
Wink Savilleef36ef62014-06-11 08:39:38 -07001417 }
1418
Etan Cohenf4311122015-02-26 17:47:13 -08001419 /*
Brad Ebingerff097922017-06-19 15:43:08 -07001420 * Returns a flag indicating whether the IMS service is available. If it is not available,
1421 * it will try to connect before reporting failure.
Etan Cohenf4311122015-02-26 17:47:13 -08001422 */
1423 public boolean isServiceAvailable() {
Brad Ebingerff097922017-06-19 15:43:08 -07001424 connectIfServiceIsAvailable();
Brad Ebinger16780ff2017-01-26 11:18:21 -08001425 // mImsServiceProxy will always create an ImsServiceProxy.
Brad Ebinger936a7d12018-01-16 09:36:56 -08001426 return mMmTelFeatureConnection.isBinderAlive();
Etan Cohenf4311122015-02-26 17:47:13 -08001427 }
1428
Suresh Koleticc3139c2017-11-03 18:23:57 +05301429 /*
1430 * Returns a flag indicating whether the IMS service is ready to send requests to lower layers.
1431 */
1432 public boolean isServiceReady() {
1433 connectIfServiceIsAvailable();
Brad Ebinger936a7d12018-01-16 09:36:56 -08001434 return mMmTelFeatureConnection.isBinderReady();
Suresh Koleticc3139c2017-11-03 18:23:57 +05301435 }
1436
Brad Ebingerff097922017-06-19 15:43:08 -07001437 /**
1438 * If the service is available, try to reconnect.
1439 */
1440 public void connectIfServiceIsAvailable() {
Brad Ebinger936a7d12018-01-16 09:36:56 -08001441 if (mMmTelFeatureConnection == null || !mMmTelFeatureConnection.isBinderAlive()) {
Brad Ebingerff097922017-06-19 15:43:08 -07001442 createImsService();
1443 }
1444 }
1445
Brad Ebinger936a7d12018-01-16 09:36:56 -08001446 public void setConfigListener(ImsConfigListener listener) {
Pavel Zhamaitsiakf4b90322016-01-26 14:34:09 -08001447 mImsConfigListener = listener;
1448 }
1449
Brad Ebingerb10b61e2017-04-18 11:45:26 -07001450
1451 /**
1452 * Adds a callback for status changed events if the binder is already available. If it is not,
1453 * this method will throw an ImsException.
1454 */
Brad Ebinger6ddf28e2018-02-21 16:07:23 -08001455 @VisibleForTesting
Brad Ebinger936a7d12018-01-16 09:36:56 -08001456 public void addNotifyStatusChangedCallbackIfAvailable(MmTelFeatureConnection.IFeatureUpdate c)
Brad Ebingerb10b61e2017-04-18 11:45:26 -07001457 throws ImsException {
Brad Ebinger936a7d12018-01-16 09:36:56 -08001458 if (!mMmTelFeatureConnection.isBinderAlive()) {
Brad Ebingerb10b61e2017-04-18 11:45:26 -07001459 throw new ImsException("Binder is not active!",
1460 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1461 }
Brad Ebinger16780ff2017-01-26 11:18:21 -08001462 if (c != null) {
1463 mStatusCallbacks.add(c);
1464 }
1465 }
1466
Brad Ebinger6ddf28e2018-02-21 16:07:23 -08001467 void removeNotifyStatusChangedCallback(MmTelFeatureConnection.IFeatureUpdate c) {
Brad Ebinger0e170c72017-12-14 14:24:02 -08001468 if (c != null) {
1469 mStatusCallbacks.remove(c);
1470 } else {
1471 Log.w(TAG, "removeNotifyStatusChangedCallback: callback is null!");
1472 }
1473 }
1474
Wink Savilleef36ef62014-06-11 08:39:38 -07001475 /**
1476 * Opens the IMS service for making calls and/or receiving generic IMS calls.
Brad Ebinger936a7d12018-01-16 09:36:56 -08001477 * The caller may make subsequent calls through {@link #makeCall}.
Wink Savilleef36ef62014-06-11 08:39:38 -07001478 * The IMS service will register the device to the operator's network with the credentials
1479 * (from ISIM) periodically in order to receive calls from the operator's network.
Brad Ebinger936a7d12018-01-16 09:36:56 -08001480 * When the IMS service receives a new call, it will call
1481 * {@link MmTelFeature.Listener#onIncomingCall}
1482 * The listener contains a call ID extra {@link #getCallId} and it can be used to take a call.
1483 * @param listener A {@link MmTelFeature.Listener}, which is the interface the
1484 * {@link MmTelFeature} uses to notify the framework of updates
1485 * @throws NullPointerException if {@code listener} is null
Wink Savilleef36ef62014-06-11 08:39:38 -07001486 * @throws ImsException if calling the IMS service results in an error
1487 * @see #getCallId
Wink Savilleef36ef62014-06-11 08:39:38 -07001488 */
Brad Ebinger936a7d12018-01-16 09:36:56 -08001489 public void open(MmTelFeature.Listener listener) throws ImsException {
Wink Savilleef36ef62014-06-11 08:39:38 -07001490 checkAndThrowExceptionIfServiceUnavailable();
1491
Wink Savilleef36ef62014-06-11 08:39:38 -07001492 if (listener == null) {
1493 throw new NullPointerException("listener can't be null");
1494 }
1495
Wink Savilleef36ef62014-06-11 08:39:38 -07001496 try {
Brad Ebinger936a7d12018-01-16 09:36:56 -08001497 mMmTelFeatureConnection.openConnection(listener);
Wink Savilleef36ef62014-06-11 08:39:38 -07001498 } catch (RemoteException e) {
Brad Ebinger936a7d12018-01-16 09:36:56 -08001499 throw new ImsException("open()", e, ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
Wink Savilleef36ef62014-06-11 08:39:38 -07001500 }
Wink Savilleef36ef62014-06-11 08:39:38 -07001501 }
1502
1503 /**
Pavel Zhamaitsiakce410172016-04-15 10:55:56 -07001504 * Adds registration listener to the IMS service.
1505 *
1506 * @param serviceClass a service class specified in {@link ImsServiceClass}
1507 * For VoLTE service, it MUST be a {@link ImsServiceClass#MMTEL}.
1508 * @param listener To listen to IMS registration events; It cannot be null
1509 * @throws NullPointerException if {@code listener} is null
1510 * @throws ImsException if calling the IMS service results in an error
Brad Ebinger9a0280c2017-06-01 15:58:48 -07001511 *
1512 * @deprecated Use {@link #addRegistrationListener(ImsConnectionStateListener)} instead.
Pavel Zhamaitsiakce410172016-04-15 10:55:56 -07001513 */
1514 public void addRegistrationListener(int serviceClass, ImsConnectionStateListener listener)
1515 throws ImsException {
Brad Ebinger9a0280c2017-06-01 15:58:48 -07001516 addRegistrationListener(listener);
1517 }
1518
1519 /**
1520 * Adds registration listener to the IMS service.
1521 *
1522 * @param listener To listen to IMS registration events; It cannot be null
1523 * @throws NullPointerException if {@code listener} is null
1524 * @throws ImsException if calling the IMS service results in an error
Brad Ebinger936a7d12018-01-16 09:36:56 -08001525 * @deprecated use {@link #addRegistrationCallback(ImsRegistrationImplBase.Callback)} and
1526 * {@link #addCapabilitiesCallback(ImsFeature.CapabilityCallback)} instead.
Brad Ebinger9a0280c2017-06-01 15:58:48 -07001527 */
Brad Ebinger0e170c72017-12-14 14:24:02 -08001528 public void addRegistrationListener(ImsConnectionStateListener listener) throws ImsException {
Pavel Zhamaitsiakce410172016-04-15 10:55:56 -07001529 if (listener == null) {
1530 throw new NullPointerException("listener can't be null");
1531 }
Brad Ebinger936a7d12018-01-16 09:36:56 -08001532 addRegistrationCallback(listener);
1533 // connect the ImsConnectionStateListener to the new CapabilityCallback.
1534 addCapabilitiesCallback(new ImsFeature.CapabilityCallback() {
1535 @Override
1536 public void onCapabilitiesStatusChanged(ImsFeature.Capabilities config) {
1537 listener.onFeatureCapabilityChangedAdapter(getRegistrationTech(), config);
Brad Ebinger9a0280c2017-06-01 15:58:48 -07001538 }
Brad Ebinger936a7d12018-01-16 09:36:56 -08001539 });
1540 log("Registration Callback registered.");
1541 }
1542
1543 /**
1544 * Adds a callback that gets called when IMS registration has changed.
1545 * @param callback A {@link ImsRegistrationImplBase.Callback} that will notify the caller when
1546 * IMS registration status has changed.
1547 * @throws ImsException when the ImsService connection is not available.
1548 */
1549 public void addRegistrationCallback(ImsRegistrationImplBase.Callback callback)
1550 throws ImsException {
1551 if (callback == null) {
1552 throw new NullPointerException("registration callback can't be null");
Brad Ebinger9a0280c2017-06-01 15:58:48 -07001553 }
Brad Ebinger936a7d12018-01-16 09:36:56 -08001554
1555 checkAndThrowExceptionIfServiceUnavailable();
1556 try {
1557 mMmTelFeatureConnection.addRegistrationCallback(callback);
1558 log("Registration Callback registered.");
1559 // Only record if there isn't a RemoteException.
1560 } catch (RemoteException e) {
1561 throw new ImsException("addRegistrationCallback(IRIB)", e,
1562 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1563 }
1564 }
1565
1566 /**
1567 * Adds a callback that gets called when MMTel capability status has changed, for example when
1568 * Voice over IMS or VT over IMS is not available currently.
1569 * @param callback A {@link ImsFeature.CapabilityCallback} that will notify the caller when
1570 * MMTel capability status has changed.
1571 * @throws ImsException when the ImsService connection is not available.
1572 */
1573 public void addCapabilitiesCallback(ImsFeature.CapabilityCallback callback)
1574 throws ImsException {
1575 if (callback == null) {
1576 throw new NullPointerException("capabilities callback can't be null");
1577 }
1578
1579 checkAndThrowExceptionIfServiceUnavailable();
1580 try {
1581 mMmTelFeatureConnection.addCapabilityCallback(callback);
1582 log("Capability Callback registered.");
1583 // Only record if there isn't a RemoteException.
1584 } catch (RemoteException e) {
1585 throw new ImsException("addCapabilitiesCallback(IF)", e,
1586 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
Pavel Zhamaitsiakce410172016-04-15 10:55:56 -07001587 }
1588 }
1589
1590 /**
Brad Ebinger16780ff2017-01-26 11:18:21 -08001591 * Removes the registration listener from the IMS service.
1592 *
Brad Ebinger16780ff2017-01-26 11:18:21 -08001593 * @param listener Previously registered listener that will be removed. Can not be null.
1594 * @throws NullPointerException if {@code listener} is null
1595 * @throws ImsException if calling the IMS service results in an error
1596 * instead.
1597 */
Brad Ebingerb5f30c72017-02-17 14:54:31 -08001598 public void removeRegistrationListener(ImsConnectionStateListener listener)
Brad Ebinger16780ff2017-01-26 11:18:21 -08001599 throws ImsException {
Brad Ebinger16780ff2017-01-26 11:18:21 -08001600 if (listener == null) {
1601 throw new NullPointerException("listener can't be null");
1602 }
1603
Brad Ebinger936a7d12018-01-16 09:36:56 -08001604 checkAndThrowExceptionIfServiceUnavailable();
1605 try {
1606 mMmTelFeatureConnection.removeRegistrationCallback(listener);
1607 log("Registration Callback/Listener registered.");
1608 // Only record if there isn't a RemoteException.
1609 } catch (RemoteException e) {
1610 throw new ImsException("addRegistrationCallback()", e,
1611 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1612 }
1613 }
1614
1615 public @ImsRegistrationImplBase.ImsRegistrationTech int getRegistrationTech() {
1616 try {
1617 return mMmTelFeatureConnection.getRegistrationTech();
1618 } catch (RemoteException e) {
1619 Log.w(TAG, "getRegistrationTech: no connection to ImsService.");
1620 return ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
Brad Ebinger16780ff2017-01-26 11:18:21 -08001621 }
1622 }
1623
1624 /**
Brad Ebinger936a7d12018-01-16 09:36:56 -08001625 * Closes the connection and removes all active callbacks.
Wink Savilleef36ef62014-06-11 08:39:38 -07001626 * All the resources that were allocated to the service are also released.
Wink Savilleef36ef62014-06-11 08:39:38 -07001627 */
Brad Ebinger936a7d12018-01-16 09:36:56 -08001628 public void close() {
1629 if (mMmTelFeatureConnection != null) {
1630 mMmTelFeatureConnection.closeConnection();
Wink Savilleef36ef62014-06-11 08:39:38 -07001631 }
Brad Ebinger936a7d12018-01-16 09:36:56 -08001632 mUt = null;
1633 mConfig = null;
1634 mEcbm = null;
1635 mMultiEndpoint = null;
Wink Savilleef36ef62014-06-11 08:39:38 -07001636 }
1637
1638 /**
1639 * Gets the configuration interface to provision / withdraw the supplementary service settings.
1640 *
Wink Savilleef36ef62014-06-11 08:39:38 -07001641 * @return the Ut interface instance
1642 * @throws ImsException if getting the Ut interface results in an error
1643 */
Brad Ebinger936a7d12018-01-16 09:36:56 -08001644 public ImsUtInterface getSupplementaryServiceConfiguration() throws ImsException {
Brad Ebinger16780ff2017-01-26 11:18:21 -08001645 // FIXME: manage the multiple Ut interfaces based on the session id
Brad Ebinger138b4a62017-06-20 16:29:50 -07001646 if (mUt != null && mUt.isBinderAlive()) {
1647 return mUt;
Wink Savilleef36ef62014-06-11 08:39:38 -07001648 }
1649
Brad Ebinger138b4a62017-06-20 16:29:50 -07001650 checkAndThrowExceptionIfServiceUnavailable();
1651 try {
Brad Ebinger936a7d12018-01-16 09:36:56 -08001652 IImsUt iUt = mMmTelFeatureConnection.getUtInterface();
Brad Ebinger138b4a62017-06-20 16:29:50 -07001653
1654 if (iUt == null) {
1655 throw new ImsException("getSupplementaryServiceConfiguration()",
1656 ImsReasonInfo.CODE_UT_NOT_SUPPORTED);
1657 }
1658
1659 mUt = new ImsUt(iUt);
1660 } catch (RemoteException e) {
1661 throw new ImsException("getSupplementaryServiceConfiguration()", e,
1662 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1663 }
Wink Savilleef36ef62014-06-11 08:39:38 -07001664 return mUt;
1665 }
1666
1667 /**
Wink Savilleef36ef62014-06-11 08:39:38 -07001668 * Creates a {@link ImsCallProfile} from the service capabilities & IMS registration state.
1669 *
Wink Savilleef36ef62014-06-11 08:39:38 -07001670 * @param serviceType a service type that is specified in {@link ImsCallProfile}
1671 * {@link ImsCallProfile#SERVICE_TYPE_NONE}
1672 * {@link ImsCallProfile#SERVICE_TYPE_NORMAL}
1673 * {@link ImsCallProfile#SERVICE_TYPE_EMERGENCY}
1674 * @param callType a call type that is specified in {@link ImsCallProfile}
1675 * {@link ImsCallProfile#CALL_TYPE_VOICE}
1676 * {@link ImsCallProfile#CALL_TYPE_VT}
1677 * {@link ImsCallProfile#CALL_TYPE_VT_TX}
1678 * {@link ImsCallProfile#CALL_TYPE_VT_RX}
1679 * {@link ImsCallProfile#CALL_TYPE_VT_NODIR}
1680 * {@link ImsCallProfile#CALL_TYPE_VS}
1681 * {@link ImsCallProfile#CALL_TYPE_VS_TX}
1682 * {@link ImsCallProfile#CALL_TYPE_VS_RX}
1683 * @return a {@link ImsCallProfile} object
1684 * @throws ImsException if calling the IMS service results in an error
1685 */
Brad Ebinger936a7d12018-01-16 09:36:56 -08001686 public ImsCallProfile createCallProfile(int serviceType, int callType) throws ImsException {
Wink Savilleef36ef62014-06-11 08:39:38 -07001687 checkAndThrowExceptionIfServiceUnavailable();
1688
1689 try {
Brad Ebinger936a7d12018-01-16 09:36:56 -08001690 return mMmTelFeatureConnection.createCallProfile(serviceType, callType);
Wink Savilleef36ef62014-06-11 08:39:38 -07001691 } catch (RemoteException e) {
1692 throw new ImsException("createCallProfile()", e,
1693 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1694 }
1695 }
1696
1697 /**
1698 * Creates a {@link ImsCall} to make a call.
1699 *
Wink Savilleef36ef62014-06-11 08:39:38 -07001700 * @param profile a call profile to make the call
1701 * (it contains service type, call type, media information, etc.)
Brad Ebinger936a7d12018-01-16 09:36:56 -08001702 * @param callees participants to invite the conference call
Wink Savilleef36ef62014-06-11 08:39:38 -07001703 * @param listener listen to the call events from {@link ImsCall}
1704 * @return a {@link ImsCall} object
1705 * @throws ImsException if calling the IMS service results in an error
1706 */
Brad Ebinger936a7d12018-01-16 09:36:56 -08001707 public ImsCall makeCall(ImsCallProfile profile, String[] callees,
Wink Savilleef36ef62014-06-11 08:39:38 -07001708 ImsCall.Listener listener) throws ImsException {
1709 if (DBG) {
Brad Ebinger936a7d12018-01-16 09:36:56 -08001710 log("makeCall :: profile=" + profile);
Wink Savilleef36ef62014-06-11 08:39:38 -07001711 }
1712
1713 checkAndThrowExceptionIfServiceUnavailable();
1714
1715 ImsCall call = new ImsCall(mContext, profile);
1716
1717 call.setListener(listener);
Brad Ebinger936a7d12018-01-16 09:36:56 -08001718 ImsCallSession session = createCallSession(profile);
Wink Savilleef36ef62014-06-11 08:39:38 -07001719
1720 if ((callees != null) && (callees.length == 1)) {
1721 call.start(session, callees[0]);
1722 } else {
1723 call.start(session, callees);
1724 }
1725
1726 return call;
1727 }
1728
1729 /**
1730 * Creates a {@link ImsCall} to take an incoming call.
1731 *
Brad Ebinger16780ff2017-01-26 11:18:21 -08001732 * @param sessionId a session id which is obtained from {@link ImsManager#open}
Brad Ebinger936a7d12018-01-16 09:36:56 -08001733 * @param incomingCallExtras the incoming call broadcast intent
Wink Savilleef36ef62014-06-11 08:39:38 -07001734 * @param listener to listen to the call events from {@link ImsCall}
1735 * @return a {@link ImsCall} object
1736 * @throws ImsException if calling the IMS service results in an error
1737 */
Brad Ebinger936a7d12018-01-16 09:36:56 -08001738 public ImsCall takeCall(IImsCallSession session, Bundle incomingCallExtras,
Wink Savilleef36ef62014-06-11 08:39:38 -07001739 ImsCall.Listener listener) throws ImsException {
1740 if (DBG) {
Brad Ebinger936a7d12018-01-16 09:36:56 -08001741 log("takeCall :: incomingCall=" + incomingCallExtras);
Wink Savilleef36ef62014-06-11 08:39:38 -07001742 }
1743
1744 checkAndThrowExceptionIfServiceUnavailable();
1745
Brad Ebinger936a7d12018-01-16 09:36:56 -08001746 if (incomingCallExtras == null) {
Wink Savilleef36ef62014-06-11 08:39:38 -07001747 throw new ImsException("Can't retrieve session with null intent",
1748 ImsReasonInfo.CODE_LOCAL_ILLEGAL_ARGUMENT);
1749 }
1750
Brad Ebinger936a7d12018-01-16 09:36:56 -08001751 String callId = getCallId(incomingCallExtras);
Wink Savilleef36ef62014-06-11 08:39:38 -07001752
1753 if (callId == null) {
1754 throw new ImsException("Call ID missing in the incoming call intent",
1755 ImsReasonInfo.CODE_LOCAL_ILLEGAL_ARGUMENT);
1756 }
1757
1758 try {
Wink Savilleef36ef62014-06-11 08:39:38 -07001759 if (session == null) {
1760 throw new ImsException("No pending session for the call",
1761 ImsReasonInfo.CODE_LOCAL_NO_PENDING_CALL);
1762 }
1763
1764 ImsCall call = new ImsCall(mContext, session.getCallProfile());
1765
1766 call.attachSession(new ImsCallSession(session));
1767 call.setListener(listener);
1768
1769 return call;
1770 } catch (Throwable t) {
1771 throw new ImsException("takeCall()", t, ImsReasonInfo.CODE_UNSPECIFIED);
1772 }
1773 }
1774
1775 /**
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -05001776 * Gets the config interface to get/set service/capability parameters.
1777 *
1778 * @return the ImsConfig instance.
1779 * @throws ImsException if getting the setting interface results in an error.
1780 */
1781 public ImsConfig getConfigInterface() throws ImsException {
Brad Ebinger138b4a62017-06-20 16:29:50 -07001782 if (mConfig != null && mConfig.isBinderAlive()) {
1783 return mConfig;
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -05001784 }
Brad Ebinger138b4a62017-06-20 16:29:50 -07001785
1786 checkAndThrowExceptionIfServiceUnavailable();
1787 try {
Brad Ebinger936a7d12018-01-16 09:36:56 -08001788 IImsConfig config = mMmTelFeatureConnection.getConfigInterface();
Brad Ebinger138b4a62017-06-20 16:29:50 -07001789 if (config == null) {
1790 throw new ImsException("getConfigInterface()",
1791 ImsReasonInfo.CODE_LOCAL_SERVICE_UNAVAILABLE);
1792 }
1793 mConfig = new ImsConfig(config, mContext);
1794 } catch (RemoteException e) {
1795 throw new ImsException("getConfigInterface()", e,
1796 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1797 }
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -05001798 return mConfig;
1799 }
1800
Brad Ebinger936a7d12018-01-16 09:36:56 -08001801 public void changeMmTelCapability(
1802 @MmTelFeature.MmTelCapabilities.MmTelCapability int capability,
1803 @ImsRegistrationImplBase.ImsRegistrationTech int radioTech,
1804 boolean isEnabled) throws RemoteException {
1805 CapabilityChangeRequest request = new CapabilityChangeRequest();
1806 if (isEnabled) {
1807 request.addCapabilitiesToEnableForTech(capability, radioTech);
1808 } else {
1809 request.addCapabilitiesToDisableForTech(capability, radioTech);
1810 }
1811 mMmTelFeatureConnection.changeEnabledCapabilities(request, null);
1812 if (mImsConfigListener != null) {
1813 mImsConfigListener.onSetFeatureResponse(capability,
1814 mMmTelFeatureConnection.getRegistrationTech(),
1815 isEnabled ? ImsConfig.FeatureValueConstants.ON
1816 : ImsConfig.FeatureValueConstants.OFF, -1);
1817 }
1818 }
1819
Hall Liu27fc8422018-01-22 19:15:05 -08001820 public void setRttEnabled(boolean enabled) {
1821 try {
1822 setAdvanced4GMode(enabled || isEnhanced4gLteModeSettingEnabledByUser());
1823 final int value = enabled ? ImsConfig.FeatureValueConstants.ON :
1824 ImsConfig.FeatureValueConstants.OFF;
1825 Thread thread = new Thread(() -> {
1826 try {
1827 Log.i(ImsManager.class.getSimpleName(), "Setting RTT enabled to " + enabled);
1828 getConfigInterface().setProvisionedValue(
1829 ImsConfig.ConfigConstants.RTT_SETTING_ENABLED, value);
1830 } catch (ImsException e) {
1831 Log.e(ImsManager.class.getSimpleName(), "Unable to set RTT enabled to "
1832 + enabled + ": " + e);
1833 }
1834 });
1835 thread.start();
1836 } catch (ImsException e) {
1837 Log.e(ImsManager.class.getSimpleName(), "Unable to set RTT enabled to " + enabled
1838 + ": " + e);
1839 }
1840 }
1841
Hall Liue511a202017-08-17 15:49:58 -07001842 /**
1843 * Set the TTY mode. This is the actual tty mode (varies depending on peripheral status)
1844 */
1845 public void setTtyMode(int ttyMode) throws ImsException {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001846 if (!getBooleanCarrierConfig(
Hall Liue511a202017-08-17 15:49:58 -07001847 CarrierConfigManager.KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL)) {
1848 setAdvanced4GMode((ttyMode == TelecomManager.TTY_MODE_OFF) &&
Brad Ebinger479f52c2017-08-28 13:19:22 -07001849 isEnhanced4gLteModeSettingEnabledByUser());
Hall Liue511a202017-08-17 15:49:58 -07001850 }
1851 }
1852
1853 /**
1854 * Sets the UI TTY mode. This is the preferred TTY mode that the user sets in the call
1855 * settings screen.
1856 */
Brad Ebingerb5f30c72017-02-17 14:54:31 -08001857 public void setUiTTYMode(Context context, int uiTtyMode, Message onComplete)
Shriram Ganeshc403b7b2014-08-14 14:18:57 +05301858 throws ImsException {
1859
Etan Cohen82f78122014-12-15 10:10:14 -08001860 checkAndThrowExceptionIfServiceUnavailable();
Shriram Ganeshc403b7b2014-08-14 14:18:57 +05301861
Etan Cohen82f78122014-12-15 10:10:14 -08001862 try {
Brad Ebinger936a7d12018-01-16 09:36:56 -08001863 mMmTelFeatureConnection.setUiTTYMode(uiTtyMode, onComplete);
Etan Cohen82f78122014-12-15 10:10:14 -08001864 } catch (RemoteException e) {
1865 throw new ImsException("setTTYMode()", e,
1866 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1867 }
Shriram Ganeshc403b7b2014-08-14 14:18:57 +05301868 }
1869
Naveen Kalla525c3a22017-02-06 14:46:42 -08001870 private ImsReasonInfo makeACopy(ImsReasonInfo imsReasonInfo) {
1871 Parcel p = Parcel.obtain();
1872 imsReasonInfo.writeToParcel(p, 0);
1873 p.setDataPosition(0);
1874 ImsReasonInfo clonedReasonInfo = ImsReasonInfo.CREATOR.createFromParcel(p);
1875 p.recycle();
1876 return clonedReasonInfo;
1877 }
1878
1879 /**
1880 * Get Recent IMS Disconnect Reasons.
1881 *
1882 * @return ArrayList of ImsReasonInfo objects. MAX size of the arraylist
1883 * is MAX_RECENT_DISCONNECT_REASONS. The objects are in the
1884 * chronological order.
1885 */
1886 public ArrayList<ImsReasonInfo> getRecentImsDisconnectReasons() {
1887 ArrayList<ImsReasonInfo> disconnectReasons = new ArrayList<>();
1888
1889 for (ImsReasonInfo reason : mRecentDisconnectReasons) {
1890 disconnectReasons.add(makeACopy(reason));
1891 }
1892 return disconnectReasons;
1893 }
Brad Ebinger16417b42017-03-07 13:48:50 -08001894
Brad Ebinger936a7d12018-01-16 09:36:56 -08001895 public int getImsServiceState() throws ImsException {
1896 return mMmTelFeatureConnection.getFeatureState();
Brad Ebinger16780ff2017-01-26 11:18:21 -08001897 }
Naveen Kalla525c3a22017-02-06 14:46:42 -08001898
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -05001899 /**
Junda Liue7663c02015-06-23 11:16:26 -07001900 * Get the boolean config from carrier config manager.
1901 *
Brad Ebinger16417b42017-03-07 13:48:50 -08001902 * @param key config key defined in CarrierConfigManager
1903 * @return boolean value of corresponding key.
1904 */
Brad Ebinger479f52c2017-08-28 13:19:22 -07001905 private boolean getBooleanCarrierConfig(String key) {
Brad Ebinger16417b42017-03-07 13:48:50 -08001906 int[] subIds = SubscriptionManager.getSubId(mPhoneId);
1907 int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1908 if (subIds != null && subIds.length >= 1) {
1909 subId = subIds[0];
1910 }
1911 PersistableBundle b = null;
1912 if (mConfigManager != null) {
1913 // If an invalid subId is used, this bundle will contain default values.
1914 b = mConfigManager.getConfigForSubId(subId);
1915 }
1916 if (b != null) {
1917 return b.getBoolean(key);
1918 } else {
1919 // Return static default defined in CarrierConfigManager.
1920 return CarrierConfigManager.getDefaultConfig().getBoolean(key);
1921 }
1922 }
1923
1924 /**
fionaxu5803ef02016-03-08 11:48:48 -08001925 * Get the int config from carrier config manager.
1926 *
Brad Ebinger16417b42017-03-07 13:48:50 -08001927 * @param key config key defined in CarrierConfigManager
1928 * @return integer value of corresponding key.
1929 */
Brad Ebinger479f52c2017-08-28 13:19:22 -07001930 private int getIntCarrierConfig(String key) {
Brad Ebinger16417b42017-03-07 13:48:50 -08001931 int[] subIds = SubscriptionManager.getSubId(mPhoneId);
1932 int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1933 if (subIds != null && subIds.length >= 1) {
1934 subId = subIds[0];
1935 }
1936 PersistableBundle b = null;
1937 if (mConfigManager != null) {
1938 // If an invalid subId is used, this bundle will contain default values.
1939 b = mConfigManager.getConfigForSubId(subId);
1940 }
1941 if (b != null) {
1942 return b.getInt(key);
1943 } else {
1944 // Return static default defined in CarrierConfigManager.
1945 return CarrierConfigManager.getDefaultConfig().getInt(key);
1946 }
1947 }
1948
1949 /**
Wink Savilleef36ef62014-06-11 08:39:38 -07001950 * Gets the call ID from the specified incoming call broadcast intent.
1951 *
Brad Ebinger936a7d12018-01-16 09:36:56 -08001952 * @param incomingCallExtras the incoming call broadcast intent
Wink Savilleef36ef62014-06-11 08:39:38 -07001953 * @return the call ID or null if the intent does not contain it
1954 */
Brad Ebinger936a7d12018-01-16 09:36:56 -08001955 private static String getCallId(Bundle incomingCallExtras) {
1956 if (incomingCallExtras == null) {
Wink Savilleef36ef62014-06-11 08:39:38 -07001957 return null;
1958 }
1959
Brad Ebinger936a7d12018-01-16 09:36:56 -08001960 return incomingCallExtras.getString(EXTRA_CALL_ID);
Wink Savilleef36ef62014-06-11 08:39:38 -07001961 }
1962
1963 /**
Brad Ebingerb10b61e2017-04-18 11:45:26 -07001964 * Checks to see if the ImsService Binder is connected. If it is not, we try to create the
1965 * connection again.
Wink Savilleef36ef62014-06-11 08:39:38 -07001966 */
1967 private void checkAndThrowExceptionIfServiceUnavailable()
1968 throws ImsException {
Brad Ebinger936a7d12018-01-16 09:36:56 -08001969 if (mMmTelFeatureConnection == null || !mMmTelFeatureConnection.isBinderAlive()) {
Brad Ebinger16780ff2017-01-26 11:18:21 -08001970 createImsService();
Wink Savilleef36ef62014-06-11 08:39:38 -07001971
Brad Ebinger936a7d12018-01-16 09:36:56 -08001972 if (mMmTelFeatureConnection == null) {
Wink Savilleef36ef62014-06-11 08:39:38 -07001973 throw new ImsException("Service is unavailable",
1974 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1975 }
1976 }
1977 }
1978
Brad Ebinger16780ff2017-01-26 11:18:21 -08001979 /**
1980 * Binds the IMS service to make/receive the call. Supports two methods of exposing an
1981 * ImsService:
1982 * 1) com.android.ims.ImsService implementation in ServiceManager (deprecated).
1983 * 2) android.telephony.ims.ImsService implementation through ImsResolver.
1984 */
1985 private void createImsService() {
Brad Ebinger936a7d12018-01-16 09:36:56 -08001986 Rlog.i(TAG, "Creating ImsService");
1987 mMmTelFeatureConnection = MmTelFeatureConnection.create(mContext, mPhoneId);
1988
Brad Ebinger0e170c72017-12-14 14:24:02 -08001989 // Forwarding interface to tell mStatusCallbacks that the Proxy is unavailable.
Brad Ebinger936a7d12018-01-16 09:36:56 -08001990 mMmTelFeatureConnection.setStatusCallback(new MmTelFeatureConnection.IFeatureUpdate() {
Brad Ebinger0e170c72017-12-14 14:24:02 -08001991 @Override
1992 public void notifyStateChanged() {
Brad Ebinger936a7d12018-01-16 09:36:56 -08001993 mStatusCallbacks.forEach(MmTelFeatureConnection.IFeatureUpdate::notifyStateChanged);
Brad Ebinger0e170c72017-12-14 14:24:02 -08001994 }
1995
1996 @Override
1997 public void notifyUnavailable() {
Brad Ebinger936a7d12018-01-16 09:36:56 -08001998 mStatusCallbacks.forEach(MmTelFeatureConnection.IFeatureUpdate::notifyUnavailable);
Brad Ebinger0e170c72017-12-14 14:24:02 -08001999 }
2000 });
Etan Cohend7727462014-07-12 14:54:10 -07002001 }
2002
Wink Savilleef36ef62014-06-11 08:39:38 -07002003 /**
2004 * Creates a {@link ImsCallSession} with the specified call profile.
2005 * Use other methods, if applicable, instead of interacting with
2006 * {@link ImsCallSession} directly.
2007 *
Wink Savilleef36ef62014-06-11 08:39:38 -07002008 * @param profile a call profile to make the call
2009 */
Brad Ebinger936a7d12018-01-16 09:36:56 -08002010 private ImsCallSession createCallSession(ImsCallProfile profile) throws ImsException {
Wink Savilleef36ef62014-06-11 08:39:38 -07002011 try {
Brad Ebingerb10b61e2017-04-18 11:45:26 -07002012 // Throws an exception if the ImsService Feature is not ready to accept commands.
Brad Ebinger936a7d12018-01-16 09:36:56 -08002013 return new ImsCallSession(mMmTelFeatureConnection.createCallSession(profile));
Wink Savilleef36ef62014-06-11 08:39:38 -07002014 } catch (RemoteException e) {
Brad Ebingerb10b61e2017-04-18 11:45:26 -07002015 Rlog.w(TAG, "CreateCallSession: Error, remote exception: " + e.getMessage());
2016 throw new ImsException("createCallSession()", e,
2017 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
2018
Wink Savilleef36ef62014-06-11 08:39:38 -07002019 }
2020 }
2021
Etan Cohena00c9192014-12-23 15:02:29 -08002022 private static void log(String s) {
Wink Savilleef36ef62014-06-11 08:39:38 -07002023 Rlog.d(TAG, s);
2024 }
2025
Etan Cohena00c9192014-12-23 15:02:29 -08002026 private static void loge(String s) {
Wink Savilleef36ef62014-06-11 08:39:38 -07002027 Rlog.e(TAG, s);
2028 }
2029
Etan Cohena00c9192014-12-23 15:02:29 -08002030 private static void loge(String s, Throwable t) {
Wink Savilleef36ef62014-06-11 08:39:38 -07002031 Rlog.e(TAG, s, t);
2032 }
2033
2034 /**
ram7da5a112014-07-16 20:59:27 +05302035 * Used for turning on IMS.if its off already
2036 */
Etan Cohen82f78122014-12-15 10:10:14 -08002037 private void turnOnIms() throws ImsException {
Brad Ebinger936a7d12018-01-16 09:36:56 -08002038 TelephonyManager tm = (TelephonyManager)
2039 mContext.getSystemService(Context.TELEPHONY_SERVICE);
2040 tm.enableIms(mPhoneId);
ram7da5a112014-07-16 20:59:27 +05302041 }
2042
Omkar Kolangade75f3ca32014-10-24 11:10:52 -07002043 private boolean isImsTurnOffAllowed() {
Brad Ebinger479f52c2017-08-28 13:19:22 -07002044 return isTurnOffImsAllowedByPlatform()
2045 && (!isWfcEnabledByPlatform()
2046 || !isWfcEnabledByUser());
Omkar Kolangade75f3ca32014-10-24 11:10:52 -07002047 }
2048
Amit Mahajan9cba36d2016-08-11 10:17:23 -07002049 private void setLteFeatureValues(boolean turnOn) {
2050 log("setLteFeatureValues: " + turnOn);
Brad Ebinger936a7d12018-01-16 09:36:56 -08002051 CapabilityChangeRequest request = new CapabilityChangeRequest();
2052 if (turnOn) {
2053 request.addCapabilitiesToEnableForTech(
2054 MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
2055 ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
2056 } else {
2057 request.addCapabilitiesToDisableForTech(
2058 MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
2059 ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
2060 }
Pavel Zhamaitsiakff29b9d2016-04-15 12:16:57 -07002061
Brad Ebinger936a7d12018-01-16 09:36:56 -08002062 if (isVolteEnabledByPlatform()) {
2063 boolean ignoreDataEnabledChanged = getBooleanCarrierConfig(
2064 CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS);
2065 boolean enableViLte = turnOn && isVtEnabledByUser() &&
2066 (ignoreDataEnabledChanged || isDataEnabled());
2067 if (enableViLte) {
2068 request.addCapabilitiesToEnableForTech(
2069 MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO,
2070 ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
2071 } else {
2072 request.addCapabilitiesToDisableForTech(
2073 MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO,
2074 ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
Etan Cohenb651fa52014-10-22 10:51:29 -07002075 }
Brad Ebinger936a7d12018-01-16 09:36:56 -08002076 }
2077 try {
2078 mMmTelFeatureConnection.changeEnabledCapabilities(request, null);
2079 } catch (RemoteException e) {
2080 Log.e(TAG, "setLteFeatureValues: Exception: " + e.getMessage());
Etan Cohencfc784d2014-08-07 18:40:31 -07002081 }
Amit Mahajan9cba36d2016-08-11 10:17:23 -07002082 }
2083
2084 private void setAdvanced4GMode(boolean turnOn) throws ImsException {
2085 checkAndThrowExceptionIfServiceUnavailable();
2086
2087 // if turnOn: first set feature values then call turnOnIms()
2088 // if turnOff: only set feature values if IMS turn off is not allowed. If turn off is
2089 // allowed, first call turnOffIms() then set feature values
Etan Cohencfc784d2014-08-07 18:40:31 -07002090 if (turnOn) {
Amit Mahajan9cba36d2016-08-11 10:17:23 -07002091 setLteFeatureValues(turnOn);
2092 log("setAdvanced4GMode: turnOnIms");
Etan Cohencfc784d2014-08-07 18:40:31 -07002093 turnOnIms();
Amit Mahajan9cba36d2016-08-11 10:17:23 -07002094 } else {
2095 if (isImsTurnOffAllowed()) {
2096 log("setAdvanced4GMode: turnOffIms");
2097 turnOffIms();
2098 }
2099 setLteFeatureValues(turnOn);
Etan Cohencfc784d2014-08-07 18:40:31 -07002100 }
2101 }
2102
ram7da5a112014-07-16 20:59:27 +05302103 /**
2104 * Used for turning off IMS completely in order to make the device CSFB'ed.
2105 * Once turned off, all calls will be over CS.
2106 */
Etan Cohen82f78122014-12-15 10:10:14 -08002107 private void turnOffIms() throws ImsException {
Brad Ebinger936a7d12018-01-16 09:36:56 -08002108 TelephonyManager tm = (TelephonyManager)
2109 mContext.getSystemService(Context.TELEPHONY_SERVICE);
2110 tm.disableIms(mPhoneId);
ram7da5a112014-07-16 20:59:27 +05302111 }
2112
Naveen Kalla525c3a22017-02-06 14:46:42 -08002113 private void addToRecentDisconnectReasons(ImsReasonInfo reason) {
2114 if (reason == null) return;
2115 while (mRecentDisconnectReasons.size() >= MAX_RECENT_DISCONNECT_REASONS) {
2116 mRecentDisconnectReasons.removeFirst();
2117 }
2118 mRecentDisconnectReasons.addLast(reason);
2119 }
2120
ram7da5a112014-07-16 20:59:27 +05302121 /**
Wink Savilleef36ef62014-06-11 08:39:38 -07002122 * Death recipient class for monitoring IMS service.
2123 */
2124 private class ImsServiceDeathRecipient implements IBinder.DeathRecipient {
2125 @Override
2126 public void binderDied() {
Brad Ebinger936a7d12018-01-16 09:36:56 -08002127 mMmTelFeatureConnection = null;
Wink Savilleef36ef62014-06-11 08:39:38 -07002128 mUt = null;
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -05002129 mConfig = null;
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -07002130 mEcbm = null;
Tyler Gunn4d128b62016-04-13 15:44:38 -07002131 mMultiEndpoint = null;
Wink Savilleef36ef62014-06-11 08:39:38 -07002132 }
2133 }
2134
2135 /**
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -07002136 * Gets the ECBM interface to request ECBM exit.
2137 *
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -07002138 * @return the ECBM interface instance
2139 * @throws ImsException if getting the ECBM interface results in an error
2140 */
Brad Ebinger936a7d12018-01-16 09:36:56 -08002141 public ImsEcbm getEcbmInterface() throws ImsException {
Brad Ebinger138b4a62017-06-20 16:29:50 -07002142 if (mEcbm != null && mEcbm.isBinderAlive()) {
2143 return mEcbm;
2144 }
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -07002145
Brad Ebinger138b4a62017-06-20 16:29:50 -07002146 checkAndThrowExceptionIfServiceUnavailable();
2147 try {
Brad Ebinger936a7d12018-01-16 09:36:56 -08002148 IImsEcbm iEcbm = mMmTelFeatureConnection.getEcbmInterface();
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -07002149
Brad Ebinger138b4a62017-06-20 16:29:50 -07002150 if (iEcbm == null) {
2151 throw new ImsException("getEcbmInterface()",
2152 ImsReasonInfo.CODE_ECBM_NOT_SUPPORTED);
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -07002153 }
Brad Ebinger138b4a62017-06-20 16:29:50 -07002154 mEcbm = new ImsEcbm(iEcbm);
2155 } catch (RemoteException e) {
2156 throw new ImsException("getEcbmInterface()", e,
2157 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -07002158 }
2159 return mEcbm;
2160 }
Pavel Zhamaitsiak8c065f52015-11-10 14:36:44 -08002161
Mohamed Abdalkaderf8800da2018-01-10 13:29:26 -08002162 public void sendSms(int token, int messageRef, String format, String smsc, boolean isRetry,
2163 byte[] pdu) throws ImsException {
2164 try {
Brad Ebinger936a7d12018-01-16 09:36:56 -08002165 mMmTelFeatureConnection.sendSms(token, messageRef, format, smsc, isRetry, pdu);
Mohamed Abdalkaderf8800da2018-01-10 13:29:26 -08002166 } catch (RemoteException e) {
2167 throw new ImsException("sendSms()", e, ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
2168 }
2169 }
2170
2171 public void acknowledgeSms(int token, int messageRef, int result) throws ImsException {
2172 try {
Brad Ebinger936a7d12018-01-16 09:36:56 -08002173 mMmTelFeatureConnection.acknowledgeSms(token, messageRef, result);
Mohamed Abdalkaderf8800da2018-01-10 13:29:26 -08002174 } catch (RemoteException e) {
2175 throw new ImsException("acknowledgeSms()", e,
2176 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
2177 }
2178 }
2179
2180 public void acknowledgeSmsReport(int token, int messageRef, int result) throws ImsException{
2181 try {
Brad Ebinger936a7d12018-01-16 09:36:56 -08002182 mMmTelFeatureConnection.acknowledgeSmsReport(token, messageRef, result);
Mohamed Abdalkaderf8800da2018-01-10 13:29:26 -08002183 } catch (RemoteException e) {
2184 throw new ImsException("acknowledgeSmsReport()", e,
2185 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
2186 }
2187 }
2188
2189 public String getSmsFormat() throws ImsException{
2190 try {
Brad Ebinger936a7d12018-01-16 09:36:56 -08002191 return mMmTelFeatureConnection.getSmsFormat();
Mohamed Abdalkaderf8800da2018-01-10 13:29:26 -08002192 } catch (RemoteException e) {
2193 throw new ImsException("getSmsFormat()", e,
2194 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
2195 }
2196 }
2197
2198 public void setSmsListener(IImsSmsListener listener) throws ImsException {
2199 try {
Brad Ebinger936a7d12018-01-16 09:36:56 -08002200 mMmTelFeatureConnection.setSmsListener(listener);
Mohamed Abdalkaderf8800da2018-01-10 13:29:26 -08002201 } catch (RemoteException e) {
2202 throw new ImsException("setSmsListener()", e,
2203 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
2204 }
2205 }
Mohamed Abdalkader415e6de2018-01-19 19:48:31 -08002206
Brad Ebingerd449b232018-02-12 14:33:05 -08002207 public void onSmsReady() throws ImsException {
Mohamed Abdalkader4d59b1b2018-01-23 13:11:00 -08002208 try {
Brad Ebingered690772018-01-23 13:41:32 -08002209 mMmTelFeatureConnection.onSmsReady();
Mohamed Abdalkader4d59b1b2018-01-23 13:11:00 -08002210 } catch (RemoteException e) {
2211 throw new ImsException("onSmsReady()", e,
2212 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
2213 }
2214 }
2215
Pavel Zhamaitsiak8c065f52015-11-10 14:36:44 -08002216 /**
Brad Ebingerd449b232018-02-12 14:33:05 -08002217 * Determines whether or not a call with the specified numbers should be placed over IMS or over
2218 * CSFB.
2219 * @param isEmergency is at least one call an emergency number.
2220 * @param numbers A {@link String} array containing the numbers in the call being placed. Can
2221 * be multiple numbers in the case of dialing out a conference.
2222 * @return The result of the query, one of the following values:
2223 * - {@link MmTelFeature#PROCESS_CALL_IMS}
2224 * - {@link MmTelFeature#PROCESS_CALL_CSFB}
2225 * @throws ImsException if the ImsService is not available. In this case, we should fall back
2226 * to CSFB anyway.
2227 */
2228 public @MmTelFeature.ProcessCallResult int shouldProcessCall(boolean isEmergency,
2229 String[] numbers) throws ImsException {
2230 try {
2231 return mMmTelFeatureConnection.shouldProcessCall(isEmergency, numbers);
2232 } catch (RemoteException e) {
2233 throw new ImsException("shouldProcessCall()", e,
2234 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
2235 }
2236 }
2237
2238 /**
Tyler Gunn4d128b62016-04-13 15:44:38 -07002239 * Gets the Multi-Endpoint interface to subscribe to multi-enpoint notifications..
2240 *
Tyler Gunn4d128b62016-04-13 15:44:38 -07002241 * @return the multi-endpoint interface instance
2242 * @throws ImsException if getting the multi-endpoint interface results in an error
2243 */
Brad Ebinger936a7d12018-01-16 09:36:56 -08002244 public ImsMultiEndpoint getMultiEndpointInterface() throws ImsException {
Brad Ebinger138b4a62017-06-20 16:29:50 -07002245 if (mMultiEndpoint != null && mMultiEndpoint.isBinderAlive()) {
2246 return mMultiEndpoint;
Tyler Gunn4d128b62016-04-13 15:44:38 -07002247 }
Brad Ebinger138b4a62017-06-20 16:29:50 -07002248
2249 checkAndThrowExceptionIfServiceUnavailable();
2250 try {
Brad Ebinger936a7d12018-01-16 09:36:56 -08002251 IImsMultiEndpoint iImsMultiEndpoint = mMmTelFeatureConnection.getMultiEndpointInterface();
Brad Ebinger138b4a62017-06-20 16:29:50 -07002252
2253 if (iImsMultiEndpoint == null) {
2254 throw new ImsException("getMultiEndpointInterface()",
2255 ImsReasonInfo.CODE_MULTIENDPOINT_NOT_SUPPORTED);
2256 }
2257 mMultiEndpoint = new ImsMultiEndpoint(iImsMultiEndpoint);
2258 } catch (RemoteException e) {
2259 throw new ImsException("getMultiEndpointInterface()", e,
2260 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
2261 }
2262
Tyler Gunn4d128b62016-04-13 15:44:38 -07002263 return mMultiEndpoint;
2264 }
2265
2266 /**
Pavel Zhamaitsiak8c065f52015-11-10 14:36:44 -08002267 * Resets ImsManager settings back to factory defaults.
2268 *
Brad Ebinger479f52c2017-08-28 13:19:22 -07002269 * @deprecated Doesn't support MSIM devices. Use {@link #factoryReset()} instead.
Brad Ebinger16417b42017-03-07 13:48:50 -08002270 *
Pavel Zhamaitsiak8c065f52015-11-10 14:36:44 -08002271 * @hide
2272 */
2273 public static void factoryReset(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07002274 ImsManager mgr = ImsManager.getInstance(context,
2275 SubscriptionManager.getDefaultVoicePhoneId());
2276 if (mgr != null) {
2277 mgr.factoryReset();
2278 }
2279 loge("factoryReset: ImsManager null.");
Pavel Zhamaitsiak8c065f52015-11-10 14:36:44 -08002280 }
Jack Yu2f102bd2015-12-28 15:31:48 -08002281
Brad Ebinger16417b42017-03-07 13:48:50 -08002282 /**
2283 * Resets ImsManager settings back to factory defaults.
2284 *
2285 * @hide
2286 */
Brad Ebinger479f52c2017-08-28 13:19:22 -07002287 public void factoryReset() {
Malcolm Chen201d2312017-09-28 17:28:45 -07002288 // Set VoLTE to default
2289 SubscriptionManager.setSubscriptionProperty(getSubId(),
2290 SubscriptionManager.ENHANCED_4G_MODE_ENABLED, booleanToPropertyString(true));
Brad Ebinger16417b42017-03-07 13:48:50 -08002291
2292 // Set VoWiFi to default
Malcolm Chen201d2312017-09-28 17:28:45 -07002293 SubscriptionManager.setSubscriptionProperty(getSubId(),
2294 SubscriptionManager.WFC_IMS_ENABLED,
2295 booleanToPropertyString(getBooleanCarrierConfig(
2296 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL)));
Brad Ebinger16417b42017-03-07 13:48:50 -08002297
2298 // Set VoWiFi mode to default
Malcolm Chen201d2312017-09-28 17:28:45 -07002299 SubscriptionManager.setSubscriptionProperty(getSubId(),
2300 SubscriptionManager.WFC_IMS_MODE,
2301 Integer.toString(getIntCarrierConfig(
2302 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT)));
Brad Ebinger16417b42017-03-07 13:48:50 -08002303
2304 // Set VoWiFi roaming to default
Malcolm Chen201d2312017-09-28 17:28:45 -07002305 SubscriptionManager.setSubscriptionProperty(getSubId(),
2306 SubscriptionManager.WFC_IMS_ROAMING_ENABLED,
2307 booleanToPropertyString(getBooleanCarrierConfig(
2308 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_ENABLED_BOOL)));
Brad Ebinger16417b42017-03-07 13:48:50 -08002309
2310 // Set VT to default
Malcolm Chen201d2312017-09-28 17:28:45 -07002311 SubscriptionManager.setSubscriptionProperty(getSubId(),
2312 SubscriptionManager.VT_IMS_ENABLED, booleanToPropertyString(true));
Brad Ebinger16417b42017-03-07 13:48:50 -08002313
2314 // Push settings to ImsConfig
Brad Ebinger479f52c2017-08-28 13:19:22 -07002315 updateImsServiceConfig(true);
Brad Ebinger16417b42017-03-07 13:48:50 -08002316 }
2317
Amit Mahajan24f7b162016-07-21 16:33:53 -07002318 private boolean isDataEnabled() {
Malcolm Chena402e892017-12-20 11:38:25 -08002319 return new TelephonyManager(mContext, getSubId()).isMobileDataEnabled();
Amit Mahajan24f7b162016-07-21 16:33:53 -07002320 }
2321
2322 private boolean isVolteProvisioned() {
Malcolm Chen45904b52017-10-25 17:05:41 -07002323 return getProvisionedBoolNoException(
2324 ImsConfig.ConfigConstants.VLT_SETTING_ENABLED);
Amit Mahajan24f7b162016-07-21 16:33:53 -07002325 }
2326
2327 private boolean isWfcProvisioned() {
Malcolm Chen45904b52017-10-25 17:05:41 -07002328 return getProvisionedBoolNoException(
2329 ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED);
Amit Mahajan24f7b162016-07-21 16:33:53 -07002330 }
2331
2332 private boolean isVtProvisioned() {
Malcolm Chen45904b52017-10-25 17:05:41 -07002333 return getProvisionedBoolNoException(
2334 ImsConfig.ConfigConstants.LVC_SETTING_ENABLED);
Jack Yu643ffe42016-07-08 14:25:46 -07002335 }
2336
Malcolm Chen201d2312017-09-28 17:28:45 -07002337 private static String booleanToPropertyString(boolean bool) {
2338 return bool ? "1" : "0";
2339 }
2340
2341
Jack Yu2f102bd2015-12-28 15:31:48 -08002342 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2343 pw.println("ImsManager:");
2344 pw.println(" mPhoneId = " + mPhoneId);
2345 pw.println(" mConfigUpdated = " + mConfigUpdated);
Brad Ebinger936a7d12018-01-16 09:36:56 -08002346 pw.println(" mImsServiceProxy = " + mMmTelFeatureConnection);
Amit Mahajan24f7b162016-07-21 16:33:53 -07002347 pw.println(" mDataEnabled = " + isDataEnabled());
Brad Ebinger479f52c2017-08-28 13:19:22 -07002348 pw.println(" ignoreDataEnabledChanged = " + getBooleanCarrierConfig(
Jack Yu57781852016-11-16 17:20:38 -08002349 CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS));
Jack Yu2f102bd2015-12-28 15:31:48 -08002350
Brad Ebinger479f52c2017-08-28 13:19:22 -07002351 pw.println(" isGbaValid = " + isGbaValid());
Jack Yu2f102bd2015-12-28 15:31:48 -08002352 pw.println(" isImsTurnOffAllowed = " + isImsTurnOffAllowed());
Brad Ebinger479f52c2017-08-28 13:19:22 -07002353 pw.println(" isNonTtyOrTtyOnVolteEnabled = " + isNonTtyOrTtyOnVolteEnabled());
Jack Yu2f102bd2015-12-28 15:31:48 -08002354
Brad Ebinger479f52c2017-08-28 13:19:22 -07002355 pw.println(" isVolteEnabledByPlatform = " + isVolteEnabledByPlatform());
2356 pw.println(" isVolteProvisionedOnDevice = " + isVolteProvisionedOnDevice());
Jack Yu2f102bd2015-12-28 15:31:48 -08002357 pw.println(" isEnhanced4gLteModeSettingEnabledByUser = " +
Brad Ebinger479f52c2017-08-28 13:19:22 -07002358 isEnhanced4gLteModeSettingEnabledByUser());
2359 pw.println(" isVtEnabledByPlatform = " + isVtEnabledByPlatform());
2360 pw.println(" isVtEnabledByUser = " + isVtEnabledByUser());
Jack Yu2f102bd2015-12-28 15:31:48 -08002361
Brad Ebinger479f52c2017-08-28 13:19:22 -07002362 pw.println(" isWfcEnabledByPlatform = " + isWfcEnabledByPlatform());
2363 pw.println(" isWfcEnabledByUser = " + isWfcEnabledByUser());
2364 pw.println(" getWfcMode = " + getWfcMode());
2365 pw.println(" isWfcRoamingEnabledByUser = " + isWfcRoamingEnabledByUser());
Jack Yu2f102bd2015-12-28 15:31:48 -08002366
Brad Ebinger479f52c2017-08-28 13:19:22 -07002367 pw.println(" isVtProvisionedOnDevice = " + isVtProvisionedOnDevice());
2368 pw.println(" isWfcProvisionedOnDevice = " + isWfcProvisionedOnDevice());
Jack Yu2f102bd2015-12-28 15:31:48 -08002369 pw.flush();
2370 }
Wink Savilleef36ef62014-06-11 08:39:38 -07002371}