blob: 590ab5ac5bd6fd2f39d9f19ea69267d6a0e55911 [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 Ebinger172977a2018-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 Ebinger172977a2018-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 Abdalkadere1453f42018-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 Ebinger190ed932018-01-23 13:41:32 -080037import android.telephony.ims.ImsCallProfile;
38import android.telephony.ims.ImsReasonInfo;
Brad Ebinger172977a2018-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 Ebinger190ed932018-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 Chen18837ff2017-10-25 17:05:41 -070058import java.util.concurrent.ConcurrentLinkedDeque;
Brad Ebinger44fd8af2017-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 Ebinger172977a2018-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 Ebinger172977a2018-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 Chen18837ff2017-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) {
Brad Ebinger6ddf28e2018-02-21 16:07:23 -0800342 manager = mImsManager;
343 }
Brad Ebinger0aed76d2018-03-05 16:39:02 -0800344 try {
345 mListener.connectionReady(manager);
346 }
347 catch (ImsException e) {
348 Log.w(TAG, "Connector: notifyReady exception: " + e.getMessage());
349 throw e;
350 }
351 // Only reset retry count if connectionReady does not generate an ImsException/
352 synchronized (mLock) {
353 mRetryCount = 0;
354 }
Brad Ebinger6ddf28e2018-02-21 16:07:23 -0800355 }
356
357 private void notifyNotReady() {
358 mListener.connectionUnavailable();
359 }
360 }
361
Wink Saville1e5a38a2014-10-23 10:24:46 -0700362 private static HashMap<Integer, ImsManager> sImsManagerInstances =
363 new HashMap<Integer, ImsManager>();
Etan Cohend7727462014-07-12 14:54:10 -0700364
Wink Savilleef36ef62014-06-11 08:39:38 -0700365 private Context mContext;
Brad Ebinger16417b42017-03-07 13:48:50 -0800366 private CarrierConfigManager mConfigManager;
Etan Cohenabbd7882014-09-26 22:35:35 -0700367 private int mPhoneId;
Brad Ebinger16780ff2017-01-26 11:18:21 -0800368 private final boolean mConfigDynamicBind;
Brad Ebinger172977a2018-01-16 09:36:56 -0800369 private @Nullable MmTelFeatureConnection mMmTelFeatureConnection = null;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -0700370 private boolean mConfigUpdated = false;
Wink Savilleef36ef62014-06-11 08:39:38 -0700371
Pavel Zhamaitsiakf4b90322016-01-26 14:34:09 -0800372 private ImsConfigListener mImsConfigListener;
373
Brad Ebinger6d1186c2018-04-26 14:23:45 -0700374 //TODO: Move these caches into the MmTelFeature Connection and restrict their lifetimes to the
375 // lifetime of the MmTelFeature.
376 // Ut interface for the supplementary service configuration
377 private ImsUt mUt = null;
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -0700378 // ECBM interface
379 private ImsEcbm mEcbm = null;
Tyler Gunn4d128b62016-04-13 15:44:38 -0700380 private ImsMultiEndpoint mMultiEndpoint = null;
381
Brad Ebinger172977a2018-01-16 09:36:56 -0800382 private Set<MmTelFeatureConnection.IFeatureUpdate> mStatusCallbacks =
383 new CopyOnWriteArraySet<>();
Brad Ebinger16780ff2017-01-26 11:18:21 -0800384
Amit Mahajan24f7b162016-07-21 16:33:53 -0700385 public static final String TRUE = "true";
386 public static final String FALSE = "false";
Jack Yu643ffe42016-07-08 14:25:46 -0700387
Naveen Kalla525c3a22017-02-06 14:46:42 -0800388 // mRecentDisconnectReasons stores the last 16 disconnect reasons
389 private static final int MAX_RECENT_DISCONNECT_REASONS = 16;
390 private ConcurrentLinkedDeque<ImsReasonInfo> mRecentDisconnectReasons =
391 new ConcurrentLinkedDeque<>();
392
Wink Savilleef36ef62014-06-11 08:39:38 -0700393 /**
394 * Gets a manager instance.
395 *
396 * @param context application context for creating the manager object
Etan Cohenabbd7882014-09-26 22:35:35 -0700397 * @param phoneId the phone ID for the IMS Service
398 * @return the manager instance corresponding to the phoneId
Wink Savilleef36ef62014-06-11 08:39:38 -0700399 */
Etan Cohenabbd7882014-09-26 22:35:35 -0700400 public static ImsManager getInstance(Context context, int phoneId) {
Etan Cohend7727462014-07-12 14:54:10 -0700401 synchronized (sImsManagerInstances) {
Naveen Kalla525c3a22017-02-06 14:46:42 -0800402 if (sImsManagerInstances.containsKey(phoneId)) {
Brad Ebingerff097922017-06-19 15:43:08 -0700403 ImsManager m = sImsManagerInstances.get(phoneId);
404 // May be null for some tests
405 if (m != null) {
406 m.connectIfServiceIsAvailable();
407 }
408 return m;
Naveen Kalla525c3a22017-02-06 14:46:42 -0800409 }
Wink Savilleef36ef62014-06-11 08:39:38 -0700410
Etan Cohenabbd7882014-09-26 22:35:35 -0700411 ImsManager mgr = new ImsManager(context, phoneId);
412 sImsManagerInstances.put(phoneId, mgr);
Etan Cohend7727462014-07-12 14:54:10 -0700413
414 return mgr;
415 }
Wink Savilleef36ef62014-06-11 08:39:38 -0700416 }
417
Etan Cohen45b5f312014-08-19 15:55:08 -0700418 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800419 * Returns the user configuration of Enhanced 4G LTE Mode setting.
420 *
421 * @deprecated Doesn't support MSIM devices. Use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700422 * {@link #isEnhanced4gLteModeSettingEnabledByUser()} instead.
Etan Cohen45b5f312014-08-19 15:55:08 -0700423 */
424 public static boolean isEnhanced4gLteModeSettingEnabledByUser(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700425 ImsManager mgr = ImsManager.getInstance(context,
426 SubscriptionManager.getDefaultVoicePhoneId());
427 if (mgr != null) {
428 return mgr.isEnhanced4gLteModeSettingEnabledByUser();
Sungmin Choi2f1af952016-02-01 17:15:35 +0900429 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700430 loge("isEnhanced4gLteModeSettingEnabledByUser: ImsManager null, returning default value.");
431 return false;
Etan Cohen45b5f312014-08-19 15:55:08 -0700432 }
433
434 /**
manabu, shimoda96aee542017-10-06 15:39:36 +0900435 * Returns the user configuration of Enhanced 4G LTE Mode setting for slot. If the option is
436 * not editable ({@link CarrierConfigManager#KEY_EDITABLE_ENHANCED_4G_LTE_BOOL} is false), or
437 * the setting is not initialized, this method will return default value specified by
438 * {@link CarrierConfigManager#KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL}.
439 *
440 * Note that even if the setting was set, it may no longer be editable. If this is the case we
441 * return the default value.
Brad Ebinger16417b42017-03-07 13:48:50 -0800442 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700443 public boolean isEnhanced4gLteModeSettingEnabledByUser() {
Malcolm Chen212ca652017-09-28 17:28:45 -0700444 int setting = SubscriptionManager.getIntegerSubscriptionProperty(
445 getSubId(), SubscriptionManager.ENHANCED_4G_MODE_ENABLED,
446 SUB_PROPERTY_NOT_INITIALIZED, mContext);
manabu, shimoda96aee542017-10-06 15:39:36 +0900447 boolean onByDefault = getBooleanCarrierConfig(
448 CarrierConfigManager.KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL);
Malcolm Chen212ca652017-09-28 17:28:45 -0700449
manabu, shimoda96aee542017-10-06 15:39:36 +0900450 // If Enhanced 4G LTE Mode is uneditable or not initialized, we use the default value
451 if (!getBooleanCarrierConfig(CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL)
452 || setting == SUB_PROPERTY_NOT_INITIALIZED) {
453 return onByDefault;
454 } else {
455 return (setting == ImsConfig.FeatureValueConstants.ON);
456 }
Brad Ebinger16417b42017-03-07 13:48:50 -0800457 }
458
459 /**
460 * Change persistent Enhanced 4G LTE Mode setting.
461 *
Brad Ebinger479f52c2017-08-28 13:19:22 -0700462 * @deprecated Doesn't support MSIM devices. Use {@link #setEnhanced4gLteModeSetting(boolean)}
Brad Ebinger16417b42017-03-07 13:48:50 -0800463 * instead.
Etan Cohen82f78122014-12-15 10:10:14 -0800464 */
465 public static void setEnhanced4gLteModeSetting(Context context, boolean enabled) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700466 ImsManager mgr = ImsManager.getInstance(context,
467 SubscriptionManager.getDefaultVoicePhoneId());
468 if (mgr != null) {
469 mgr.setEnhanced4gLteModeSetting(enabled);
Etan Cohen82f78122014-12-15 10:10:14 -0800470 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700471 loge("setEnhanced4gLteModeSetting: ImsManager null, value not set.");
Etan Cohen82f78122014-12-15 10:10:14 -0800472 }
473
474 /**
manabu, shimoda96aee542017-10-06 15:39:36 +0900475 * Change persistent Enhanced 4G LTE Mode setting. If the option is not editable
Brad Ebinger16417b42017-03-07 13:48:50 -0800476 * ({@link CarrierConfigManager#KEY_EDITABLE_ENHANCED_4G_LTE_BOOL} is false), this method will
manabu, shimoda96aee542017-10-06 15:39:36 +0900477 * set the setting to the default value specified by
478 * {@link CarrierConfigManager#KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL}.
Brad Ebinger16417b42017-03-07 13:48:50 -0800479 *
480 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700481 public void setEnhanced4gLteModeSetting(boolean enabled) {
manabu, shimoda96aee542017-10-06 15:39:36 +0900482 // If editable=false, we must keep default advanced 4G mode.
483 if (!getBooleanCarrierConfig(CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL)) {
484 enabled = getBooleanCarrierConfig(
485 CarrierConfigManager.KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL);
486 }
Brad Ebinger16417b42017-03-07 13:48:50 -0800487
Malcolm Chen212ca652017-09-28 17:28:45 -0700488 int prevSetting = SubscriptionManager.getIntegerSubscriptionProperty(
489 getSubId(), SubscriptionManager.ENHANCED_4G_MODE_ENABLED,
490 SUB_PROPERTY_NOT_INITIALIZED, mContext);
Brad Ebinger16417b42017-03-07 13:48:50 -0800491
manabu, shimoda96aee542017-10-06 15:39:36 +0900492 if (prevSetting != (enabled ?
493 ImsConfig.FeatureValueConstants.ON :
494 ImsConfig.FeatureValueConstants.OFF)) {
Malcolm Chen212ca652017-09-28 17:28:45 -0700495 SubscriptionManager.setSubscriptionProperty(getSubId(),
496 SubscriptionManager.ENHANCED_4G_MODE_ENABLED, booleanToPropertyString(enabled));
497 if (isNonTtyOrTtyOnVolteEnabled()) {
498 try {
499 setAdvanced4GMode(enabled);
500 } catch (ImsException ie) {
501 // do nothing
502 }
Brad Ebinger16417b42017-03-07 13:48:50 -0800503 }
504 }
505 }
506
507 /**
Etan Cohen82f78122014-12-15 10:10:14 -0800508 * Indicates whether the call is non-TTY or if TTY - whether TTY on VoLTE is
509 * supported.
Brad Ebinger16417b42017-03-07 13:48:50 -0800510 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700511 * {@link #isNonTtyOrTtyOnVolteEnabled()} instead.
Etan Cohen82f78122014-12-15 10:10:14 -0800512 */
513 public static boolean isNonTtyOrTtyOnVolteEnabled(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700514 ImsManager mgr = ImsManager.getInstance(context,
515 SubscriptionManager.getDefaultVoicePhoneId());
516 if (mgr != null) {
517 return mgr.isNonTtyOrTtyOnVolteEnabled();
518 }
519 loge("isNonTtyOrTtyOnVolteEnabled: ImsManager null, returning default value.");
520 return false;
521 }
522
523 /**
524 * Indicates whether the call is non-TTY or if TTY - whether TTY on VoLTE is
525 * supported on a per slot basis.
526 */
527 public boolean isNonTtyOrTtyOnVolteEnabled() {
528 if (getBooleanCarrierConfig(
fionaxu5803ef02016-03-08 11:48:48 -0800529 CarrierConfigManager.KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL)) {
Etan Cohen82f78122014-12-15 10:10:14 -0800530 return true;
531 }
532
Brad Ebinger479f52c2017-08-28 13:19:22 -0700533 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
Hall Liue511a202017-08-17 15:49:58 -0700534 if (tm == null) {
535 Log.w(TAG, "isNonTtyOrTtyOnVolteEnabled: telecom not available");
536 return true;
537 }
538 return tm.getCurrentTtyMode() == TelecomManager.TTY_MODE_OFF;
Etan Cohen82f78122014-12-15 10:10:14 -0800539 }
540
541 /**
Etan Cohenea2b5832014-10-23 18:50:35 -0700542 * Returns a platform configuration for VoLTE which may override the user setting.
Brad Ebinger16417b42017-03-07 13:48:50 -0800543 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700544 * {@link #isVolteEnabledByPlatform()} instead.
Etan Cohen45b5f312014-08-19 15:55:08 -0700545 */
Etan Cohenea2b5832014-10-23 18:50:35 -0700546 public static boolean isVolteEnabledByPlatform(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700547 ImsManager mgr = ImsManager.getInstance(context,
548 SubscriptionManager.getDefaultVoicePhoneId());
549 if (mgr != null) {
550 return mgr.isVolteEnabledByPlatform();
Etan Cohenaf55a402014-09-04 22:34:41 -0700551 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700552 loge("isVolteEnabledByPlatform: ImsManager null, returning default value.");
553 return false;
Etan Cohenb5388a32014-11-26 11:57:47 -0800554 }
555
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -0700556 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800557 * Returns a platform configuration for VoLTE which may override the user setting on a per Slot
558 * basis.
559 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700560 public boolean isVolteEnabledByPlatform() {
Malcolm Chen18837ff2017-10-25 17:05:41 -0700561 // We first read the per slot value. If doesn't exist, we read the general value. If still
562 // doesn't exist, we use the hardcoded default value.
563 if (SystemProperties.getInt(
564 PROPERTY_DBG_VOLTE_AVAIL_OVERRIDE + Integer.toString(mPhoneId),
565 SYSTEM_PROPERTY_NOT_SET) == 1 ||
566 SystemProperties.getInt(PROPERTY_DBG_VOLTE_AVAIL_OVERRIDE,
567 SYSTEM_PROPERTY_NOT_SET) == 1) {
Brad Ebinger16417b42017-03-07 13:48:50 -0800568 return true;
569 }
570
571 return mContext.getResources().getBoolean(
572 com.android.internal.R.bool.config_device_volte_available)
Malcolm Chen212ca652017-09-28 17:28:45 -0700573 && getBooleanCarrierConfig(CarrierConfigManager.KEY_CARRIER_VOLTE_AVAILABLE_BOOL)
Brad Ebinger479f52c2017-08-28 13:19:22 -0700574 && isGbaValid();
Brad Ebinger16417b42017-03-07 13:48:50 -0800575 }
576
577 /**
578 * Indicates whether VoLTE is provisioned on device.
579 *
580 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700581 * {@link #isVolteProvisionedOnDevice()} instead.
Etan Cohenb5388a32014-11-26 11:57:47 -0800582 */
583 public static boolean isVolteProvisionedOnDevice(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700584 ImsManager mgr = ImsManager.getInstance(context,
585 SubscriptionManager.getDefaultVoicePhoneId());
586 if (mgr != null) {
587 return mgr.isVolteProvisionedOnDevice();
Etan Cohenb5388a32014-11-26 11:57:47 -0800588 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700589 loge("isVolteProvisionedOnDevice: ImsManager null, returning default value.");
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -0700590 return true;
591 }
592
593 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800594 * Indicates whether VoLTE is provisioned on this slot.
595 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700596 public boolean isVolteProvisionedOnDevice() {
597 if (getBooleanCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -0800598 CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL)) {
599 return isVolteProvisioned();
600 }
601
602 return true;
603 }
604
605 /**
Meng Wang54fd41a2017-04-12 11:44:47 -0700606 * Indicates whether VoWifi is provisioned on device.
607 *
608 * When CarrierConfig KEY_CARRIER_VOLTE_OVERRIDE_WFC_PROVISIONING_BOOL is true, and VoLTE is not
609 * provisioned on device, this method returns false.
Brad Ebinger16417b42017-03-07 13:48:50 -0800610 *
611 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700612 * {@link #isWfcProvisionedOnDevice()} instead.
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -0700613 */
614 public static boolean isWfcProvisionedOnDevice(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700615 ImsManager mgr = ImsManager.getInstance(context,
616 SubscriptionManager.getDefaultVoicePhoneId());
617 if (mgr != null) {
618 return mgr.isWfcProvisionedOnDevice();
Meng Wang54fd41a2017-04-12 11:44:47 -0700619 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700620 loge("isWfcProvisionedOnDevice: ImsManager null, returning default value.");
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -0700621 return true;
622 }
623
624 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800625 * Indicates whether VoWifi is provisioned on slot.
Meng Wang54fd41a2017-04-12 11:44:47 -0700626 *
627 * When CarrierConfig KEY_CARRIER_VOLTE_OVERRIDE_WFC_PROVISIONING_BOOL is true, and VoLTE is not
628 * provisioned on device, this method returns false.
Brad Ebinger16417b42017-03-07 13:48:50 -0800629 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700630 public boolean isWfcProvisionedOnDevice() {
631 if (getBooleanCarrierConfig(
Meng Wang54fd41a2017-04-12 11:44:47 -0700632 CarrierConfigManager.KEY_CARRIER_VOLTE_OVERRIDE_WFC_PROVISIONING_BOOL)) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700633 if (!isVolteProvisionedOnDevice()) {
Meng Wang54fd41a2017-04-12 11:44:47 -0700634 return false;
635 }
636 }
637
Brad Ebinger479f52c2017-08-28 13:19:22 -0700638 if (getBooleanCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -0800639 CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL)) {
Meng Wang54fd41a2017-04-12 11:44:47 -0700640 return isWfcProvisioned();
Brad Ebinger16417b42017-03-07 13:48:50 -0800641 }
642
643 return true;
644 }
645
646 /**
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -0700647 * Indicates whether VT is provisioned on device
Brad Ebinger16417b42017-03-07 13:48:50 -0800648 *
649 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700650 * {@link #isVtProvisionedOnDevice()} instead.
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -0700651 */
652 public static boolean isVtProvisionedOnDevice(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700653 ImsManager mgr = ImsManager.getInstance(context,
654 SubscriptionManager.getDefaultVoicePhoneId());
655 if (mgr != null) {
656 return mgr.isVtProvisionedOnDevice();
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -0700657 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700658 loge("isVtProvisionedOnDevice: ImsManager null, returning default value.");
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -0700659 return true;
Etan Cohenb651fa52014-10-22 10:51:29 -0700660 }
661
Etan Cohenea2b5832014-10-23 18:50:35 -0700662 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800663 * Indicates whether VT is provisioned on slot.
664 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700665 public boolean isVtProvisionedOnDevice() {
666 if (getBooleanCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -0800667 CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL)) {
668 return isVtProvisioned();
669 }
670
671 return true;
672 }
673
674 /**
Etan Cohenea2b5832014-10-23 18:50:35 -0700675 * Returns a platform configuration for VT which may override the user setting.
676 *
677 * Note: VT presumes that VoLTE is enabled (these are configuration settings
678 * which must be done correctly).
Brad Ebinger16417b42017-03-07 13:48:50 -0800679 *
680 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700681 * {@link #isVtEnabledByPlatform()} instead.
Etan Cohenea2b5832014-10-23 18:50:35 -0700682 */
Etan Cohenb651fa52014-10-22 10:51:29 -0700683 public static boolean isVtEnabledByPlatform(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700684 ImsManager mgr = ImsManager.getInstance(context,
685 SubscriptionManager.getDefaultVoicePhoneId());
686 if (mgr != null) {
687 return mgr.isVtEnabledByPlatform();
Etan Cohenea2b5832014-10-23 18:50:35 -0700688 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700689 loge("isVtEnabledByPlatform: ImsManager null, returning default value.");
690 return false;
Etan Cohen45b5f312014-08-19 15:55:08 -0700691 }
692
Etan Cohena00c9192014-12-23 15:02:29 -0800693 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800694 * Returns a platform configuration for VT which may override the user setting.
695 *
696 * Note: VT presumes that VoLTE is enabled (these are configuration settings
697 * which must be done correctly).
698 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700699 public boolean isVtEnabledByPlatform() {
Malcolm Chen18837ff2017-10-25 17:05:41 -0700700 // We first read the per slot value. If doesn't exist, we read the general value. If still
701 // doesn't exist, we use the hardcoded default value.
702 if (SystemProperties.getInt(PROPERTY_DBG_VT_AVAIL_OVERRIDE +
703 Integer.toString(mPhoneId), SYSTEM_PROPERTY_NOT_SET) == 1 ||
704 SystemProperties.getInt(
705 PROPERTY_DBG_VT_AVAIL_OVERRIDE, SYSTEM_PROPERTY_NOT_SET) == 1) {
Brad Ebinger16417b42017-03-07 13:48:50 -0800706 return true;
707 }
708
709 return mContext.getResources().getBoolean(
710 com.android.internal.R.bool.config_device_vt_available) &&
Malcolm Chen212ca652017-09-28 17:28:45 -0700711 getBooleanCarrierConfig(CarrierConfigManager.KEY_CARRIER_VT_AVAILABLE_BOOL) &&
Brad Ebinger479f52c2017-08-28 13:19:22 -0700712 isGbaValid();
Brad Ebinger16417b42017-03-07 13:48:50 -0800713 }
714
715 /**
Etan Cohena7d32e82015-05-04 18:02:09 -0700716 * Returns the user configuration of VT setting
Brad Ebinger16417b42017-03-07 13:48:50 -0800717 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700718 * {@link #isVtEnabledByUser()} instead.
Etan Cohena7d32e82015-05-04 18:02:09 -0700719 */
720 public static boolean isVtEnabledByUser(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700721 ImsManager mgr = ImsManager.getInstance(context,
722 SubscriptionManager.getDefaultVoicePhoneId());
723 if (mgr != null) {
724 return mgr.isVtEnabledByUser();
725 }
726 loge("isVtEnabledByUser: ImsManager null, returning default value.");
727 return false;
Etan Cohena7d32e82015-05-04 18:02:09 -0700728 }
729
730 /**
Malcolm Chen212ca652017-09-28 17:28:45 -0700731 * Returns the user configuration of VT setting per slot. If not set, it
732 * returns true as default value.
Brad Ebinger16417b42017-03-07 13:48:50 -0800733 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700734 public boolean isVtEnabledByUser() {
Malcolm Chen212ca652017-09-28 17:28:45 -0700735 int setting = SubscriptionManager.getIntegerSubscriptionProperty(
736 getSubId(), SubscriptionManager.VT_IMS_ENABLED,
737 SUB_PROPERTY_NOT_INITIALIZED, mContext);
738
739 // If it's never set, by default we return true.
manabu, shimoda96aee542017-10-06 15:39:36 +0900740 return (setting == SUB_PROPERTY_NOT_INITIALIZED
741 || setting == ImsConfig.FeatureValueConstants.ON);
Brad Ebinger16417b42017-03-07 13:48:50 -0800742 }
743
744 /**
Etan Cohena7d32e82015-05-04 18:02:09 -0700745 * Change persistent VT enabled setting
Brad Ebinger16417b42017-03-07 13:48:50 -0800746 *
Brad Ebinger479f52c2017-08-28 13:19:22 -0700747 * @deprecated Does not support MSIM devices. Please use {@link #setVtSetting(boolean)} instead.
Etan Cohena7d32e82015-05-04 18:02:09 -0700748 */
749 public static void setVtSetting(Context context, boolean enabled) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700750 ImsManager mgr = ImsManager.getInstance(context,
Etan Cohena7d32e82015-05-04 18:02:09 -0700751 SubscriptionManager.getDefaultVoicePhoneId());
Brad Ebinger479f52c2017-08-28 13:19:22 -0700752 if (mgr != null) {
753 mgr.setVtSetting(enabled);
Etan Cohena7d32e82015-05-04 18:02:09 -0700754 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700755 loge("setVtSetting: ImsManager null, can not set value.");
Etan Cohena7d32e82015-05-04 18:02:09 -0700756 }
757
Brad Ebinger16417b42017-03-07 13:48:50 -0800758 /**
759 * Change persistent VT enabled setting for slot.
760 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700761 public void setVtSetting(boolean enabled) {
Brad Ebinger172977a2018-01-16 09:36:56 -0800762 SubscriptionManager.setSubscriptionProperty(getSubId(), SubscriptionManager.VT_IMS_ENABLED,
Malcolm Chen212ca652017-09-28 17:28:45 -0700763 booleanToPropertyString(enabled));
Brad Ebinger172977a2018-01-16 09:36:56 -0800764
Brad Ebinger16417b42017-03-07 13:48:50 -0800765 try {
Brad Ebinger172977a2018-01-16 09:36:56 -0800766 changeMmTelCapability(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO,
767 ImsRegistrationImplBase.REGISTRATION_TECH_LTE, enabled);
Brad Ebinger16417b42017-03-07 13:48:50 -0800768
769 if (enabled) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700770 log("setVtSetting(b) : turnOnIms");
Brad Ebinger16417b42017-03-07 13:48:50 -0800771 turnOnIms();
Brad Ebinger2384f422018-03-15 16:09:41 -0700772 } else if (isTurnOffImsAllowedByPlatform()
Brad Ebinger479f52c2017-08-28 13:19:22 -0700773 && (!isVolteEnabledByPlatform()
774 || !isEnhanced4gLteModeSettingEnabledByUser())) {
775 log("setVtSetting(b) : imsServiceAllowTurnOff -> turnOffIms");
Brad Ebinger16417b42017-03-07 13:48:50 -0800776 turnOffIms();
777 }
Brad Ebinger6d1186c2018-04-26 14:23:45 -0700778 } catch (ImsException e) {
Brad Ebinger172977a2018-01-16 09:36:56 -0800779 // The ImsService is down. Since the SubscriptionManager already recorded the user's
780 // preference, it will be resent in updateImsServiceConfig when the ImsPhoneCallTracker
781 // reconnects.
Brad Ebinger479f52c2017-08-28 13:19:22 -0700782 loge("setVtSetting(b): ", e);
Brad Ebinger16417b42017-03-07 13:48:50 -0800783 }
784 }
785
786 /**
Meng Wang9352c432016-06-08 14:22:20 -0700787 * Returns whether turning off ims is allowed by platform.
788 * The platform property may override the carrier config.
Brad Ebinger16417b42017-03-07 13:48:50 -0800789 *
790 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700791 * {@link #isTurnOffImsAllowedByPlatform()} instead.
Meng Wang9352c432016-06-08 14:22:20 -0700792 */
793 private static boolean isTurnOffImsAllowedByPlatform(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700794 ImsManager mgr = ImsManager.getInstance(context,
795 SubscriptionManager.getDefaultVoicePhoneId());
796 if (mgr != null) {
797 return mgr.isTurnOffImsAllowedByPlatform();
Meng Wang9352c432016-06-08 14:22:20 -0700798 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700799 loge("isTurnOffImsAllowedByPlatform: ImsManager null, returning default value.");
800 return true;
Meng Wang9352c432016-06-08 14:22:20 -0700801 }
802
Etan Cohena7d32e82015-05-04 18:02:09 -0700803 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800804 * Returns whether turning off ims is allowed by platform.
805 * The platform property may override the carrier config.
806 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700807 private boolean isTurnOffImsAllowedByPlatform() {
Malcolm Chen18837ff2017-10-25 17:05:41 -0700808 // We first read the per slot value. If doesn't exist, we read the general value. If still
809 // doesn't exist, we use the hardcoded default value.
810 if (SystemProperties.getInt(PROPERTY_DBG_ALLOW_IMS_OFF_OVERRIDE +
811 Integer.toString(mPhoneId), SYSTEM_PROPERTY_NOT_SET) == 1 ||
812 SystemProperties.getInt(
813 PROPERTY_DBG_ALLOW_IMS_OFF_OVERRIDE, SYSTEM_PROPERTY_NOT_SET) == 1) {
Brad Ebinger16417b42017-03-07 13:48:50 -0800814 return true;
815 }
Malcolm Chen18837ff2017-10-25 17:05:41 -0700816
Brad Ebinger479f52c2017-08-28 13:19:22 -0700817 return getBooleanCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -0800818 CarrierConfigManager.KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL);
819 }
820
821 /**
Etan Cohena00c9192014-12-23 15:02:29 -0800822 * Returns the user configuration of WFC setting
Brad Ebinger16417b42017-03-07 13:48:50 -0800823 *
824 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700825 * {@link #isWfcEnabledByUser()} instead.
Etan Cohena00c9192014-12-23 15:02:29 -0800826 */
827 public static boolean isWfcEnabledByUser(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700828 ImsManager mgr = ImsManager.getInstance(context,
829 SubscriptionManager.getDefaultVoicePhoneId());
830 if (mgr != null) {
831 return mgr.isWfcEnabledByUser();
832 }
833 loge("isWfcEnabledByUser: ImsManager null, returning default value.");
834 return true;
Etan Cohena00c9192014-12-23 15:02:29 -0800835 }
836
837 /**
Malcolm Chen212ca652017-09-28 17:28:45 -0700838 * Returns the user configuration of WFC setting for slot. If not set, it
839 * queries CarrierConfig value as default.
Brad Ebinger16417b42017-03-07 13:48:50 -0800840 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700841 public boolean isWfcEnabledByUser() {
Malcolm Chen212ca652017-09-28 17:28:45 -0700842 int setting = SubscriptionManager.getIntegerSubscriptionProperty(
843 getSubId(), SubscriptionManager.WFC_IMS_ENABLED,
844 SUB_PROPERTY_NOT_INITIALIZED, mContext);
845
846 // SUB_PROPERTY_NOT_INITIALIZED indicates it's never set in sub db.
847 if (setting == SUB_PROPERTY_NOT_INITIALIZED) {
848 return getBooleanCarrierConfig(
849 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL);
850 } else {
manabu, shimoda96aee542017-10-06 15:39:36 +0900851 return setting == ImsConfig.FeatureValueConstants.ON;
Malcolm Chen212ca652017-09-28 17:28:45 -0700852 }
Brad Ebinger16417b42017-03-07 13:48:50 -0800853 }
854
855 /**
856 * Change persistent WFC enabled setting.
857 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700858 * {@link #setWfcSetting} instead.
Etan Cohena00c9192014-12-23 15:02:29 -0800859 */
860 public static void setWfcSetting(Context context, boolean enabled) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700861 ImsManager mgr = ImsManager.getInstance(context,
Etan Cohena00c9192014-12-23 15:02:29 -0800862 SubscriptionManager.getDefaultVoicePhoneId());
Brad Ebinger479f52c2017-08-28 13:19:22 -0700863 if (mgr != null) {
864 mgr.setWfcSetting(enabled);
Etan Cohena00c9192014-12-23 15:02:29 -0800865 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700866 loge("setWfcSetting: ImsManager null, can not set value.");
Etan Cohena00c9192014-12-23 15:02:29 -0800867 }
868
869 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800870 * Change persistent WFC enabled setting for slot.
871 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700872 public void setWfcSetting(boolean enabled) {
Malcolm Chen212ca652017-09-28 17:28:45 -0700873 SubscriptionManager.setSubscriptionProperty(getSubId(),
874 SubscriptionManager.WFC_IMS_ENABLED, booleanToPropertyString(enabled));
Brad Ebinger16417b42017-03-07 13:48:50 -0800875
Meng Wangeba31e12018-04-17 11:27:21 -0700876 TelephonyManager tm = (TelephonyManager)
877 mContext.getSystemService(Context.TELEPHONY_SERVICE);
878 setWfcNonPersistent(enabled, getWfcMode(tm.isNetworkRoaming(getSubId())));
Meng Wang51c09072017-03-27 10:47:45 -0700879 }
880
881 /**
882 * Non-persistently change WFC enabled setting and WFC mode for slot
883 *
884 * @param wfcMode The WFC preference if WFC is enabled
885 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700886 public void setWfcNonPersistent(boolean enabled, int wfcMode) {
Meng Wang51c09072017-03-27 10:47:45 -0700887 // Force IMS to register over LTE when turning off WFC
888 int imsWfcModeFeatureValue =
889 enabled ? wfcMode : ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED;
890
Brad Ebinger16417b42017-03-07 13:48:50 -0800891 try {
Brad Ebinger172977a2018-01-16 09:36:56 -0800892 changeMmTelCapability(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
893 ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN, enabled);
Brad Ebinger16417b42017-03-07 13:48:50 -0800894
895 if (enabled) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700896 log("setWfcSetting() : turnOnIms");
Brad Ebinger16417b42017-03-07 13:48:50 -0800897 turnOnIms();
Brad Ebinger479f52c2017-08-28 13:19:22 -0700898 } else if (isTurnOffImsAllowedByPlatform()
899 && (!isVolteEnabledByPlatform()
900 || !isEnhanced4gLteModeSettingEnabledByUser())) {
901 log("setWfcSetting() : imsServiceAllowTurnOff -> turnOffIms");
Brad Ebinger16417b42017-03-07 13:48:50 -0800902 turnOffIms();
903 }
904
Brad Ebinger479f52c2017-08-28 13:19:22 -0700905 setWfcModeInternal(imsWfcModeFeatureValue);
Brad Ebinger6d1186c2018-04-26 14:23:45 -0700906 } catch (ImsException e) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700907 loge("setWfcSetting(): ", e);
Brad Ebinger16417b42017-03-07 13:48:50 -0800908 }
909 }
910
911 /**
912 * Returns the user configuration of WFC preference setting.
913 *
Malcolm Chen212ca652017-09-28 17:28:45 -0700914 * @deprecated Doesn't support MSIM devices. Use {@link #getWfcMode(boolean roaming)} instead.
Etan Cohena00c9192014-12-23 15:02:29 -0800915 */
916 public static int getWfcMode(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700917 ImsManager mgr = ImsManager.getInstance(context,
918 SubscriptionManager.getDefaultVoicePhoneId());
919 if (mgr != null) {
920 return mgr.getWfcMode();
921 }
922 loge("getWfcMode: ImsManager null, returning default value.");
923 return ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY;
Etan Cohena00c9192014-12-23 15:02:29 -0800924 }
925
926 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800927 * Returns the user configuration of WFC preference setting
Malcolm Chen212ca652017-09-28 17:28:45 -0700928 * @deprecated. Use {@link #getWfcMode(boolean roaming)} instead.
Brad Ebinger16417b42017-03-07 13:48:50 -0800929 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700930 public int getWfcMode() {
Malcolm Chen212ca652017-09-28 17:28:45 -0700931 return getWfcMode(false);
Brad Ebinger16417b42017-03-07 13:48:50 -0800932 }
933
934 /**
935 * Change persistent WFC preference setting.
936 *
Brad Ebinger479f52c2017-08-28 13:19:22 -0700937 * @deprecated Doesn't support MSIM devices. Use {@link #setWfcMode(int)} instead.
Etan Cohena00c9192014-12-23 15:02:29 -0800938 */
939 public static void setWfcMode(Context context, int wfcMode) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700940 ImsManager mgr = ImsManager.getInstance(context,
941 SubscriptionManager.getDefaultVoicePhoneId());
942 if (mgr != null) {
943 mgr.setWfcMode(wfcMode);
944 }
945 loge("setWfcMode: ImsManager null, can not set value.");
Pavel Zhamaitsiak9e6eca22015-03-16 15:30:53 -0700946 }
947
Meng Wang37477012016-09-20 09:59:56 -0700948 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800949 * Change persistent WFC preference setting for slot.
950 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700951 public void setWfcMode(int wfcMode) {
952 if (DBG) log("setWfcMode(i) - setting=" + wfcMode);
Malcolm Chen212ca652017-09-28 17:28:45 -0700953
954 SubscriptionManager.setSubscriptionProperty(getSubId(),
955 SubscriptionManager.WFC_IMS_MODE, Integer.toString(wfcMode));
Brad Ebinger16417b42017-03-07 13:48:50 -0800956
Brad Ebinger479f52c2017-08-28 13:19:22 -0700957 setWfcModeInternal(wfcMode);
Brad Ebinger16417b42017-03-07 13:48:50 -0800958 }
959
960 /**
Meng Wang37477012016-09-20 09:59:56 -0700961 * Returns the user configuration of WFC preference setting
962 *
963 * @param roaming {@code false} for home network setting, {@code true} for roaming setting
Brad Ebinger16417b42017-03-07 13:48:50 -0800964 *
Brad Ebinger479f52c2017-08-28 13:19:22 -0700965 * @deprecated Doesn't support MSIM devices. Use {@link #getWfcMode(boolean)} instead.
Meng Wang37477012016-09-20 09:59:56 -0700966 */
967 public static int getWfcMode(Context context, boolean roaming) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700968 ImsManager mgr = ImsManager.getInstance(context,
969 SubscriptionManager.getDefaultVoicePhoneId());
970 if (mgr != null) {
971 return mgr.getWfcMode(roaming);
Meng Wang37477012016-09-20 09:59:56 -0700972 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700973 loge("getWfcMode: ImsManager null, returning default value.");
974 return ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY;
Meng Wang37477012016-09-20 09:59:56 -0700975 }
976
977 /**
Malcolm Chen212ca652017-09-28 17:28:45 -0700978 * Returns the user configuration of WFC preference setting for slot. If not set, it
979 * queries CarrierConfig value as default.
Brad Ebinger16417b42017-03-07 13:48:50 -0800980 *
981 * @param roaming {@code false} for home network setting, {@code true} for roaming setting
982 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700983 public int getWfcMode(boolean roaming) {
Brad Ebinger74974e52018-05-01 16:16:47 -0700984 int setting;
Brad Ebinger16417b42017-03-07 13:48:50 -0800985 if (!roaming) {
Brad Ebinger74974e52018-05-01 16:16:47 -0700986 // The WFC mode is not editable, return the default setting in the CarrierConfig, not
987 // the user set value.
988 if (!getBooleanCarrierConfig(CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL)) {
Malcolm Chen212ca652017-09-28 17:28:45 -0700989 setting = getIntCarrierConfig(
990 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT);
Brad Ebinger74974e52018-05-01 16:16:47 -0700991
992 } else {
993 setting = getSettingFromSubscriptionManager(SubscriptionManager.WFC_IMS_MODE,
994 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT);
Malcolm Chen212ca652017-09-28 17:28:45 -0700995 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700996 if (DBG) log("getWfcMode - setting=" + setting);
Brad Ebinger16417b42017-03-07 13:48:50 -0800997 } else {
Brad Ebingerdf978672018-05-24 09:48:47 -0700998 // The WFC roaming mode is set in the Settings UI to be the same as the WFC mode if the
999 // roaming mode is set to not "editable" (see
1000 // CarrierConfigManager.KEY_EDITABLE_WFC_ROAMING_MODE_BOOL for explanation), so can't
1001 // override those settings here by setting the WFC roaming mode to default, like above.
1002 setting = getSettingFromSubscriptionManager(
1003 SubscriptionManager.WFC_IMS_ROAMING_MODE,
1004 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_MODE_INT);
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 /**
Brad Ebinger74974e52018-05-01 16:16:47 -07001011 * Returns the SubscriptionManager setting for the subSetting string. If it is not set, default
1012 * to the default CarrierConfig value for defaultConfigKey.
1013 */
1014 private int getSettingFromSubscriptionManager(String subSetting, String defaultConfigKey) {
1015 int result;
1016 result = SubscriptionManager.getIntegerSubscriptionProperty(getSubId(), subSetting,
1017 SUB_PROPERTY_NOT_INITIALIZED, mContext);
1018
1019 // SUB_PROPERTY_NOT_INITIALIZED indicates it's never set in sub db.
1020 if (result == SUB_PROPERTY_NOT_INITIALIZED) {
1021 result = getIntCarrierConfig(defaultConfigKey);
1022 }
1023 return result;
1024 }
1025
1026 /**
Meng Wang37477012016-09-20 09:59:56 -07001027 * Change persistent WFC preference setting
1028 *
1029 * @param roaming {@code false} for home network setting, {@code true} for roaming setting
Brad Ebinger16417b42017-03-07 13:48:50 -08001030 *
Brad Ebinger479f52c2017-08-28 13:19:22 -07001031 * @deprecated Doesn't support MSIM devices. Please use {@link #setWfcMode(int, boolean)}
1032 * instead.
Meng Wang37477012016-09-20 09:59:56 -07001033 */
1034 public static void setWfcMode(Context context, int wfcMode, boolean roaming) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001035 ImsManager mgr = ImsManager.getInstance(context,
1036 SubscriptionManager.getDefaultVoicePhoneId());
1037 if (mgr != null) {
1038 mgr.setWfcMode(wfcMode, roaming);
Meng Wang37477012016-09-20 09:59:56 -07001039 }
Brad Ebinger479f52c2017-08-28 13:19:22 -07001040 loge("setWfcMode: ImsManager null, can not set value.");
Meng Wang37477012016-09-20 09:59:56 -07001041 }
1042
Brad Ebinger16417b42017-03-07 13:48:50 -08001043 /**
1044 * Change persistent WFC preference setting
1045 *
1046 * @param roaming {@code false} for home network setting, {@code true} for roaming setting
1047 */
Brad Ebinger479f52c2017-08-28 13:19:22 -07001048 public void setWfcMode(int wfcMode, boolean roaming) {
Brad Ebinger16417b42017-03-07 13:48:50 -08001049 if (!roaming) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001050 if (DBG) log("setWfcMode(i,b) - setting=" + wfcMode);
Malcolm Chen212ca652017-09-28 17:28:45 -07001051 SubscriptionManager.setSubscriptionProperty(getSubId(),
1052 SubscriptionManager.WFC_IMS_MODE, Integer.toString(wfcMode));
Brad Ebinger16417b42017-03-07 13:48:50 -08001053 } else {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001054 if (DBG) log("setWfcMode(i,b) (roaming) - setting=" + wfcMode);
Malcolm Chen212ca652017-09-28 17:28:45 -07001055 SubscriptionManager.setSubscriptionProperty(getSubId(),
1056 SubscriptionManager.WFC_IMS_ROAMING_MODE, Integer.toString(wfcMode));
Brad Ebinger16417b42017-03-07 13:48:50 -08001057 }
1058
Brad Ebinger479f52c2017-08-28 13:19:22 -07001059 TelephonyManager tm = (TelephonyManager)
1060 mContext.getSystemService(Context.TELEPHONY_SERVICE);
1061 if (roaming == tm.isNetworkRoaming(getSubId())) {
1062 setWfcModeInternal(wfcMode);
1063 }
1064 }
1065
1066 private int getSubId() {
Brad Ebinger16417b42017-03-07 13:48:50 -08001067 int[] subIds = SubscriptionManager.getSubId(mPhoneId);
1068 int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1069 if (subIds != null && subIds.length >= 1) {
1070 subId = subIds[0];
1071 }
Brad Ebinger479f52c2017-08-28 13:19:22 -07001072 return subId;
Brad Ebinger16417b42017-03-07 13:48:50 -08001073 }
1074
Brad Ebinger479f52c2017-08-28 13:19:22 -07001075 private void setWfcModeInternal(int wfcMode) {
Brad Ebinger16417b42017-03-07 13:48:50 -08001076 final int value = wfcMode;
1077 Thread thread = new Thread(() -> {
Malcolm Chen212ca652017-09-28 17:28:45 -07001078 try {
Brad Ebinger172977a2018-01-16 09:36:56 -08001079 getConfigInterface().setConfig(
Malcolm Chen212ca652017-09-28 17:28:45 -07001080 ImsConfig.ConfigConstants.VOICE_OVER_WIFI_MODE, value);
1081 } catch (ImsException e) {
1082 // do nothing
1083 }
Brad Ebinger16417b42017-03-07 13:48:50 -08001084 });
1085 thread.start();
1086 }
1087
Etan Cohena00c9192014-12-23 15:02:29 -08001088 /**
1089 * Returns the user configuration of WFC roaming setting
Brad Ebinger16417b42017-03-07 13:48:50 -08001090 *
1091 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -07001092 * {@link #isWfcRoamingEnabledByUser()} instead.
Etan Cohena00c9192014-12-23 15:02:29 -08001093 */
1094 public static boolean isWfcRoamingEnabledByUser(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001095 ImsManager mgr = ImsManager.getInstance(context,
1096 SubscriptionManager.getDefaultVoicePhoneId());
1097 if (mgr != null) {
1098 return mgr.isWfcRoamingEnabledByUser();
1099 }
1100 loge("isWfcRoamingEnabledByUser: ImsManager null, returning default value.");
1101 return false;
Etan Cohena00c9192014-12-23 15:02:29 -08001102 }
1103
1104 /**
Malcolm Chen212ca652017-09-28 17:28:45 -07001105 * Returns the user configuration of WFC roaming setting for slot. If not set, it
1106 * queries CarrierConfig value as default.
Brad Ebinger16417b42017-03-07 13:48:50 -08001107 */
Brad Ebinger479f52c2017-08-28 13:19:22 -07001108 public boolean isWfcRoamingEnabledByUser() {
Malcolm Chen212ca652017-09-28 17:28:45 -07001109 int setting = SubscriptionManager.getIntegerSubscriptionProperty(
1110 getSubId(), SubscriptionManager.WFC_IMS_ROAMING_ENABLED,
1111 SUB_PROPERTY_NOT_INITIALIZED, mContext);
1112 if (setting == SUB_PROPERTY_NOT_INITIALIZED) {
1113 return getBooleanCarrierConfig(
1114 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_ENABLED_BOOL);
1115 } else {
manabu, shimoda96aee542017-10-06 15:39:36 +09001116 return setting == ImsConfig.FeatureValueConstants.ON;
Malcolm Chen212ca652017-09-28 17:28:45 -07001117 }
Brad Ebinger16417b42017-03-07 13:48:50 -08001118 }
1119
1120 /**
Etan Cohena00c9192014-12-23 15:02:29 -08001121 * Change persistent WFC roaming enabled setting
1122 */
1123 public static void setWfcRoamingSetting(Context context, boolean enabled) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001124 ImsManager mgr = ImsManager.getInstance(context,
Etan Cohena00c9192014-12-23 15:02:29 -08001125 SubscriptionManager.getDefaultVoicePhoneId());
Brad Ebinger479f52c2017-08-28 13:19:22 -07001126 if (mgr != null) {
1127 mgr.setWfcRoamingSetting(enabled);
Etan Cohena00c9192014-12-23 15:02:29 -08001128 }
Brad Ebinger479f52c2017-08-28 13:19:22 -07001129 loge("setWfcRoamingSetting: ImsManager null, value not set.");
Etan Cohena00c9192014-12-23 15:02:29 -08001130 }
1131
1132 /**
Brad Ebinger16417b42017-03-07 13:48:50 -08001133 * Change persistent WFC roaming enabled setting
1134 */
Brad Ebinger479f52c2017-08-28 13:19:22 -07001135 public void setWfcRoamingSetting(boolean enabled) {
Malcolm Chen212ca652017-09-28 17:28:45 -07001136 SubscriptionManager.setSubscriptionProperty(getSubId(),
1137 SubscriptionManager.WFC_IMS_ROAMING_ENABLED, booleanToPropertyString(enabled)
1138 );
Brad Ebinger16417b42017-03-07 13:48:50 -08001139
1140 setWfcRoamingSettingInternal(enabled);
1141 }
1142
1143 private void setWfcRoamingSettingInternal(boolean enabled) {
1144 final int value = enabled
1145 ? ImsConfig.FeatureValueConstants.ON
1146 : ImsConfig.FeatureValueConstants.OFF;
1147 Thread thread = new Thread(() -> {
Malcolm Chen212ca652017-09-28 17:28:45 -07001148 try {
Brad Ebinger172977a2018-01-16 09:36:56 -08001149 getConfigInterface().setConfig(
Malcolm Chen212ca652017-09-28 17:28:45 -07001150 ImsConfig.ConfigConstants.VOICE_OVER_WIFI_ROAMING, value);
1151 } catch (ImsException e) {
1152 // do nothing
1153 }
Brad Ebinger16417b42017-03-07 13:48:50 -08001154 });
1155 thread.start();
1156 }
1157
1158 /**
Etan Cohena00c9192014-12-23 15:02:29 -08001159 * Returns a platform configuration for WFC which may override the user
1160 * setting. Note: WFC presumes that VoLTE is enabled (these are
1161 * configuration settings which must be done correctly).
Brad Ebinger16417b42017-03-07 13:48:50 -08001162 *
Brad Ebinger479f52c2017-08-28 13:19:22 -07001163 * @deprecated Doesn't work for MSIM devices. Use {@link #isWfcEnabledByPlatform()}
Brad Ebinger16417b42017-03-07 13:48:50 -08001164 * instead.
Etan Cohena00c9192014-12-23 15:02:29 -08001165 */
1166 public static boolean isWfcEnabledByPlatform(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001167 ImsManager mgr = ImsManager.getInstance(context,
1168 SubscriptionManager.getDefaultVoicePhoneId());
1169 if (mgr != null) {
1170 return mgr.isWfcEnabledByPlatform();
Etan Cohena00c9192014-12-23 15:02:29 -08001171 }
Brad Ebinger479f52c2017-08-28 13:19:22 -07001172 loge("isWfcEnabledByPlatform: ImsManager null, returning default value.");
1173 return false;
Pavel Zhamaitsiak57911d12015-10-20 14:26:34 -07001174 }
1175
1176 /**
Brad Ebinger16417b42017-03-07 13:48:50 -08001177 * Returns a platform configuration for WFC which may override the user
1178 * setting per slot. Note: WFC presumes that VoLTE is enabled (these are
1179 * configuration settings which must be done correctly).
1180 */
Brad Ebinger479f52c2017-08-28 13:19:22 -07001181 public boolean isWfcEnabledByPlatform() {
Malcolm Chen18837ff2017-10-25 17:05:41 -07001182 // We first read the per slot value. If doesn't exist, we read the general value. If still
1183 // doesn't exist, we use the hardcoded default value.
1184 if (SystemProperties.getInt(PROPERTY_DBG_WFC_AVAIL_OVERRIDE +
1185 Integer.toString(mPhoneId), SYSTEM_PROPERTY_NOT_SET) == 1 ||
1186 SystemProperties.getInt(
1187 PROPERTY_DBG_WFC_AVAIL_OVERRIDE, SYSTEM_PROPERTY_NOT_SET) == 1) {
Brad Ebinger16417b42017-03-07 13:48:50 -08001188 return true;
1189 }
1190
1191 return mContext.getResources().getBoolean(
1192 com.android.internal.R.bool.config_device_wfc_ims_available) &&
Brad Ebinger479f52c2017-08-28 13:19:22 -07001193 getBooleanCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -08001194 CarrierConfigManager.KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL) &&
Brad Ebinger479f52c2017-08-28 13:19:22 -07001195 isGbaValid();
Etan Cohena00c9192014-12-23 15:02:29 -08001196 }
1197
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001198 /**
Brad Ebinger16417b42017-03-07 13:48:50 -08001199 * If carrier requires that IMS is only available if GBA capable SIM is used,
1200 * then this function checks GBA bit in EF IST.
1201 *
1202 * Format of EF IST is defined in 3GPP TS 31.103 (Section 4.2.7).
1203 */
Brad Ebinger479f52c2017-08-28 13:19:22 -07001204 private boolean isGbaValid() {
1205 if (getBooleanCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -08001206 CarrierConfigManager.KEY_CARRIER_IMS_GBA_REQUIRED_BOOL)) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001207 final TelephonyManager telephonyManager = new TelephonyManager(mContext, getSubId());
Brad Ebinger16417b42017-03-07 13:48:50 -08001208 String efIst = telephonyManager.getIsimIst();
1209 if (efIst == null) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001210 loge("isGbaValid - ISF is NULL");
Brad Ebinger16417b42017-03-07 13:48:50 -08001211 return true;
1212 }
1213 boolean result = efIst != null && efIst.length() > 1 &&
1214 (0x02 & (byte)efIst.charAt(1)) != 0;
Brad Ebinger479f52c2017-08-28 13:19:22 -07001215 if (DBG) log("isGbaValid - GBA capable=" + result + ", ISF=" + efIst);
Brad Ebinger16417b42017-03-07 13:48:50 -08001216 return result;
1217 }
1218 return true;
1219 }
1220
1221 /**
Malcolm Chen18837ff2017-10-25 17:05:41 -07001222 * Will return with config value or throw an ImsException if we receive an error from
1223 * ImsConfig for that value.
1224 */
1225 private boolean getProvisionedBool(ImsConfig config, int item) throws ImsException {
1226 int value = config.getProvisionedValue(item);
1227 if (value == ImsConfig.OperationStatusConstants.UNKNOWN) {
1228 throw new ImsException("getProvisionedBool failed with error for item: " + item,
1229 ImsReasonInfo.CODE_LOCAL_INTERNAL_ERROR);
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -07001230 }
Malcolm Chen18837ff2017-10-25 17:05:41 -07001231 return config.getProvisionedValue(item) == ImsConfig.FeatureValueConstants.ON;
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -07001232 }
1233
1234 /**
Malcolm Chen18837ff2017-10-25 17:05:41 -07001235 * Will return with config value or return false if we receive an error from
1236 * ImsConfig for that value.
Brad Ebingerbe6cb672017-08-25 14:55:00 -07001237 */
Malcolm Chen18837ff2017-10-25 17:05:41 -07001238 private boolean getProvisionedBoolNoException(int item) {
1239 try {
1240 ImsConfig config = getConfigInterface();
1241 return getProvisionedBool(config, item);
1242 } catch (ImsException ex) {
1243 return false;
Brad Ebingerbe6cb672017-08-25 14:55:00 -07001244 }
1245 }
1246
1247 /**
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001248 * Sync carrier config and user settings with ImsConfig.
1249 *
1250 * @param context for the manager object
1251 * @param phoneId phone id
1252 * @param force update
Brad Ebinger16417b42017-03-07 13:48:50 -08001253 *
Brad Ebinger479f52c2017-08-28 13:19:22 -07001254 * @deprecated Doesn't support MSIM devices. Use {@link #updateImsServiceConfig(boolean)}
1255 * instead.
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001256 */
1257 public static void updateImsServiceConfig(Context context, int phoneId, boolean force) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001258 ImsManager mgr = ImsManager.getInstance(context, phoneId);
1259 if (mgr != null) {
1260 mgr.updateImsServiceConfig(force);
Pavel Zhamaitsiakfc202992016-03-29 18:07:38 -07001261 }
Brad Ebinger479f52c2017-08-28 13:19:22 -07001262 loge("updateImsServiceConfig: ImsManager null, returning without update.");
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001263 }
1264
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -07001265 /**
Brad Ebinger16417b42017-03-07 13:48:50 -08001266 * Sync carrier config and user settings with ImsConfig.
1267 *
Brad Ebinger16417b42017-03-07 13:48:50 -08001268 * @param force update
1269 */
Brad Ebinger479f52c2017-08-28 13:19:22 -07001270 public void updateImsServiceConfig(boolean force) {
Brad Ebinger16417b42017-03-07 13:48:50 -08001271 if (!force) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001272 TelephonyManager tm = new TelephonyManager(mContext, getSubId());
1273 if (tm.getSimState() != TelephonyManager.SIM_STATE_READY) {
1274 log("updateImsServiceConfig: SIM not ready");
Brad Ebinger16417b42017-03-07 13:48:50 -08001275 // Don't disable IMS if SIM is not ready
1276 return;
1277 }
1278 }
1279
1280 if (!mConfigUpdated || force) {
1281 try {
Brad Ebinger16417b42017-03-07 13:48:50 -08001282 // TODO: Extend ImsConfig API and set all feature values in single function call.
1283
1284 // Note: currently the order of updates is set to produce different order of
Brad Ebinger172977a2018-01-16 09:36:56 -08001285 // changeEnabledCapabilities() function calls from setAdvanced4GMode(). This is done
1286 // to differentiate this code path from vendor code perspective.
Brad Ebinger16417b42017-03-07 13:48:50 -08001287 boolean isImsUsed = updateVolteFeatureValue();
1288 isImsUsed |= updateWfcFeatureAndProvisionedValues();
1289 isImsUsed |= updateVideoCallFeatureValue();
1290
Brad Ebinger479f52c2017-08-28 13:19:22 -07001291 if (isImsUsed || !isTurnOffImsAllowedByPlatform()) {
Brad Ebinger16417b42017-03-07 13:48:50 -08001292 // Turn on IMS if it is used.
1293 // Also, if turning off is not allowed for current carrier,
1294 // we need to turn IMS on because it might be turned off before
1295 // phone switched to current carrier.
Brad Ebinger479f52c2017-08-28 13:19:22 -07001296 log("updateImsServiceConfig: turnOnIms");
Brad Ebinger16417b42017-03-07 13:48:50 -08001297 turnOnIms();
1298 } else {
1299 // Turn off IMS if it is not used AND turning off is allowed for carrier.
Brad Ebinger479f52c2017-08-28 13:19:22 -07001300 log("updateImsServiceConfig: turnOffIms");
Brad Ebinger16417b42017-03-07 13:48:50 -08001301 turnOffIms();
1302 }
1303
1304 mConfigUpdated = true;
Brad Ebinger6d1186c2018-04-26 14:23:45 -07001305 } catch (ImsException e) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001306 loge("updateImsServiceConfig: ", e);
Brad Ebinger16417b42017-03-07 13:48:50 -08001307 mConfigUpdated = false;
1308 }
1309 }
1310 }
1311
1312 /**
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -07001313 * Update VoLTE config
1314 * @return whether feature is On
1315 * @throws ImsException
1316 */
Brad Ebinger6d1186c2018-04-26 14:23:45 -07001317 private boolean updateVolteFeatureValue() throws ImsException {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001318 boolean available = isVolteEnabledByPlatform();
1319 boolean enabled = isEnhanced4gLteModeSettingEnabledByUser();
1320 boolean isNonTty = isNonTtyOrTtyOnVolteEnabled();
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -08001321 boolean isFeatureOn = available && enabled && isNonTty;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001322
1323 log("updateVolteFeatureValue: available = " + available
1324 + ", enabled = " + enabled
1325 + ", nonTTY = " + isNonTty);
1326
Brad Ebinger172977a2018-01-16 09:36:56 -08001327 changeMmTelCapability(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
1328 ImsRegistrationImplBase.REGISTRATION_TECH_LTE, isFeatureOn);
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -07001329
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -08001330 return isFeatureOn;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001331 }
1332
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -07001333 /**
Jack Yu643ffe42016-07-08 14:25:46 -07001334 * Update video call over LTE config
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -07001335 * @return whether feature is On
1336 * @throws ImsException
1337 */
Brad Ebinger6d1186c2018-04-26 14:23:45 -07001338 private boolean updateVideoCallFeatureValue() throws ImsException {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001339 boolean available = isVtEnabledByPlatform();
1340 boolean enabled = isVtEnabledByUser();
1341 boolean isNonTty = isNonTtyOrTtyOnVolteEnabled();
Amit Mahajan24f7b162016-07-21 16:33:53 -07001342 boolean isDataEnabled = isDataEnabled();
Brad Ebinger479f52c2017-08-28 13:19:22 -07001343 boolean ignoreDataEnabledChanged = getBooleanCarrierConfig(
Jack Yu57781852016-11-16 17:20:38 -08001344 CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS);
Jack Yu643ffe42016-07-08 14:25:46 -07001345
Jack Yu57781852016-11-16 17:20:38 -08001346 boolean isFeatureOn = available && enabled && isNonTty
1347 && (ignoreDataEnabledChanged || isDataEnabled);
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001348
1349 log("updateVideoCallFeatureValue: available = " + available
1350 + ", enabled = " + enabled
Jack Yu643ffe42016-07-08 14:25:46 -07001351 + ", nonTTY = " + isNonTty
Amit Mahajan24f7b162016-07-21 16:33:53 -07001352 + ", data enabled = " + isDataEnabled);
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001353
Brad Ebinger172977a2018-01-16 09:36:56 -08001354 changeMmTelCapability(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO,
1355 ImsRegistrationImplBase.REGISTRATION_TECH_LTE, isFeatureOn);
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -07001356
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -08001357 return isFeatureOn;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001358 }
1359
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -07001360 /**
1361 * Update WFC config
1362 * @return whether feature is On
1363 * @throws ImsException
1364 */
Brad Ebinger6d1186c2018-04-26 14:23:45 -07001365 private boolean updateWfcFeatureAndProvisionedValues() throws ImsException {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001366 TelephonyManager tm = new TelephonyManager(mContext, getSubId());
1367 boolean isNetworkRoaming = tm.isNetworkRoaming();
1368 boolean available = isWfcEnabledByPlatform();
1369 boolean enabled = isWfcEnabledByUser();
Brad Ebinger479f52c2017-08-28 13:19:22 -07001370 int mode = getWfcMode(isNetworkRoaming);
1371 boolean roaming = isWfcRoamingEnabledByUser();
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -08001372 boolean isFeatureOn = available && enabled;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001373
1374 log("updateWfcFeatureAndProvisionedValues: available = " + available
1375 + ", enabled = " + enabled
1376 + ", mode = " + mode
1377 + ", roaming = " + roaming);
1378
Brad Ebinger172977a2018-01-16 09:36:56 -08001379 changeMmTelCapability(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
1380 ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN, isFeatureOn);
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001381
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -08001382 if (!isFeatureOn) {
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001383 mode = ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED;
1384 roaming = false;
1385 }
Brad Ebinger74974e52018-05-01 16:16:47 -07001386 setWfcModeInternal(mode);
Brad Ebinger16417b42017-03-07 13:48:50 -08001387 setWfcRoamingSettingInternal(roaming);
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -07001388
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -08001389 return isFeatureOn;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001390 }
1391
Brad Ebinger16780ff2017-01-26 11:18:21 -08001392 /**
Brad Ebinger479f52c2017-08-28 13:19:22 -07001393 * Do NOT use this directly, instead use {@link #getInstance(Context, int)}.
Brad Ebinger16780ff2017-01-26 11:18:21 -08001394 */
1395 @VisibleForTesting
1396 public ImsManager(Context context, int phoneId) {
Wink Savilleef36ef62014-06-11 08:39:38 -07001397 mContext = context;
Etan Cohenabbd7882014-09-26 22:35:35 -07001398 mPhoneId = phoneId;
Brad Ebinger16780ff2017-01-26 11:18:21 -08001399 mConfigDynamicBind = mContext.getResources().getBoolean(
1400 com.android.internal.R.bool.config_dynamic_bind_ims);
Brad Ebinger16417b42017-03-07 13:48:50 -08001401 mConfigManager = (CarrierConfigManager) context.getSystemService(
1402 Context.CARRIER_CONFIG_SERVICE);
Brad Ebinger16780ff2017-01-26 11:18:21 -08001403 createImsService();
1404 }
1405
1406 /**
Brad Ebinger16780ff2017-01-26 11:18:21 -08001407 * @return Whether or not ImsManager is configured to Dynamically bind or not to support legacy
1408 * devices.
1409 */
1410 public boolean isDynamicBinding() {
1411 return mConfigDynamicBind;
Wink Savilleef36ef62014-06-11 08:39:38 -07001412 }
1413
Etan Cohenf4311122015-02-26 17:47:13 -08001414 /*
Brad Ebinger0aed76d2018-03-05 16:39:02 -08001415 * Returns a flag indicating whether the IMS service is available. If it is not available or
1416 * busy, it will try to connect before reporting failure.
Etan Cohenf4311122015-02-26 17:47:13 -08001417 */
1418 public boolean isServiceAvailable() {
Brad Ebinger0aed76d2018-03-05 16:39:02 -08001419 // If we are busy resolving dynamic IMS bindings, we are not available yet.
1420 TelephonyManager tm = (TelephonyManager)
1421 mContext.getSystemService(Context.TELEPHONY_SERVICE);
1422 if (tm.isResolvingImsBinding()) {
1423 Log.d(TAG, "isServiceAvailable: resolving IMS binding, returning false");
1424 return false;
1425 }
1426
Brad Ebingerff097922017-06-19 15:43:08 -07001427 connectIfServiceIsAvailable();
Brad Ebinger16780ff2017-01-26 11:18:21 -08001428 // mImsServiceProxy will always create an ImsServiceProxy.
Brad Ebinger172977a2018-01-16 09:36:56 -08001429 return mMmTelFeatureConnection.isBinderAlive();
Etan Cohenf4311122015-02-26 17:47:13 -08001430 }
1431
Suresh Koleticc3139c2017-11-03 18:23:57 +05301432 /*
1433 * Returns a flag indicating whether the IMS service is ready to send requests to lower layers.
1434 */
1435 public boolean isServiceReady() {
1436 connectIfServiceIsAvailable();
Brad Ebinger172977a2018-01-16 09:36:56 -08001437 return mMmTelFeatureConnection.isBinderReady();
Suresh Koleticc3139c2017-11-03 18:23:57 +05301438 }
1439
Brad Ebingerff097922017-06-19 15:43:08 -07001440 /**
1441 * If the service is available, try to reconnect.
1442 */
1443 public void connectIfServiceIsAvailable() {
Brad Ebinger172977a2018-01-16 09:36:56 -08001444 if (mMmTelFeatureConnection == null || !mMmTelFeatureConnection.isBinderAlive()) {
Brad Ebingerff097922017-06-19 15:43:08 -07001445 createImsService();
1446 }
1447 }
1448
Brad Ebinger172977a2018-01-16 09:36:56 -08001449 public void setConfigListener(ImsConfigListener listener) {
Pavel Zhamaitsiakf4b90322016-01-26 14:34:09 -08001450 mImsConfigListener = listener;
1451 }
1452
Brad Ebingerb10b61e2017-04-18 11:45:26 -07001453
1454 /**
1455 * Adds a callback for status changed events if the binder is already available. If it is not,
1456 * this method will throw an ImsException.
1457 */
Brad Ebinger6ddf28e2018-02-21 16:07:23 -08001458 @VisibleForTesting
Brad Ebinger172977a2018-01-16 09:36:56 -08001459 public void addNotifyStatusChangedCallbackIfAvailable(MmTelFeatureConnection.IFeatureUpdate c)
Brad Ebingerb10b61e2017-04-18 11:45:26 -07001460 throws ImsException {
Brad Ebinger172977a2018-01-16 09:36:56 -08001461 if (!mMmTelFeatureConnection.isBinderAlive()) {
Brad Ebingerb10b61e2017-04-18 11:45:26 -07001462 throw new ImsException("Binder is not active!",
1463 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1464 }
Brad Ebinger16780ff2017-01-26 11:18:21 -08001465 if (c != null) {
1466 mStatusCallbacks.add(c);
1467 }
1468 }
1469
Brad Ebinger6ddf28e2018-02-21 16:07:23 -08001470 void removeNotifyStatusChangedCallback(MmTelFeatureConnection.IFeatureUpdate c) {
Brad Ebinger44fd8af2017-12-14 14:24:02 -08001471 if (c != null) {
1472 mStatusCallbacks.remove(c);
1473 } else {
1474 Log.w(TAG, "removeNotifyStatusChangedCallback: callback is null!");
1475 }
1476 }
1477
Wink Savilleef36ef62014-06-11 08:39:38 -07001478 /**
1479 * Opens the IMS service for making calls and/or receiving generic IMS calls.
Brad Ebinger172977a2018-01-16 09:36:56 -08001480 * The caller may make subsequent calls through {@link #makeCall}.
Wink Savilleef36ef62014-06-11 08:39:38 -07001481 * The IMS service will register the device to the operator's network with the credentials
1482 * (from ISIM) periodically in order to receive calls from the operator's network.
Brad Ebinger172977a2018-01-16 09:36:56 -08001483 * When the IMS service receives a new call, it will call
1484 * {@link MmTelFeature.Listener#onIncomingCall}
1485 * The listener contains a call ID extra {@link #getCallId} and it can be used to take a call.
1486 * @param listener A {@link MmTelFeature.Listener}, which is the interface the
1487 * {@link MmTelFeature} uses to notify the framework of updates
1488 * @throws NullPointerException if {@code listener} is null
Wink Savilleef36ef62014-06-11 08:39:38 -07001489 * @throws ImsException if calling the IMS service results in an error
1490 * @see #getCallId
Wink Savilleef36ef62014-06-11 08:39:38 -07001491 */
Brad Ebinger172977a2018-01-16 09:36:56 -08001492 public void open(MmTelFeature.Listener listener) throws ImsException {
Wink Savilleef36ef62014-06-11 08:39:38 -07001493 checkAndThrowExceptionIfServiceUnavailable();
1494
Wink Savilleef36ef62014-06-11 08:39:38 -07001495 if (listener == null) {
1496 throw new NullPointerException("listener can't be null");
1497 }
1498
Wink Savilleef36ef62014-06-11 08:39:38 -07001499 try {
Brad Ebinger172977a2018-01-16 09:36:56 -08001500 mMmTelFeatureConnection.openConnection(listener);
Wink Savilleef36ef62014-06-11 08:39:38 -07001501 } catch (RemoteException e) {
Brad Ebinger172977a2018-01-16 09:36:56 -08001502 throw new ImsException("open()", e, ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
Wink Savilleef36ef62014-06-11 08:39:38 -07001503 }
Wink Savilleef36ef62014-06-11 08:39:38 -07001504 }
1505
1506 /**
Pavel Zhamaitsiakce410172016-04-15 10:55:56 -07001507 * Adds registration listener to the IMS service.
1508 *
1509 * @param serviceClass a service class specified in {@link ImsServiceClass}
1510 * For VoLTE service, it MUST be a {@link ImsServiceClass#MMTEL}.
1511 * @param listener To listen to IMS registration events; It cannot be null
1512 * @throws NullPointerException if {@code listener} is null
1513 * @throws ImsException if calling the IMS service results in an error
Brad Ebinger9a0280c2017-06-01 15:58:48 -07001514 *
1515 * @deprecated Use {@link #addRegistrationListener(ImsConnectionStateListener)} instead.
Pavel Zhamaitsiakce410172016-04-15 10:55:56 -07001516 */
1517 public void addRegistrationListener(int serviceClass, ImsConnectionStateListener listener)
1518 throws ImsException {
Brad Ebinger9a0280c2017-06-01 15:58:48 -07001519 addRegistrationListener(listener);
1520 }
1521
1522 /**
1523 * Adds registration listener to the IMS service.
1524 *
1525 * @param listener To listen to IMS registration events; It cannot be null
1526 * @throws NullPointerException if {@code listener} is null
1527 * @throws ImsException if calling the IMS service results in an error
Brad Ebinger172977a2018-01-16 09:36:56 -08001528 * @deprecated use {@link #addRegistrationCallback(ImsRegistrationImplBase.Callback)} and
1529 * {@link #addCapabilitiesCallback(ImsFeature.CapabilityCallback)} instead.
Brad Ebinger9a0280c2017-06-01 15:58:48 -07001530 */
Brad Ebinger44fd8af2017-12-14 14:24:02 -08001531 public void addRegistrationListener(ImsConnectionStateListener listener) throws ImsException {
Pavel Zhamaitsiakce410172016-04-15 10:55:56 -07001532 if (listener == null) {
1533 throw new NullPointerException("listener can't be null");
1534 }
Brad Ebinger172977a2018-01-16 09:36:56 -08001535 addRegistrationCallback(listener);
1536 // connect the ImsConnectionStateListener to the new CapabilityCallback.
1537 addCapabilitiesCallback(new ImsFeature.CapabilityCallback() {
1538 @Override
1539 public void onCapabilitiesStatusChanged(ImsFeature.Capabilities config) {
1540 listener.onFeatureCapabilityChangedAdapter(getRegistrationTech(), config);
Brad Ebinger9a0280c2017-06-01 15:58:48 -07001541 }
Brad Ebinger172977a2018-01-16 09:36:56 -08001542 });
1543 log("Registration Callback registered.");
1544 }
1545
1546 /**
1547 * Adds a callback that gets called when IMS registration has changed.
1548 * @param callback A {@link ImsRegistrationImplBase.Callback} that will notify the caller when
1549 * IMS registration status has changed.
1550 * @throws ImsException when the ImsService connection is not available.
1551 */
1552 public void addRegistrationCallback(ImsRegistrationImplBase.Callback callback)
1553 throws ImsException {
1554 if (callback == null) {
1555 throw new NullPointerException("registration callback can't be null");
Brad Ebinger9a0280c2017-06-01 15:58:48 -07001556 }
Brad Ebinger172977a2018-01-16 09:36:56 -08001557
Brad Ebinger172977a2018-01-16 09:36:56 -08001558 try {
1559 mMmTelFeatureConnection.addRegistrationCallback(callback);
1560 log("Registration Callback registered.");
1561 // Only record if there isn't a RemoteException.
1562 } catch (RemoteException e) {
1563 throw new ImsException("addRegistrationCallback(IRIB)", e,
1564 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1565 }
1566 }
1567
1568 /**
Brad Ebingerd1b1a3c2018-03-08 11:37:35 -08001569 * Removes a previously added registration callback that was added via
1570 * {@link #addRegistrationCallback(ImsRegistrationImplBase.Callback)} .
1571 * @param callback A {@link ImsRegistrationImplBase.Callback} that was previously added.
1572 * @throws ImsException when the ImsService connection is not available.
1573 */
1574 public void removeRegistrationListener(ImsRegistrationImplBase.Callback callback)
1575 throws ImsException {
1576 if (callback == null) {
1577 throw new NullPointerException("registration callback can't be null");
1578 }
1579
1580 try {
1581 mMmTelFeatureConnection.removeRegistrationCallback(callback);
1582 log("Registration callback removed.");
1583 } catch (RemoteException e) {
1584 throw new ImsException("removeRegistrationCallback(IRIB)", e,
1585 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1586 }
1587 }
1588
1589 /**
Brad Ebinger172977a2018-01-16 09:36:56 -08001590 * Adds a callback that gets called when MMTel capability status has changed, for example when
1591 * Voice over IMS or VT over IMS is not available currently.
1592 * @param callback A {@link ImsFeature.CapabilityCallback} that will notify the caller when
1593 * MMTel capability status has changed.
1594 * @throws ImsException when the ImsService connection is not available.
1595 */
1596 public void addCapabilitiesCallback(ImsFeature.CapabilityCallback callback)
1597 throws ImsException {
1598 if (callback == null) {
1599 throw new NullPointerException("capabilities callback can't be null");
1600 }
1601
1602 checkAndThrowExceptionIfServiceUnavailable();
1603 try {
1604 mMmTelFeatureConnection.addCapabilityCallback(callback);
1605 log("Capability Callback registered.");
1606 // Only record if there isn't a RemoteException.
1607 } catch (RemoteException e) {
1608 throw new ImsException("addCapabilitiesCallback(IF)", e,
1609 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
Pavel Zhamaitsiakce410172016-04-15 10:55:56 -07001610 }
1611 }
1612
1613 /**
Brad Ebinger16780ff2017-01-26 11:18:21 -08001614 * Removes the registration listener from the IMS service.
1615 *
Brad Ebinger16780ff2017-01-26 11:18:21 -08001616 * @param listener Previously registered listener that will be removed. Can not be null.
1617 * @throws NullPointerException if {@code listener} is null
1618 * @throws ImsException if calling the IMS service results in an error
1619 * instead.
1620 */
Brad Ebingerb5f30c72017-02-17 14:54:31 -08001621 public void removeRegistrationListener(ImsConnectionStateListener listener)
Brad Ebinger16780ff2017-01-26 11:18:21 -08001622 throws ImsException {
Brad Ebinger16780ff2017-01-26 11:18:21 -08001623 if (listener == null) {
1624 throw new NullPointerException("listener can't be null");
1625 }
1626
Brad Ebinger172977a2018-01-16 09:36:56 -08001627 checkAndThrowExceptionIfServiceUnavailable();
1628 try {
1629 mMmTelFeatureConnection.removeRegistrationCallback(listener);
1630 log("Registration Callback/Listener registered.");
1631 // Only record if there isn't a RemoteException.
1632 } catch (RemoteException e) {
1633 throw new ImsException("addRegistrationCallback()", e,
1634 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1635 }
1636 }
1637
1638 public @ImsRegistrationImplBase.ImsRegistrationTech int getRegistrationTech() {
1639 try {
1640 return mMmTelFeatureConnection.getRegistrationTech();
1641 } catch (RemoteException e) {
1642 Log.w(TAG, "getRegistrationTech: no connection to ImsService.");
1643 return ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
Brad Ebinger16780ff2017-01-26 11:18:21 -08001644 }
1645 }
1646
1647 /**
Brad Ebinger172977a2018-01-16 09:36:56 -08001648 * Closes the connection and removes all active callbacks.
Wink Savilleef36ef62014-06-11 08:39:38 -07001649 * All the resources that were allocated to the service are also released.
Wink Savilleef36ef62014-06-11 08:39:38 -07001650 */
Brad Ebinger172977a2018-01-16 09:36:56 -08001651 public void close() {
1652 if (mMmTelFeatureConnection != null) {
1653 mMmTelFeatureConnection.closeConnection();
Wink Savilleef36ef62014-06-11 08:39:38 -07001654 }
Brad Ebinger172977a2018-01-16 09:36:56 -08001655 mUt = null;
Brad Ebinger172977a2018-01-16 09:36:56 -08001656 mEcbm = null;
1657 mMultiEndpoint = null;
Wink Savilleef36ef62014-06-11 08:39:38 -07001658 }
1659
1660 /**
1661 * Gets the configuration interface to provision / withdraw the supplementary service settings.
1662 *
Wink Savilleef36ef62014-06-11 08:39:38 -07001663 * @return the Ut interface instance
1664 * @throws ImsException if getting the Ut interface results in an error
1665 */
Brad Ebinger172977a2018-01-16 09:36:56 -08001666 public ImsUtInterface getSupplementaryServiceConfiguration() throws ImsException {
Brad Ebinger16780ff2017-01-26 11:18:21 -08001667 // FIXME: manage the multiple Ut interfaces based on the session id
Brad Ebinger138b4a62017-06-20 16:29:50 -07001668 if (mUt != null && mUt.isBinderAlive()) {
1669 return mUt;
Wink Savilleef36ef62014-06-11 08:39:38 -07001670 }
1671
Brad Ebinger138b4a62017-06-20 16:29:50 -07001672 checkAndThrowExceptionIfServiceUnavailable();
1673 try {
Brad Ebinger172977a2018-01-16 09:36:56 -08001674 IImsUt iUt = mMmTelFeatureConnection.getUtInterface();
Brad Ebinger138b4a62017-06-20 16:29:50 -07001675
1676 if (iUt == null) {
1677 throw new ImsException("getSupplementaryServiceConfiguration()",
1678 ImsReasonInfo.CODE_UT_NOT_SUPPORTED);
1679 }
1680
1681 mUt = new ImsUt(iUt);
1682 } catch (RemoteException e) {
1683 throw new ImsException("getSupplementaryServiceConfiguration()", e,
1684 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1685 }
Wink Savilleef36ef62014-06-11 08:39:38 -07001686 return mUt;
1687 }
1688
1689 /**
Wink Savilleef36ef62014-06-11 08:39:38 -07001690 * Creates a {@link ImsCallProfile} from the service capabilities & IMS registration state.
1691 *
Wink Savilleef36ef62014-06-11 08:39:38 -07001692 * @param serviceType a service type that is specified in {@link ImsCallProfile}
1693 * {@link ImsCallProfile#SERVICE_TYPE_NONE}
1694 * {@link ImsCallProfile#SERVICE_TYPE_NORMAL}
1695 * {@link ImsCallProfile#SERVICE_TYPE_EMERGENCY}
1696 * @param callType a call type that is specified in {@link ImsCallProfile}
1697 * {@link ImsCallProfile#CALL_TYPE_VOICE}
1698 * {@link ImsCallProfile#CALL_TYPE_VT}
1699 * {@link ImsCallProfile#CALL_TYPE_VT_TX}
1700 * {@link ImsCallProfile#CALL_TYPE_VT_RX}
1701 * {@link ImsCallProfile#CALL_TYPE_VT_NODIR}
1702 * {@link ImsCallProfile#CALL_TYPE_VS}
1703 * {@link ImsCallProfile#CALL_TYPE_VS_TX}
1704 * {@link ImsCallProfile#CALL_TYPE_VS_RX}
1705 * @return a {@link ImsCallProfile} object
1706 * @throws ImsException if calling the IMS service results in an error
1707 */
Brad Ebinger172977a2018-01-16 09:36:56 -08001708 public ImsCallProfile createCallProfile(int serviceType, int callType) throws ImsException {
Wink Savilleef36ef62014-06-11 08:39:38 -07001709 checkAndThrowExceptionIfServiceUnavailable();
1710
1711 try {
Brad Ebinger172977a2018-01-16 09:36:56 -08001712 return mMmTelFeatureConnection.createCallProfile(serviceType, callType);
Wink Savilleef36ef62014-06-11 08:39:38 -07001713 } catch (RemoteException e) {
1714 throw new ImsException("createCallProfile()", e,
1715 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1716 }
1717 }
1718
1719 /**
1720 * Creates a {@link ImsCall} to make a call.
1721 *
Wink Savilleef36ef62014-06-11 08:39:38 -07001722 * @param profile a call profile to make the call
1723 * (it contains service type, call type, media information, etc.)
Brad Ebinger172977a2018-01-16 09:36:56 -08001724 * @param callees participants to invite the conference call
Wink Savilleef36ef62014-06-11 08:39:38 -07001725 * @param listener listen to the call events from {@link ImsCall}
1726 * @return a {@link ImsCall} object
1727 * @throws ImsException if calling the IMS service results in an error
1728 */
Brad Ebinger172977a2018-01-16 09:36:56 -08001729 public ImsCall makeCall(ImsCallProfile profile, String[] callees,
Wink Savilleef36ef62014-06-11 08:39:38 -07001730 ImsCall.Listener listener) throws ImsException {
1731 if (DBG) {
Brad Ebinger172977a2018-01-16 09:36:56 -08001732 log("makeCall :: profile=" + profile);
Wink Savilleef36ef62014-06-11 08:39:38 -07001733 }
1734
1735 checkAndThrowExceptionIfServiceUnavailable();
1736
1737 ImsCall call = new ImsCall(mContext, profile);
1738
1739 call.setListener(listener);
Brad Ebinger172977a2018-01-16 09:36:56 -08001740 ImsCallSession session = createCallSession(profile);
Wink Savilleef36ef62014-06-11 08:39:38 -07001741
1742 if ((callees != null) && (callees.length == 1)) {
1743 call.start(session, callees[0]);
1744 } else {
1745 call.start(session, callees);
1746 }
1747
1748 return call;
1749 }
1750
1751 /**
1752 * Creates a {@link ImsCall} to take an incoming call.
1753 *
Brad Ebinger16780ff2017-01-26 11:18:21 -08001754 * @param sessionId a session id which is obtained from {@link ImsManager#open}
Brad Ebinger172977a2018-01-16 09:36:56 -08001755 * @param incomingCallExtras the incoming call broadcast intent
Wink Savilleef36ef62014-06-11 08:39:38 -07001756 * @param listener to listen to the call events from {@link ImsCall}
1757 * @return a {@link ImsCall} object
1758 * @throws ImsException if calling the IMS service results in an error
1759 */
Brad Ebinger172977a2018-01-16 09:36:56 -08001760 public ImsCall takeCall(IImsCallSession session, Bundle incomingCallExtras,
Wink Savilleef36ef62014-06-11 08:39:38 -07001761 ImsCall.Listener listener) throws ImsException {
1762 if (DBG) {
Brad Ebinger172977a2018-01-16 09:36:56 -08001763 log("takeCall :: incomingCall=" + incomingCallExtras);
Wink Savilleef36ef62014-06-11 08:39:38 -07001764 }
1765
1766 checkAndThrowExceptionIfServiceUnavailable();
1767
Brad Ebinger172977a2018-01-16 09:36:56 -08001768 if (incomingCallExtras == null) {
Wink Savilleef36ef62014-06-11 08:39:38 -07001769 throw new ImsException("Can't retrieve session with null intent",
1770 ImsReasonInfo.CODE_LOCAL_ILLEGAL_ARGUMENT);
1771 }
1772
Brad Ebinger172977a2018-01-16 09:36:56 -08001773 String callId = getCallId(incomingCallExtras);
Wink Savilleef36ef62014-06-11 08:39:38 -07001774
1775 if (callId == null) {
1776 throw new ImsException("Call ID missing in the incoming call intent",
1777 ImsReasonInfo.CODE_LOCAL_ILLEGAL_ARGUMENT);
1778 }
1779
1780 try {
Wink Savilleef36ef62014-06-11 08:39:38 -07001781 if (session == null) {
1782 throw new ImsException("No pending session for the call",
1783 ImsReasonInfo.CODE_LOCAL_NO_PENDING_CALL);
1784 }
1785
1786 ImsCall call = new ImsCall(mContext, session.getCallProfile());
1787
1788 call.attachSession(new ImsCallSession(session));
1789 call.setListener(listener);
1790
1791 return call;
1792 } catch (Throwable t) {
1793 throw new ImsException("takeCall()", t, ImsReasonInfo.CODE_UNSPECIFIED);
1794 }
1795 }
1796
1797 /**
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -05001798 * Gets the config interface to get/set service/capability parameters.
1799 *
1800 * @return the ImsConfig instance.
1801 * @throws ImsException if getting the setting interface results in an error.
1802 */
1803 public ImsConfig getConfigInterface() throws ImsException {
Brad Ebinger138b4a62017-06-20 16:29:50 -07001804 checkAndThrowExceptionIfServiceUnavailable();
Brad Ebinger6d1186c2018-04-26 14:23:45 -07001805
Brad Ebinger138b4a62017-06-20 16:29:50 -07001806 try {
Brad Ebinger172977a2018-01-16 09:36:56 -08001807 IImsConfig config = mMmTelFeatureConnection.getConfigInterface();
Brad Ebinger138b4a62017-06-20 16:29:50 -07001808 if (config == null) {
1809 throw new ImsException("getConfigInterface()",
1810 ImsReasonInfo.CODE_LOCAL_SERVICE_UNAVAILABLE);
1811 }
Brad Ebinger6d1186c2018-04-26 14:23:45 -07001812 return new ImsConfig(config);
Brad Ebinger138b4a62017-06-20 16:29:50 -07001813 } catch (RemoteException e) {
1814 throw new ImsException("getConfigInterface()", e,
1815 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1816 }
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -05001817 }
1818
Brad Ebinger172977a2018-01-16 09:36:56 -08001819 public void changeMmTelCapability(
1820 @MmTelFeature.MmTelCapabilities.MmTelCapability int capability,
1821 @ImsRegistrationImplBase.ImsRegistrationTech int radioTech,
Brad Ebinger6d1186c2018-04-26 14:23:45 -07001822 boolean isEnabled) throws ImsException {
1823 checkAndThrowExceptionIfServiceUnavailable();
1824
Brad Ebinger172977a2018-01-16 09:36:56 -08001825 CapabilityChangeRequest request = new CapabilityChangeRequest();
1826 if (isEnabled) {
1827 request.addCapabilitiesToEnableForTech(capability, radioTech);
1828 } else {
1829 request.addCapabilitiesToDisableForTech(capability, radioTech);
1830 }
Brad Ebinger6d1186c2018-04-26 14:23:45 -07001831 try {
1832 mMmTelFeatureConnection.changeEnabledCapabilities(request, null);
1833 if (mImsConfigListener != null) {
1834 mImsConfigListener.onSetFeatureResponse(capability,
1835 mMmTelFeatureConnection.getRegistrationTech(),
1836 isEnabled ? ImsConfig.FeatureValueConstants.ON
1837 : ImsConfig.FeatureValueConstants.OFF, -1);
1838 }
1839 } catch (RemoteException e) {
1840 throw new ImsException("changeMmTelCapability()", e,
1841 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
Brad Ebinger172977a2018-01-16 09:36:56 -08001842 }
1843 }
1844
Hall Liub77d8972018-01-22 19:15:05 -08001845 public void setRttEnabled(boolean enabled) {
1846 try {
1847 setAdvanced4GMode(enabled || isEnhanced4gLteModeSettingEnabledByUser());
1848 final int value = enabled ? ImsConfig.FeatureValueConstants.ON :
1849 ImsConfig.FeatureValueConstants.OFF;
1850 Thread thread = new Thread(() -> {
1851 try {
1852 Log.i(ImsManager.class.getSimpleName(), "Setting RTT enabled to " + enabled);
1853 getConfigInterface().setProvisionedValue(
1854 ImsConfig.ConfigConstants.RTT_SETTING_ENABLED, value);
1855 } catch (ImsException e) {
1856 Log.e(ImsManager.class.getSimpleName(), "Unable to set RTT enabled to "
1857 + enabled + ": " + e);
1858 }
1859 });
1860 thread.start();
1861 } catch (ImsException e) {
1862 Log.e(ImsManager.class.getSimpleName(), "Unable to set RTT enabled to " + enabled
1863 + ": " + e);
1864 }
1865 }
1866
Hall Liue511a202017-08-17 15:49:58 -07001867 /**
1868 * Set the TTY mode. This is the actual tty mode (varies depending on peripheral status)
1869 */
1870 public void setTtyMode(int ttyMode) throws ImsException {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001871 if (!getBooleanCarrierConfig(
Hall Liue511a202017-08-17 15:49:58 -07001872 CarrierConfigManager.KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL)) {
1873 setAdvanced4GMode((ttyMode == TelecomManager.TTY_MODE_OFF) &&
Brad Ebinger479f52c2017-08-28 13:19:22 -07001874 isEnhanced4gLteModeSettingEnabledByUser());
Hall Liue511a202017-08-17 15:49:58 -07001875 }
1876 }
1877
1878 /**
1879 * Sets the UI TTY mode. This is the preferred TTY mode that the user sets in the call
1880 * settings screen.
Brad Ebingerb19b2832018-04-11 11:27:50 -07001881 * @param uiTtyMode TTY Mode, valid options are:
1882 * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF}
1883 * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL}
1884 * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO}
1885 * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO}
1886 * @param onComplete A Message that will be called by the ImsService when it has completed this
1887 * operation or null if not waiting for an async response. The Message must contain a
1888 * valid {@link Message#replyTo} {@link android.os.Messenger}, since it will be passed
1889 * through Binder to another process.
Hall Liue511a202017-08-17 15:49:58 -07001890 */
Brad Ebingerb5f30c72017-02-17 14:54:31 -08001891 public void setUiTTYMode(Context context, int uiTtyMode, Message onComplete)
Shriram Ganeshc403b7b2014-08-14 14:18:57 +05301892 throws ImsException {
1893
Etan Cohen82f78122014-12-15 10:10:14 -08001894 checkAndThrowExceptionIfServiceUnavailable();
Shriram Ganeshc403b7b2014-08-14 14:18:57 +05301895
Etan Cohen82f78122014-12-15 10:10:14 -08001896 try {
Brad Ebinger172977a2018-01-16 09:36:56 -08001897 mMmTelFeatureConnection.setUiTTYMode(uiTtyMode, onComplete);
Etan Cohen82f78122014-12-15 10:10:14 -08001898 } catch (RemoteException e) {
1899 throw new ImsException("setTTYMode()", e,
1900 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1901 }
Shriram Ganeshc403b7b2014-08-14 14:18:57 +05301902 }
1903
Naveen Kalla525c3a22017-02-06 14:46:42 -08001904 private ImsReasonInfo makeACopy(ImsReasonInfo imsReasonInfo) {
1905 Parcel p = Parcel.obtain();
1906 imsReasonInfo.writeToParcel(p, 0);
1907 p.setDataPosition(0);
1908 ImsReasonInfo clonedReasonInfo = ImsReasonInfo.CREATOR.createFromParcel(p);
1909 p.recycle();
1910 return clonedReasonInfo;
1911 }
1912
1913 /**
1914 * Get Recent IMS Disconnect Reasons.
1915 *
1916 * @return ArrayList of ImsReasonInfo objects. MAX size of the arraylist
1917 * is MAX_RECENT_DISCONNECT_REASONS. The objects are in the
1918 * chronological order.
1919 */
1920 public ArrayList<ImsReasonInfo> getRecentImsDisconnectReasons() {
1921 ArrayList<ImsReasonInfo> disconnectReasons = new ArrayList<>();
1922
1923 for (ImsReasonInfo reason : mRecentDisconnectReasons) {
1924 disconnectReasons.add(makeACopy(reason));
1925 }
1926 return disconnectReasons;
1927 }
Brad Ebinger16417b42017-03-07 13:48:50 -08001928
Brad Ebinger172977a2018-01-16 09:36:56 -08001929 public int getImsServiceState() throws ImsException {
1930 return mMmTelFeatureConnection.getFeatureState();
Brad Ebinger16780ff2017-01-26 11:18:21 -08001931 }
Naveen Kalla525c3a22017-02-06 14:46:42 -08001932
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -05001933 /**
Junda Liue7663c02015-06-23 11:16:26 -07001934 * Get the boolean config from carrier config manager.
1935 *
Brad Ebinger16417b42017-03-07 13:48:50 -08001936 * @param key config key defined in CarrierConfigManager
1937 * @return boolean value of corresponding key.
1938 */
Brad Ebinger479f52c2017-08-28 13:19:22 -07001939 private boolean getBooleanCarrierConfig(String key) {
Brad Ebinger16417b42017-03-07 13:48:50 -08001940 int[] subIds = SubscriptionManager.getSubId(mPhoneId);
1941 int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1942 if (subIds != null && subIds.length >= 1) {
1943 subId = subIds[0];
1944 }
1945 PersistableBundle b = null;
1946 if (mConfigManager != null) {
1947 // If an invalid subId is used, this bundle will contain default values.
1948 b = mConfigManager.getConfigForSubId(subId);
1949 }
1950 if (b != null) {
1951 return b.getBoolean(key);
1952 } else {
1953 // Return static default defined in CarrierConfigManager.
1954 return CarrierConfigManager.getDefaultConfig().getBoolean(key);
1955 }
1956 }
1957
1958 /**
fionaxu5803ef02016-03-08 11:48:48 -08001959 * Get the int config from carrier config manager.
1960 *
Brad Ebinger16417b42017-03-07 13:48:50 -08001961 * @param key config key defined in CarrierConfigManager
1962 * @return integer value of corresponding key.
1963 */
Brad Ebinger479f52c2017-08-28 13:19:22 -07001964 private int getIntCarrierConfig(String key) {
Brad Ebinger16417b42017-03-07 13:48:50 -08001965 int[] subIds = SubscriptionManager.getSubId(mPhoneId);
1966 int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1967 if (subIds != null && subIds.length >= 1) {
1968 subId = subIds[0];
1969 }
1970 PersistableBundle b = null;
1971 if (mConfigManager != null) {
1972 // If an invalid subId is used, this bundle will contain default values.
1973 b = mConfigManager.getConfigForSubId(subId);
1974 }
1975 if (b != null) {
1976 return b.getInt(key);
1977 } else {
1978 // Return static default defined in CarrierConfigManager.
1979 return CarrierConfigManager.getDefaultConfig().getInt(key);
1980 }
1981 }
1982
1983 /**
Wink Savilleef36ef62014-06-11 08:39:38 -07001984 * Gets the call ID from the specified incoming call broadcast intent.
1985 *
Brad Ebinger172977a2018-01-16 09:36:56 -08001986 * @param incomingCallExtras the incoming call broadcast intent
Wink Savilleef36ef62014-06-11 08:39:38 -07001987 * @return the call ID or null if the intent does not contain it
1988 */
Brad Ebinger172977a2018-01-16 09:36:56 -08001989 private static String getCallId(Bundle incomingCallExtras) {
1990 if (incomingCallExtras == null) {
Wink Savilleef36ef62014-06-11 08:39:38 -07001991 return null;
1992 }
1993
Brad Ebinger172977a2018-01-16 09:36:56 -08001994 return incomingCallExtras.getString(EXTRA_CALL_ID);
Wink Savilleef36ef62014-06-11 08:39:38 -07001995 }
1996
1997 /**
Brad Ebingerb10b61e2017-04-18 11:45:26 -07001998 * Checks to see if the ImsService Binder is connected. If it is not, we try to create the
1999 * connection again.
Wink Savilleef36ef62014-06-11 08:39:38 -07002000 */
2001 private void checkAndThrowExceptionIfServiceUnavailable()
2002 throws ImsException {
Brad Ebinger172977a2018-01-16 09:36:56 -08002003 if (mMmTelFeatureConnection == null || !mMmTelFeatureConnection.isBinderAlive()) {
Brad Ebinger16780ff2017-01-26 11:18:21 -08002004 createImsService();
Wink Savilleef36ef62014-06-11 08:39:38 -07002005
Brad Ebinger172977a2018-01-16 09:36:56 -08002006 if (mMmTelFeatureConnection == null) {
Wink Savilleef36ef62014-06-11 08:39:38 -07002007 throw new ImsException("Service is unavailable",
2008 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
2009 }
2010 }
2011 }
2012
Brad Ebinger16780ff2017-01-26 11:18:21 -08002013 /**
2014 * Binds the IMS service to make/receive the call. Supports two methods of exposing an
2015 * ImsService:
2016 * 1) com.android.ims.ImsService implementation in ServiceManager (deprecated).
2017 * 2) android.telephony.ims.ImsService implementation through ImsResolver.
2018 */
2019 private void createImsService() {
Brad Ebinger172977a2018-01-16 09:36:56 -08002020 Rlog.i(TAG, "Creating ImsService");
2021 mMmTelFeatureConnection = MmTelFeatureConnection.create(mContext, mPhoneId);
2022
Brad Ebinger44fd8af2017-12-14 14:24:02 -08002023 // Forwarding interface to tell mStatusCallbacks that the Proxy is unavailable.
Brad Ebinger172977a2018-01-16 09:36:56 -08002024 mMmTelFeatureConnection.setStatusCallback(new MmTelFeatureConnection.IFeatureUpdate() {
Brad Ebinger44fd8af2017-12-14 14:24:02 -08002025 @Override
2026 public void notifyStateChanged() {
Brad Ebinger172977a2018-01-16 09:36:56 -08002027 mStatusCallbacks.forEach(MmTelFeatureConnection.IFeatureUpdate::notifyStateChanged);
Brad Ebinger44fd8af2017-12-14 14:24:02 -08002028 }
2029
2030 @Override
2031 public void notifyUnavailable() {
Brad Ebinger172977a2018-01-16 09:36:56 -08002032 mStatusCallbacks.forEach(MmTelFeatureConnection.IFeatureUpdate::notifyUnavailable);
Brad Ebinger44fd8af2017-12-14 14:24:02 -08002033 }
2034 });
Etan Cohend7727462014-07-12 14:54:10 -07002035 }
2036
Wink Savilleef36ef62014-06-11 08:39:38 -07002037 /**
2038 * Creates a {@link ImsCallSession} with the specified call profile.
2039 * Use other methods, if applicable, instead of interacting with
2040 * {@link ImsCallSession} directly.
2041 *
Wink Savilleef36ef62014-06-11 08:39:38 -07002042 * @param profile a call profile to make the call
2043 */
Brad Ebinger172977a2018-01-16 09:36:56 -08002044 private ImsCallSession createCallSession(ImsCallProfile profile) throws ImsException {
Wink Savilleef36ef62014-06-11 08:39:38 -07002045 try {
Brad Ebingerb10b61e2017-04-18 11:45:26 -07002046 // Throws an exception if the ImsService Feature is not ready to accept commands.
Brad Ebinger172977a2018-01-16 09:36:56 -08002047 return new ImsCallSession(mMmTelFeatureConnection.createCallSession(profile));
Wink Savilleef36ef62014-06-11 08:39:38 -07002048 } catch (RemoteException e) {
Brad Ebingerb10b61e2017-04-18 11:45:26 -07002049 Rlog.w(TAG, "CreateCallSession: Error, remote exception: " + e.getMessage());
2050 throw new ImsException("createCallSession()", e,
2051 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
2052
Wink Savilleef36ef62014-06-11 08:39:38 -07002053 }
2054 }
2055
Etan Cohena00c9192014-12-23 15:02:29 -08002056 private static void log(String s) {
Wink Savilleef36ef62014-06-11 08:39:38 -07002057 Rlog.d(TAG, s);
2058 }
2059
Etan Cohena00c9192014-12-23 15:02:29 -08002060 private static void loge(String s) {
Wink Savilleef36ef62014-06-11 08:39:38 -07002061 Rlog.e(TAG, s);
2062 }
2063
Etan Cohena00c9192014-12-23 15:02:29 -08002064 private static void loge(String s, Throwable t) {
Wink Savilleef36ef62014-06-11 08:39:38 -07002065 Rlog.e(TAG, s, t);
2066 }
2067
2068 /**
ram7da5a112014-07-16 20:59:27 +05302069 * Used for turning on IMS.if its off already
2070 */
Etan Cohen82f78122014-12-15 10:10:14 -08002071 private void turnOnIms() throws ImsException {
Brad Ebinger172977a2018-01-16 09:36:56 -08002072 TelephonyManager tm = (TelephonyManager)
2073 mContext.getSystemService(Context.TELEPHONY_SERVICE);
2074 tm.enableIms(mPhoneId);
ram7da5a112014-07-16 20:59:27 +05302075 }
2076
Omkar Kolangade75f3ca32014-10-24 11:10:52 -07002077 private boolean isImsTurnOffAllowed() {
Brad Ebinger479f52c2017-08-28 13:19:22 -07002078 return isTurnOffImsAllowedByPlatform()
2079 && (!isWfcEnabledByPlatform()
2080 || !isWfcEnabledByUser());
Omkar Kolangade75f3ca32014-10-24 11:10:52 -07002081 }
2082
Amit Mahajan9cba36d2016-08-11 10:17:23 -07002083 private void setLteFeatureValues(boolean turnOn) {
2084 log("setLteFeatureValues: " + turnOn);
Brad Ebinger172977a2018-01-16 09:36:56 -08002085 CapabilityChangeRequest request = new CapabilityChangeRequest();
2086 if (turnOn) {
2087 request.addCapabilitiesToEnableForTech(
2088 MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
2089 ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
2090 } else {
2091 request.addCapabilitiesToDisableForTech(
2092 MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
2093 ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
2094 }
Pavel Zhamaitsiakff29b9d2016-04-15 12:16:57 -07002095
Brad Ebinger172977a2018-01-16 09:36:56 -08002096 if (isVolteEnabledByPlatform()) {
2097 boolean ignoreDataEnabledChanged = getBooleanCarrierConfig(
2098 CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS);
2099 boolean enableViLte = turnOn && isVtEnabledByUser() &&
2100 (ignoreDataEnabledChanged || isDataEnabled());
2101 if (enableViLte) {
2102 request.addCapabilitiesToEnableForTech(
2103 MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO,
2104 ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
2105 } else {
2106 request.addCapabilitiesToDisableForTech(
2107 MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO,
2108 ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
Etan Cohenb651fa52014-10-22 10:51:29 -07002109 }
Brad Ebinger172977a2018-01-16 09:36:56 -08002110 }
2111 try {
2112 mMmTelFeatureConnection.changeEnabledCapabilities(request, null);
2113 } catch (RemoteException e) {
2114 Log.e(TAG, "setLteFeatureValues: Exception: " + e.getMessage());
Etan Cohencfc784d2014-08-07 18:40:31 -07002115 }
Amit Mahajan9cba36d2016-08-11 10:17:23 -07002116 }
2117
2118 private void setAdvanced4GMode(boolean turnOn) throws ImsException {
2119 checkAndThrowExceptionIfServiceUnavailable();
2120
2121 // if turnOn: first set feature values then call turnOnIms()
2122 // if turnOff: only set feature values if IMS turn off is not allowed. If turn off is
2123 // allowed, first call turnOffIms() then set feature values
Etan Cohencfc784d2014-08-07 18:40:31 -07002124 if (turnOn) {
Amit Mahajan9cba36d2016-08-11 10:17:23 -07002125 setLteFeatureValues(turnOn);
2126 log("setAdvanced4GMode: turnOnIms");
Etan Cohencfc784d2014-08-07 18:40:31 -07002127 turnOnIms();
Amit Mahajan9cba36d2016-08-11 10:17:23 -07002128 } else {
2129 if (isImsTurnOffAllowed()) {
2130 log("setAdvanced4GMode: turnOffIms");
2131 turnOffIms();
2132 }
2133 setLteFeatureValues(turnOn);
Etan Cohencfc784d2014-08-07 18:40:31 -07002134 }
2135 }
2136
ram7da5a112014-07-16 20:59:27 +05302137 /**
2138 * Used for turning off IMS completely in order to make the device CSFB'ed.
2139 * Once turned off, all calls will be over CS.
2140 */
Etan Cohen82f78122014-12-15 10:10:14 -08002141 private void turnOffIms() throws ImsException {
Brad Ebinger172977a2018-01-16 09:36:56 -08002142 TelephonyManager tm = (TelephonyManager)
2143 mContext.getSystemService(Context.TELEPHONY_SERVICE);
2144 tm.disableIms(mPhoneId);
ram7da5a112014-07-16 20:59:27 +05302145 }
2146
Naveen Kalla525c3a22017-02-06 14:46:42 -08002147 private void addToRecentDisconnectReasons(ImsReasonInfo reason) {
2148 if (reason == null) return;
2149 while (mRecentDisconnectReasons.size() >= MAX_RECENT_DISCONNECT_REASONS) {
2150 mRecentDisconnectReasons.removeFirst();
2151 }
2152 mRecentDisconnectReasons.addLast(reason);
2153 }
2154
ram7da5a112014-07-16 20:59:27 +05302155 /**
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -07002156 * Gets the ECBM interface to request ECBM exit.
2157 *
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -07002158 * @return the ECBM interface instance
2159 * @throws ImsException if getting the ECBM interface results in an error
2160 */
Brad Ebinger172977a2018-01-16 09:36:56 -08002161 public ImsEcbm getEcbmInterface() throws ImsException {
Brad Ebinger138b4a62017-06-20 16:29:50 -07002162 if (mEcbm != null && mEcbm.isBinderAlive()) {
2163 return mEcbm;
2164 }
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -07002165
Brad Ebinger138b4a62017-06-20 16:29:50 -07002166 checkAndThrowExceptionIfServiceUnavailable();
2167 try {
Brad Ebinger172977a2018-01-16 09:36:56 -08002168 IImsEcbm iEcbm = mMmTelFeatureConnection.getEcbmInterface();
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -07002169
Brad Ebinger138b4a62017-06-20 16:29:50 -07002170 if (iEcbm == null) {
2171 throw new ImsException("getEcbmInterface()",
2172 ImsReasonInfo.CODE_ECBM_NOT_SUPPORTED);
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -07002173 }
Brad Ebinger138b4a62017-06-20 16:29:50 -07002174 mEcbm = new ImsEcbm(iEcbm);
2175 } catch (RemoteException e) {
2176 throw new ImsException("getEcbmInterface()", e,
2177 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -07002178 }
2179 return mEcbm;
2180 }
Pavel Zhamaitsiak8c065f52015-11-10 14:36:44 -08002181
Mohamed Abdalkader4d68a982018-01-10 13:29:26 -08002182 public void sendSms(int token, int messageRef, String format, String smsc, boolean isRetry,
2183 byte[] pdu) throws ImsException {
2184 try {
Brad Ebinger172977a2018-01-16 09:36:56 -08002185 mMmTelFeatureConnection.sendSms(token, messageRef, format, smsc, isRetry, pdu);
Mohamed Abdalkader4d68a982018-01-10 13:29:26 -08002186 } catch (RemoteException e) {
2187 throw new ImsException("sendSms()", e, ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
2188 }
2189 }
2190
2191 public void acknowledgeSms(int token, int messageRef, int result) throws ImsException {
2192 try {
Brad Ebinger172977a2018-01-16 09:36:56 -08002193 mMmTelFeatureConnection.acknowledgeSms(token, messageRef, result);
Mohamed Abdalkader4d68a982018-01-10 13:29:26 -08002194 } catch (RemoteException e) {
2195 throw new ImsException("acknowledgeSms()", e,
2196 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
2197 }
2198 }
2199
2200 public void acknowledgeSmsReport(int token, int messageRef, int result) throws ImsException{
2201 try {
Brad Ebinger172977a2018-01-16 09:36:56 -08002202 mMmTelFeatureConnection.acknowledgeSmsReport(token, messageRef, result);
Mohamed Abdalkader4d68a982018-01-10 13:29:26 -08002203 } catch (RemoteException e) {
2204 throw new ImsException("acknowledgeSmsReport()", e,
2205 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
2206 }
2207 }
2208
2209 public String getSmsFormat() throws ImsException{
2210 try {
Brad Ebinger172977a2018-01-16 09:36:56 -08002211 return mMmTelFeatureConnection.getSmsFormat();
Mohamed Abdalkader4d68a982018-01-10 13:29:26 -08002212 } catch (RemoteException e) {
2213 throw new ImsException("getSmsFormat()", e,
2214 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
2215 }
2216 }
2217
2218 public void setSmsListener(IImsSmsListener listener) throws ImsException {
2219 try {
Brad Ebinger172977a2018-01-16 09:36:56 -08002220 mMmTelFeatureConnection.setSmsListener(listener);
Mohamed Abdalkader4d68a982018-01-10 13:29:26 -08002221 } catch (RemoteException e) {
2222 throw new ImsException("setSmsListener()", e,
2223 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
2224 }
2225 }
Mohamed Abdalkadere1453f42018-01-19 19:48:31 -08002226
Brad Ebingerd449b232018-02-12 14:33:05 -08002227 public void onSmsReady() throws ImsException {
Mohamed Abdalkader0e734e12018-01-23 13:11:00 -08002228 try {
Brad Ebinger190ed932018-01-23 13:41:32 -08002229 mMmTelFeatureConnection.onSmsReady();
Mohamed Abdalkader0e734e12018-01-23 13:11:00 -08002230 } catch (RemoteException e) {
2231 throw new ImsException("onSmsReady()", e,
2232 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
2233 }
2234 }
2235
Pavel Zhamaitsiak8c065f52015-11-10 14:36:44 -08002236 /**
Brad Ebingerd449b232018-02-12 14:33:05 -08002237 * Determines whether or not a call with the specified numbers should be placed over IMS or over
2238 * CSFB.
2239 * @param isEmergency is at least one call an emergency number.
2240 * @param numbers A {@link String} array containing the numbers in the call being placed. Can
2241 * be multiple numbers in the case of dialing out a conference.
2242 * @return The result of the query, one of the following values:
2243 * - {@link MmTelFeature#PROCESS_CALL_IMS}
2244 * - {@link MmTelFeature#PROCESS_CALL_CSFB}
2245 * @throws ImsException if the ImsService is not available. In this case, we should fall back
2246 * to CSFB anyway.
2247 */
2248 public @MmTelFeature.ProcessCallResult int shouldProcessCall(boolean isEmergency,
2249 String[] numbers) throws ImsException {
2250 try {
2251 return mMmTelFeatureConnection.shouldProcessCall(isEmergency, numbers);
2252 } catch (RemoteException e) {
2253 throw new ImsException("shouldProcessCall()", e,
2254 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
2255 }
2256 }
2257
2258 /**
Tyler Gunn4d128b62016-04-13 15:44:38 -07002259 * Gets the Multi-Endpoint interface to subscribe to multi-enpoint notifications..
2260 *
Tyler Gunn4d128b62016-04-13 15:44:38 -07002261 * @return the multi-endpoint interface instance
2262 * @throws ImsException if getting the multi-endpoint interface results in an error
2263 */
Brad Ebinger172977a2018-01-16 09:36:56 -08002264 public ImsMultiEndpoint getMultiEndpointInterface() throws ImsException {
Brad Ebinger138b4a62017-06-20 16:29:50 -07002265 if (mMultiEndpoint != null && mMultiEndpoint.isBinderAlive()) {
2266 return mMultiEndpoint;
Tyler Gunn4d128b62016-04-13 15:44:38 -07002267 }
Brad Ebinger138b4a62017-06-20 16:29:50 -07002268
2269 checkAndThrowExceptionIfServiceUnavailable();
2270 try {
Brad Ebinger172977a2018-01-16 09:36:56 -08002271 IImsMultiEndpoint iImsMultiEndpoint = mMmTelFeatureConnection.getMultiEndpointInterface();
Brad Ebinger138b4a62017-06-20 16:29:50 -07002272
2273 if (iImsMultiEndpoint == null) {
2274 throw new ImsException("getMultiEndpointInterface()",
2275 ImsReasonInfo.CODE_MULTIENDPOINT_NOT_SUPPORTED);
2276 }
2277 mMultiEndpoint = new ImsMultiEndpoint(iImsMultiEndpoint);
2278 } catch (RemoteException e) {
2279 throw new ImsException("getMultiEndpointInterface()", e,
2280 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
2281 }
2282
Tyler Gunn4d128b62016-04-13 15:44:38 -07002283 return mMultiEndpoint;
2284 }
2285
2286 /**
Pavel Zhamaitsiak8c065f52015-11-10 14:36:44 -08002287 * Resets ImsManager settings back to factory defaults.
2288 *
Brad Ebinger479f52c2017-08-28 13:19:22 -07002289 * @deprecated Doesn't support MSIM devices. Use {@link #factoryReset()} instead.
Brad Ebinger16417b42017-03-07 13:48:50 -08002290 *
Pavel Zhamaitsiak8c065f52015-11-10 14:36:44 -08002291 * @hide
2292 */
2293 public static void factoryReset(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07002294 ImsManager mgr = ImsManager.getInstance(context,
2295 SubscriptionManager.getDefaultVoicePhoneId());
2296 if (mgr != null) {
2297 mgr.factoryReset();
2298 }
2299 loge("factoryReset: ImsManager null.");
Pavel Zhamaitsiak8c065f52015-11-10 14:36:44 -08002300 }
Jack Yu2f102bd2015-12-28 15:31:48 -08002301
Brad Ebinger16417b42017-03-07 13:48:50 -08002302 /**
2303 * Resets ImsManager settings back to factory defaults.
2304 *
2305 * @hide
2306 */
Brad Ebinger479f52c2017-08-28 13:19:22 -07002307 public void factoryReset() {
Brad Ebinger16417b42017-03-07 13:48:50 -08002308 // Set VoLTE to default
Malcolm Chen212ca652017-09-28 17:28:45 -07002309 SubscriptionManager.setSubscriptionProperty(getSubId(),
manabu, shimoda96aee542017-10-06 15:39:36 +09002310 SubscriptionManager.ENHANCED_4G_MODE_ENABLED,
2311 booleanToPropertyString(getBooleanCarrierConfig(
2312 CarrierConfigManager.KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL)));
Brad Ebinger16417b42017-03-07 13:48:50 -08002313
2314 // Set VoWiFi to default
Malcolm Chen212ca652017-09-28 17:28:45 -07002315 SubscriptionManager.setSubscriptionProperty(getSubId(),
2316 SubscriptionManager.WFC_IMS_ENABLED,
2317 booleanToPropertyString(getBooleanCarrierConfig(
2318 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL)));
Brad Ebinger16417b42017-03-07 13:48:50 -08002319
2320 // Set VoWiFi mode to default
Malcolm Chen212ca652017-09-28 17:28:45 -07002321 SubscriptionManager.setSubscriptionProperty(getSubId(),
2322 SubscriptionManager.WFC_IMS_MODE,
2323 Integer.toString(getIntCarrierConfig(
2324 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT)));
Brad Ebinger16417b42017-03-07 13:48:50 -08002325
2326 // Set VoWiFi roaming to default
Malcolm Chen212ca652017-09-28 17:28:45 -07002327 SubscriptionManager.setSubscriptionProperty(getSubId(),
2328 SubscriptionManager.WFC_IMS_ROAMING_ENABLED,
2329 booleanToPropertyString(getBooleanCarrierConfig(
2330 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_ENABLED_BOOL)));
Brad Ebinger16417b42017-03-07 13:48:50 -08002331
2332 // Set VT to default
Malcolm Chen212ca652017-09-28 17:28:45 -07002333 SubscriptionManager.setSubscriptionProperty(getSubId(),
2334 SubscriptionManager.VT_IMS_ENABLED, booleanToPropertyString(true));
Brad Ebinger16417b42017-03-07 13:48:50 -08002335
2336 // Push settings to ImsConfig
Brad Ebinger479f52c2017-08-28 13:19:22 -07002337 updateImsServiceConfig(true);
Brad Ebinger16417b42017-03-07 13:48:50 -08002338 }
2339
Amit Mahajan24f7b162016-07-21 16:33:53 -07002340 private boolean isDataEnabled() {
Malcolm Chenb8cd4402018-03-23 18:51:51 -07002341 return new TelephonyManager(mContext, getSubId()).isDataCapable();
Amit Mahajan24f7b162016-07-21 16:33:53 -07002342 }
2343
2344 private boolean isVolteProvisioned() {
Malcolm Chen18837ff2017-10-25 17:05:41 -07002345 return getProvisionedBoolNoException(
2346 ImsConfig.ConfigConstants.VLT_SETTING_ENABLED);
Amit Mahajan24f7b162016-07-21 16:33:53 -07002347 }
2348
2349 private boolean isWfcProvisioned() {
Malcolm Chen18837ff2017-10-25 17:05:41 -07002350 return getProvisionedBoolNoException(
2351 ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED);
Amit Mahajan24f7b162016-07-21 16:33:53 -07002352 }
2353
2354 private boolean isVtProvisioned() {
Malcolm Chen18837ff2017-10-25 17:05:41 -07002355 return getProvisionedBoolNoException(
2356 ImsConfig.ConfigConstants.LVC_SETTING_ENABLED);
Jack Yu643ffe42016-07-08 14:25:46 -07002357 }
2358
Malcolm Chen212ca652017-09-28 17:28:45 -07002359 private static String booleanToPropertyString(boolean bool) {
2360 return bool ? "1" : "0";
2361 }
2362
2363
Jack Yu2f102bd2015-12-28 15:31:48 -08002364 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2365 pw.println("ImsManager:");
2366 pw.println(" mPhoneId = " + mPhoneId);
2367 pw.println(" mConfigUpdated = " + mConfigUpdated);
Brad Ebinger172977a2018-01-16 09:36:56 -08002368 pw.println(" mImsServiceProxy = " + mMmTelFeatureConnection);
Amit Mahajan24f7b162016-07-21 16:33:53 -07002369 pw.println(" mDataEnabled = " + isDataEnabled());
Brad Ebinger479f52c2017-08-28 13:19:22 -07002370 pw.println(" ignoreDataEnabledChanged = " + getBooleanCarrierConfig(
Jack Yu57781852016-11-16 17:20:38 -08002371 CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS));
Jack Yu2f102bd2015-12-28 15:31:48 -08002372
Brad Ebinger479f52c2017-08-28 13:19:22 -07002373 pw.println(" isGbaValid = " + isGbaValid());
Jack Yu2f102bd2015-12-28 15:31:48 -08002374 pw.println(" isImsTurnOffAllowed = " + isImsTurnOffAllowed());
Brad Ebinger479f52c2017-08-28 13:19:22 -07002375 pw.println(" isNonTtyOrTtyOnVolteEnabled = " + isNonTtyOrTtyOnVolteEnabled());
Jack Yu2f102bd2015-12-28 15:31:48 -08002376
Brad Ebinger479f52c2017-08-28 13:19:22 -07002377 pw.println(" isVolteEnabledByPlatform = " + isVolteEnabledByPlatform());
2378 pw.println(" isVolteProvisionedOnDevice = " + isVolteProvisionedOnDevice());
Jack Yu2f102bd2015-12-28 15:31:48 -08002379 pw.println(" isEnhanced4gLteModeSettingEnabledByUser = " +
Brad Ebinger479f52c2017-08-28 13:19:22 -07002380 isEnhanced4gLteModeSettingEnabledByUser());
2381 pw.println(" isVtEnabledByPlatform = " + isVtEnabledByPlatform());
2382 pw.println(" isVtEnabledByUser = " + isVtEnabledByUser());
Jack Yu2f102bd2015-12-28 15:31:48 -08002383
Brad Ebinger479f52c2017-08-28 13:19:22 -07002384 pw.println(" isWfcEnabledByPlatform = " + isWfcEnabledByPlatform());
2385 pw.println(" isWfcEnabledByUser = " + isWfcEnabledByUser());
2386 pw.println(" getWfcMode = " + getWfcMode());
2387 pw.println(" isWfcRoamingEnabledByUser = " + isWfcRoamingEnabledByUser());
Jack Yu2f102bd2015-12-28 15:31:48 -08002388
Brad Ebinger479f52c2017-08-28 13:19:22 -07002389 pw.println(" isVtProvisionedOnDevice = " + isVtProvisionedOnDevice());
2390 pw.println(" isWfcProvisionedOnDevice = " + isWfcProvisionedOnDevice());
Jack Yu2f102bd2015-12-28 15:31:48 -08002391 pw.flush();
2392 }
Wink Savilleef36ef62014-06-11 08:39:38 -07002393}