blob: a77abcd6d458a1cdf25d56176567a717e22cfb1e [file] [log] [blame]
Wink Savilleef36ef62014-06-11 08:39:38 -07001/*
2 * Copyright (c) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.ims;
18
19import android.app.PendingIntent;
20import android.content.Context;
21import android.content.Intent;
Pavel Zhamaitsiak4de9cbb2016-02-11 17:21:05 -080022import android.net.Uri;
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -070023import android.os.AsyncTask;
Brad Ebingerbe6cb672017-08-25 14:55:00 -070024import android.os.Handler;
Wink Savilleef36ef62014-06-11 08:39:38 -070025import android.os.IBinder;
Brad Ebingerbe6cb672017-08-25 14:55:00 -070026import android.os.Looper;
Wink Savilleef36ef62014-06-11 08:39:38 -070027import android.os.Message;
Naveen Kalla525c3a22017-02-06 14:46:42 -080028import android.os.Parcel;
Jonathan Basseri2acea6f2015-07-01 15:00:38 -070029import android.os.PersistableBundle;
Wink Savilleef36ef62014-06-11 08:39:38 -070030import android.os.RemoteException;
31import android.os.ServiceManager;
Etan Cohenaf55a402014-09-04 22:34:41 -070032import android.os.SystemProperties;
Etan Cohen82f78122014-12-15 10:10:14 -080033import android.provider.Settings;
34import android.telecom.TelecomManager;
Junda Liue7663c02015-06-23 11:16:26 -070035import android.telephony.CarrierConfigManager;
Wink Savilleef36ef62014-06-11 08:39:38 -070036import android.telephony.Rlog;
Meng Wangbb98b9b2016-12-07 16:27:15 -080037import android.telephony.ServiceState;
Etan Cohen82f78122014-12-15 10:10:14 -080038import android.telephony.SubscriptionManager;
Etan Cohencfc784d2014-08-07 18:40:31 -070039import android.telephony.TelephonyManager;
Brad Ebinger16780ff2017-01-26 11:18:21 -080040import android.telephony.ims.ImsServiceProxy;
41import android.telephony.ims.ImsServiceProxyCompat;
42import android.telephony.ims.feature.ImsFeature;
Hall Liue511a202017-08-17 15:49:58 -070043import android.util.Log;
Wink Savilleef36ef62014-06-11 08:39:38 -070044
45import com.android.ims.internal.IImsCallSession;
Naveen Kalla525c3a22017-02-06 14:46:42 -080046import com.android.ims.internal.IImsConfig;
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.IImsRegistrationListener;
Brad Ebinger16780ff2017-01-26 11:18:21 -080050import com.android.ims.internal.IImsServiceController;
Wink Savilleef36ef62014-06-11 08:39:38 -070051import com.android.ims.internal.IImsUt;
52import com.android.ims.internal.ImsCallSession;
Brad Ebinger16780ff2017-01-26 11:18:21 -080053import com.android.internal.annotations.VisibleForTesting;
Brad Ebingerbe6cb672017-08-25 14:55:00 -070054import com.android.internal.telephony.ExponentialBackoff;
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -050055
Jack Yu2f102bd2015-12-28 15:31:48 -080056import java.io.FileDescriptor;
57import java.io.PrintWriter;
Naveen Kalla525c3a22017-02-06 14:46:42 -080058import java.util.ArrayList;
Etan Cohend7727462014-07-12 14:54:10 -070059import java.util.HashMap;
Naveen Kalla525c3a22017-02-06 14:46:42 -080060import java.util.concurrent.ConcurrentLinkedDeque;
Brad Ebinger16780ff2017-01-26 11:18:21 -080061import java.util.HashSet;
Brad Ebinger16780ff2017-01-26 11:18:21 -080062import java.util.Set;
Etan Cohend7727462014-07-12 14:54:10 -070063
Wink Savilleef36ef62014-06-11 08:39:38 -070064/**
65 * Provides APIs for IMS services, such as initiating IMS calls, and provides access to
66 * the operator's IMS network. This class is the starting point for any IMS actions.
67 * You can acquire an instance of it with {@link #getInstance getInstance()}.</p>
68 * <p>The APIs in this class allows you to:</p>
69 *
70 * @hide
71 */
72public class ImsManager {
Etan Cohen19604c02014-08-11 14:32:57 -070073
Etan Cohenaf55a402014-09-04 22:34:41 -070074 /*
75 * Debug flag to override configuration flag
76 */
Etan Cohenb651fa52014-10-22 10:51:29 -070077 public static final String PROPERTY_DBG_VOLTE_AVAIL_OVERRIDE = "persist.dbg.volte_avail_ovr";
78 public static final int PROPERTY_DBG_VOLTE_AVAIL_OVERRIDE_DEFAULT = 0;
Etan Cohenea2b5832014-10-23 18:50:35 -070079 public static final String PROPERTY_DBG_VT_AVAIL_OVERRIDE = "persist.dbg.vt_avail_ovr";
80 public static final int PROPERTY_DBG_VT_AVAIL_OVERRIDE_DEFAULT = 0;
Etan Cohena00c9192014-12-23 15:02:29 -080081 public static final String PROPERTY_DBG_WFC_AVAIL_OVERRIDE = "persist.dbg.wfc_avail_ovr";
82 public static final int PROPERTY_DBG_WFC_AVAIL_OVERRIDE_DEFAULT = 0;
Meng Wang9352c432016-06-08 14:22:20 -070083 public static final String PROPERTY_DBG_ALLOW_IMS_OFF_OVERRIDE = "persist.dbg.allow_ims_off";
84 public static final int PROPERTY_DBG_ALLOW_IMS_OFF_OVERRIDE_DEFAULT = 0;
Etan Cohenaf55a402014-09-04 22:34:41 -070085
Wink Savilleef36ef62014-06-11 08:39:38 -070086 /**
87 * For accessing the IMS related service.
88 * Internal use only.
89 * @hide
90 */
Etan Cohend7727462014-07-12 14:54:10 -070091 private static final String IMS_SERVICE = "ims";
Wink Savilleef36ef62014-06-11 08:39:38 -070092
93 /**
94 * The result code to be sent back with the incoming call {@link PendingIntent}.
95 * @see #open(PendingIntent, ImsConnectionStateListener)
96 */
97 public static final int INCOMING_CALL_RESULT_CODE = 101;
98
99 /**
100 * Key to retrieve the call ID from an incoming call intent.
101 * @see #open(PendingIntent, ImsConnectionStateListener)
102 */
103 public static final String EXTRA_CALL_ID = "android:imsCallID";
104
105 /**
106 * Action to broadcast when ImsService is up.
107 * Internal use only.
Brad Ebinger16780ff2017-01-26 11:18:21 -0800108 * @deprecated
Wink Savilleef36ef62014-06-11 08:39:38 -0700109 * @hide
110 */
111 public static final String ACTION_IMS_SERVICE_UP =
112 "com.android.ims.IMS_SERVICE_UP";
113
114 /**
115 * Action to broadcast when ImsService is down.
116 * Internal use only.
Brad Ebinger16780ff2017-01-26 11:18:21 -0800117 * @deprecated
Wink Savilleef36ef62014-06-11 08:39:38 -0700118 * @hide
119 */
120 public static final String ACTION_IMS_SERVICE_DOWN =
121 "com.android.ims.IMS_SERVICE_DOWN";
122
123 /**
Pavel Zhamaitsiak0c2f15c2015-03-12 15:37:54 -0700124 * Action to broadcast when ImsService registration fails.
125 * Internal use only.
126 * @hide
127 */
128 public static final String ACTION_IMS_REGISTRATION_ERROR =
129 "com.android.ims.REGISTRATION_ERROR";
130
131 /**
Etan Cohend7727462014-07-12 14:54:10 -0700132 * Part of the ACTION_IMS_SERVICE_UP or _DOWN intents.
Etan Cohenabbd7882014-09-26 22:35:35 -0700133 * A long value; the phone ID corresponding to the IMS service coming up or down.
Etan Cohend7727462014-07-12 14:54:10 -0700134 * Internal use only.
135 * @hide
136 */
Etan Cohenabbd7882014-09-26 22:35:35 -0700137 public static final String EXTRA_PHONE_ID = "android:phone_id";
Etan Cohend7727462014-07-12 14:54:10 -0700138
139 /**
Wink Savilleef36ef62014-06-11 08:39:38 -0700140 * Action for the incoming call intent for the Phone app.
141 * Internal use only.
142 * @hide
143 */
144 public static final String ACTION_IMS_INCOMING_CALL =
145 "com.android.ims.IMS_INCOMING_CALL";
146
147 /**
148 * Part of the ACTION_IMS_INCOMING_CALL intents.
149 * An integer value; service identifier obtained from {@link ImsManager#open}.
150 * Internal use only.
151 * @hide
152 */
153 public static final String EXTRA_SERVICE_ID = "android:imsServiceId";
154
155 /**
156 * Part of the ACTION_IMS_INCOMING_CALL intents.
157 * An boolean value; Flag to indicate that the incoming call is a normal call or call for USSD.
158 * The value "true" indicates that the incoming call is for USSD.
159 * Internal use only.
160 * @hide
161 */
162 public static final String EXTRA_USSD = "android:ussd";
163
Shriram Ganeshd3adfad2015-05-31 10:06:15 -0700164 /**
165 * Part of the ACTION_IMS_INCOMING_CALL intents.
166 * A boolean value; Flag to indicate whether the call is an unknown
167 * dialing call. Such calls are originated by sending commands (like
168 * AT commands) directly to modem without Android involvement.
169 * Even though they are not incoming calls, they are propagated
170 * to Phone app using same ACTION_IMS_INCOMING_CALL intent.
171 * Internal use only.
172 * @hide
173 */
Anju Mathapati9c033792015-06-16 16:33:16 -0700174 public static final String EXTRA_IS_UNKNOWN_CALL = "android:isUnknown";
Shriram Ganeshd3adfad2015-05-31 10:06:15 -0700175
Wink Savilleef36ef62014-06-11 08:39:38 -0700176 private static final String TAG = "ImsManager";
177 private static final boolean DBG = true;
178
Wink Saville1e5a38a2014-10-23 10:24:46 -0700179 private static HashMap<Integer, ImsManager> sImsManagerInstances =
180 new HashMap<Integer, ImsManager>();
Etan Cohend7727462014-07-12 14:54:10 -0700181
Wink Savilleef36ef62014-06-11 08:39:38 -0700182 private Context mContext;
Brad Ebinger16417b42017-03-07 13:48:50 -0800183 private CarrierConfigManager mConfigManager;
Etan Cohenabbd7882014-09-26 22:35:35 -0700184 private int mPhoneId;
Brad Ebinger16780ff2017-01-26 11:18:21 -0800185 private final boolean mConfigDynamicBind;
186 private ImsServiceProxyCompat mImsServiceProxy = null;
Wink Savilleef36ef62014-06-11 08:39:38 -0700187 private ImsServiceDeathRecipient mDeathRecipient = new ImsServiceDeathRecipient();
188 // Ut interface for the supplementary service configuration
189 private ImsUt mUt = null;
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -0500190 // Interface to get/set ims config items
191 private ImsConfig mConfig = null;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -0700192 private boolean mConfigUpdated = false;
Wink Savilleef36ef62014-06-11 08:39:38 -0700193
Pavel Zhamaitsiakf4b90322016-01-26 14:34:09 -0800194 private ImsConfigListener mImsConfigListener;
195
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -0700196 // ECBM interface
197 private ImsEcbm mEcbm = null;
198
Tyler Gunn4d128b62016-04-13 15:44:38 -0700199 private ImsMultiEndpoint mMultiEndpoint = null;
200
Brad Ebinger16780ff2017-01-26 11:18:21 -0800201 private Set<ImsServiceProxy.INotifyStatusChanged> mStatusCallbacks = new HashSet<>();
202
203 // Keep track of the ImsRegistrationListenerProxys that have been created so that we can
204 // remove them from the ImsService.
Brad Ebinger9a0280c2017-06-01 15:58:48 -0700205 private final Set<ImsConnectionStateListener> mRegistrationListeners = new HashSet<>();
206
207 private final ImsRegistrationListenerProxy mRegistrationListenerProxy =
208 new ImsRegistrationListenerProxy();
209
210 // When true, we have registered the mRegistrationListenerProxy with the ImsService. Don't do
211 // it again.
212 private boolean mHasRegisteredForProxy = false;
213 private final Object mHasRegisteredLock = new Object();
Brad Ebinger16780ff2017-01-26 11:18:21 -0800214
Amit Mahajan24f7b162016-07-21 16:33:53 -0700215 // SystemProperties used as cache
216 private static final String VOLTE_PROVISIONED_PROP = "net.lte.ims.volte.provisioned";
217 private static final String WFC_PROVISIONED_PROP = "net.lte.ims.wfc.provisioned";
218 private static final String VT_PROVISIONED_PROP = "net.lte.ims.vt.provisioned";
Jack Yu643ffe42016-07-08 14:25:46 -0700219 // Flag indicating data enabled or not. This flag should be in sync with
220 // DcTracker.isDataEnabled(). The flag will be set later during boot up.
Amit Mahajan24f7b162016-07-21 16:33:53 -0700221 private static final String DATA_ENABLED_PROP = "net.lte.ims.data.enabled";
222
223 public static final String TRUE = "true";
224 public static final String FALSE = "false";
Jack Yu643ffe42016-07-08 14:25:46 -0700225
Naveen Kalla525c3a22017-02-06 14:46:42 -0800226 // mRecentDisconnectReasons stores the last 16 disconnect reasons
227 private static final int MAX_RECENT_DISCONNECT_REASONS = 16;
228 private ConcurrentLinkedDeque<ImsReasonInfo> mRecentDisconnectReasons =
229 new ConcurrentLinkedDeque<>();
230
Brad Ebingerbe6cb672017-08-25 14:55:00 -0700231 // Exponential backoff for provisioning cache update. May be null for instances of ImsManager
232 // that are not on a thread supporting a looper.
233 private ExponentialBackoff mProvisionBackoff;
234 // Initial Provisioning check delay in ms
235 private static final long BACKOFF_INITIAL_DELAY_MS = 500;
236 // Max Provisioning check delay in ms (5 Minutes)
237 private static final long BACKOFF_MAX_DELAY_MS = 300000;
238 // Multiplier for exponential delay
239 private static final int BACKOFF_MULTIPLIER = 2;
240
241
Wink Savilleef36ef62014-06-11 08:39:38 -0700242 /**
243 * Gets a manager instance.
244 *
245 * @param context application context for creating the manager object
Etan Cohenabbd7882014-09-26 22:35:35 -0700246 * @param phoneId the phone ID for the IMS Service
247 * @return the manager instance corresponding to the phoneId
Wink Savilleef36ef62014-06-11 08:39:38 -0700248 */
Etan Cohenabbd7882014-09-26 22:35:35 -0700249 public static ImsManager getInstance(Context context, int phoneId) {
Etan Cohend7727462014-07-12 14:54:10 -0700250 synchronized (sImsManagerInstances) {
Naveen Kalla525c3a22017-02-06 14:46:42 -0800251 if (sImsManagerInstances.containsKey(phoneId)) {
Brad Ebingerff097922017-06-19 15:43:08 -0700252 ImsManager m = sImsManagerInstances.get(phoneId);
253 // May be null for some tests
254 if (m != null) {
255 m.connectIfServiceIsAvailable();
256 }
257 return m;
Naveen Kalla525c3a22017-02-06 14:46:42 -0800258 }
Wink Savilleef36ef62014-06-11 08:39:38 -0700259
Etan Cohenabbd7882014-09-26 22:35:35 -0700260 ImsManager mgr = new ImsManager(context, phoneId);
261 sImsManagerInstances.put(phoneId, mgr);
Etan Cohend7727462014-07-12 14:54:10 -0700262
263 return mgr;
264 }
Wink Savilleef36ef62014-06-11 08:39:38 -0700265 }
266
Etan Cohen45b5f312014-08-19 15:55:08 -0700267 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800268 * Returns the user configuration of Enhanced 4G LTE Mode setting.
269 *
270 * @deprecated Doesn't support MSIM devices. Use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700271 * {@link #isEnhanced4gLteModeSettingEnabledByUser()} instead.
Etan Cohen45b5f312014-08-19 15:55:08 -0700272 */
273 public static boolean isEnhanced4gLteModeSettingEnabledByUser(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700274 ImsManager mgr = ImsManager.getInstance(context,
275 SubscriptionManager.getDefaultVoicePhoneId());
276 if (mgr != null) {
277 return mgr.isEnhanced4gLteModeSettingEnabledByUser();
Sungmin Choi2f1af952016-02-01 17:15:35 +0900278 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700279 loge("isEnhanced4gLteModeSettingEnabledByUser: ImsManager null, returning default value.");
280 return false;
Etan Cohen45b5f312014-08-19 15:55:08 -0700281 }
282
283 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800284 * Returns the user configuration of Enhanced 4G LTE Mode setting for slot.
285 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700286 public boolean isEnhanced4gLteModeSettingEnabledByUser() {
Brad Ebinger16417b42017-03-07 13:48:50 -0800287 // If user can't edit Enhanced 4G LTE Mode, it assumes Enhanced 4G LTE Mode is always true.
288 // If user changes SIM from editable mode to uneditable mode, need to return true.
Brad Ebinger479f52c2017-08-28 13:19:22 -0700289 if (!getBooleanCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -0800290 CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL)) {
291 return true;
292 }
293 int enabled = android.provider.Settings.Global.getInt(
294 mContext.getContentResolver(),
295 android.provider.Settings.Global.ENHANCED_4G_MODE_ENABLED,
296 ImsConfig.FeatureValueConstants.ON);
297 return (enabled == 1);
298 }
299
300 /**
301 * Change persistent Enhanced 4G LTE Mode setting.
302 *
Brad Ebinger479f52c2017-08-28 13:19:22 -0700303 * @deprecated Doesn't support MSIM devices. Use {@link #setEnhanced4gLteModeSetting(boolean)}
Brad Ebinger16417b42017-03-07 13:48:50 -0800304 * instead.
Etan Cohen82f78122014-12-15 10:10:14 -0800305 */
306 public static void setEnhanced4gLteModeSetting(Context context, boolean enabled) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700307 ImsManager mgr = ImsManager.getInstance(context,
308 SubscriptionManager.getDefaultVoicePhoneId());
309 if (mgr != null) {
310 mgr.setEnhanced4gLteModeSetting(enabled);
Etan Cohen82f78122014-12-15 10:10:14 -0800311 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700312 loge("setEnhanced4gLteModeSetting: ImsManager null, value not set.");
Etan Cohen82f78122014-12-15 10:10:14 -0800313 }
314
315 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800316 * Change persistent Enhanced 4G LTE Mode setting. If the the option is not editable
317 * ({@link CarrierConfigManager#KEY_EDITABLE_ENHANCED_4G_LTE_BOOL} is false), this method will
318 * always set the setting to true.
319 *
320 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700321 public void setEnhanced4gLteModeSetting(boolean enabled) {
Brad Ebinger16417b42017-03-07 13:48:50 -0800322 // If false, we must always keep advanced 4G mode set to true (1).
Brad Ebinger479f52c2017-08-28 13:19:22 -0700323 int value = getBooleanCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -0800324 CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL) ? (enabled ? 1: 0) : 1;
325
326 try {
327 int prevSetting = android.provider.Settings.Global.getInt(mContext.getContentResolver(),
328 android.provider.Settings.Global.ENHANCED_4G_MODE_ENABLED);
329 if (prevSetting == value) {
330 // Don't trigger setAdvanced4GMode if the setting hasn't changed.
331 return;
332 }
333 } catch (Settings.SettingNotFoundException e) {
334 // Setting doesn't exist yet, so set it below.
335 }
336
337 android.provider.Settings.Global.putInt(mContext.getContentResolver(),
338 android.provider.Settings.Global.ENHANCED_4G_MODE_ENABLED, value);
Brad Ebinger479f52c2017-08-28 13:19:22 -0700339 if (isNonTtyOrTtyOnVolteEnabled()) {
Brad Ebinger16417b42017-03-07 13:48:50 -0800340 try {
341 setAdvanced4GMode(enabled);
342 } catch (ImsException ie) {
343 // do nothing
344 }
345 }
346 }
347
348 /**
Etan Cohen82f78122014-12-15 10:10:14 -0800349 * Indicates whether the call is non-TTY or if TTY - whether TTY on VoLTE is
350 * supported.
Brad Ebinger16417b42017-03-07 13:48:50 -0800351 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700352 * {@link #isNonTtyOrTtyOnVolteEnabled()} instead.
Etan Cohen82f78122014-12-15 10:10:14 -0800353 */
354 public static boolean isNonTtyOrTtyOnVolteEnabled(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700355 ImsManager mgr = ImsManager.getInstance(context,
356 SubscriptionManager.getDefaultVoicePhoneId());
357 if (mgr != null) {
358 return mgr.isNonTtyOrTtyOnVolteEnabled();
359 }
360 loge("isNonTtyOrTtyOnVolteEnabled: ImsManager null, returning default value.");
361 return false;
362 }
363
364 /**
365 * Indicates whether the call is non-TTY or if TTY - whether TTY on VoLTE is
366 * supported on a per slot basis.
367 */
368 public boolean isNonTtyOrTtyOnVolteEnabled() {
369 if (getBooleanCarrierConfig(
fionaxu5803ef02016-03-08 11:48:48 -0800370 CarrierConfigManager.KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL)) {
Etan Cohen82f78122014-12-15 10:10:14 -0800371 return true;
372 }
373
Brad Ebinger479f52c2017-08-28 13:19:22 -0700374 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
Hall Liue511a202017-08-17 15:49:58 -0700375 if (tm == null) {
376 Log.w(TAG, "isNonTtyOrTtyOnVolteEnabled: telecom not available");
377 return true;
378 }
379 return tm.getCurrentTtyMode() == TelecomManager.TTY_MODE_OFF;
Etan Cohen82f78122014-12-15 10:10:14 -0800380 }
381
382 /**
Etan Cohenea2b5832014-10-23 18:50:35 -0700383 * Returns a platform configuration for VoLTE which may override the user setting.
Brad Ebinger16417b42017-03-07 13:48:50 -0800384 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700385 * {@link #isVolteEnabledByPlatform()} instead.
Etan Cohen45b5f312014-08-19 15:55:08 -0700386 */
Etan Cohenea2b5832014-10-23 18:50:35 -0700387 public static boolean isVolteEnabledByPlatform(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700388 ImsManager mgr = ImsManager.getInstance(context,
389 SubscriptionManager.getDefaultVoicePhoneId());
390 if (mgr != null) {
391 return mgr.isVolteEnabledByPlatform();
Etan Cohenaf55a402014-09-04 22:34:41 -0700392 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700393 loge("isVolteEnabledByPlatform: ImsManager null, returning default value.");
394 return false;
Etan Cohenb5388a32014-11-26 11:57:47 -0800395 }
396
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -0700397 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800398 * Returns a platform configuration for VoLTE which may override the user setting on a per Slot
399 * basis.
400 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700401 public boolean isVolteEnabledByPlatform() {
Brad Ebinger16417b42017-03-07 13:48:50 -0800402 if (SystemProperties.getInt(PROPERTY_DBG_VOLTE_AVAIL_OVERRIDE,
403 PROPERTY_DBG_VOLTE_AVAIL_OVERRIDE_DEFAULT) == 1) {
404 return true;
405 }
406
407 return mContext.getResources().getBoolean(
408 com.android.internal.R.bool.config_device_volte_available)
Brad Ebinger479f52c2017-08-28 13:19:22 -0700409 && getBooleanCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -0800410 CarrierConfigManager.KEY_CARRIER_VOLTE_AVAILABLE_BOOL)
Brad Ebinger479f52c2017-08-28 13:19:22 -0700411 && isGbaValid();
Brad Ebinger16417b42017-03-07 13:48:50 -0800412 }
413
414 /**
415 * Indicates whether VoLTE is provisioned on device.
416 *
417 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700418 * {@link #isVolteProvisionedOnDevice()} instead.
Etan Cohenb5388a32014-11-26 11:57:47 -0800419 */
420 public static boolean isVolteProvisionedOnDevice(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700421 ImsManager mgr = ImsManager.getInstance(context,
422 SubscriptionManager.getDefaultVoicePhoneId());
423 if (mgr != null) {
424 return mgr.isVolteProvisionedOnDevice();
Etan Cohenb5388a32014-11-26 11:57:47 -0800425 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700426 loge("isVolteProvisionedOnDevice: ImsManager null, returning default value.");
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -0700427 return true;
428 }
429
430 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800431 * Indicates whether VoLTE is provisioned on this slot.
432 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700433 public boolean isVolteProvisionedOnDevice() {
434 if (getBooleanCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -0800435 CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL)) {
436 return isVolteProvisioned();
437 }
438
439 return true;
440 }
441
442 /**
Meng Wang54fd41a2017-04-12 11:44:47 -0700443 * Indicates whether VoWifi is provisioned on device.
444 *
445 * When CarrierConfig KEY_CARRIER_VOLTE_OVERRIDE_WFC_PROVISIONING_BOOL is true, and VoLTE is not
446 * provisioned on device, this method returns false.
Brad Ebinger16417b42017-03-07 13:48:50 -0800447 *
448 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700449 * {@link #isWfcProvisionedOnDevice()} instead.
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -0700450 */
451 public static boolean isWfcProvisionedOnDevice(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700452 ImsManager mgr = ImsManager.getInstance(context,
453 SubscriptionManager.getDefaultVoicePhoneId());
454 if (mgr != null) {
455 return mgr.isWfcProvisionedOnDevice();
Meng Wang54fd41a2017-04-12 11:44:47 -0700456 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700457 loge("isWfcProvisionedOnDevice: ImsManager null, returning default value.");
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -0700458 return true;
459 }
460
461 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800462 * Indicates whether VoWifi is provisioned on slot.
Meng Wang54fd41a2017-04-12 11:44:47 -0700463 *
464 * When CarrierConfig KEY_CARRIER_VOLTE_OVERRIDE_WFC_PROVISIONING_BOOL is true, and VoLTE is not
465 * provisioned on device, this method returns false.
Brad Ebinger16417b42017-03-07 13:48:50 -0800466 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700467 public boolean isWfcProvisionedOnDevice() {
468 if (getBooleanCarrierConfig(
Meng Wang54fd41a2017-04-12 11:44:47 -0700469 CarrierConfigManager.KEY_CARRIER_VOLTE_OVERRIDE_WFC_PROVISIONING_BOOL)) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700470 if (!isVolteProvisionedOnDevice()) {
Meng Wang54fd41a2017-04-12 11:44:47 -0700471 return false;
472 }
473 }
474
Brad Ebinger479f52c2017-08-28 13:19:22 -0700475 if (getBooleanCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -0800476 CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL)) {
Meng Wang54fd41a2017-04-12 11:44:47 -0700477 return isWfcProvisioned();
Brad Ebinger16417b42017-03-07 13:48:50 -0800478 }
479
480 return true;
481 }
482
483 /**
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -0700484 * Indicates whether VT is provisioned on device
Brad Ebinger16417b42017-03-07 13:48:50 -0800485 *
486 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700487 * {@link #isVtProvisionedOnDevice()} instead.
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -0700488 */
489 public static boolean isVtProvisionedOnDevice(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700490 ImsManager mgr = ImsManager.getInstance(context,
491 SubscriptionManager.getDefaultVoicePhoneId());
492 if (mgr != null) {
493 return mgr.isVtProvisionedOnDevice();
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -0700494 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700495 loge("isVtProvisionedOnDevice: ImsManager null, returning default value.");
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -0700496 return true;
Etan Cohenb651fa52014-10-22 10:51:29 -0700497 }
498
Etan Cohenea2b5832014-10-23 18:50:35 -0700499 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800500 * Indicates whether VT is provisioned on slot.
501 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700502 public boolean isVtProvisionedOnDevice() {
503 if (getBooleanCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -0800504 CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL)) {
505 return isVtProvisioned();
506 }
507
508 return true;
509 }
510
511 /**
Etan Cohenea2b5832014-10-23 18:50:35 -0700512 * Returns a platform configuration for VT which may override the user setting.
513 *
514 * Note: VT presumes that VoLTE is enabled (these are configuration settings
515 * which must be done correctly).
Brad Ebinger16417b42017-03-07 13:48:50 -0800516 *
517 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700518 * {@link #isVtEnabledByPlatform()} instead.
Etan Cohenea2b5832014-10-23 18:50:35 -0700519 */
Etan Cohenb651fa52014-10-22 10:51:29 -0700520 public static boolean isVtEnabledByPlatform(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700521 ImsManager mgr = ImsManager.getInstance(context,
522 SubscriptionManager.getDefaultVoicePhoneId());
523 if (mgr != null) {
524 return mgr.isVtEnabledByPlatform();
Etan Cohenea2b5832014-10-23 18:50:35 -0700525 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700526 loge("isVtEnabledByPlatform: ImsManager null, returning default value.");
527 return false;
Etan Cohen45b5f312014-08-19 15:55:08 -0700528 }
529
Etan Cohena00c9192014-12-23 15:02:29 -0800530 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800531 * Returns a platform configuration for VT which may override the user setting.
532 *
533 * Note: VT presumes that VoLTE is enabled (these are configuration settings
534 * which must be done correctly).
535 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700536 public boolean isVtEnabledByPlatform() {
Brad Ebinger16417b42017-03-07 13:48:50 -0800537 if (SystemProperties.getInt(PROPERTY_DBG_VT_AVAIL_OVERRIDE,
538 PROPERTY_DBG_VT_AVAIL_OVERRIDE_DEFAULT) == 1) {
539 return true;
540 }
541
542 return mContext.getResources().getBoolean(
543 com.android.internal.R.bool.config_device_vt_available) &&
Brad Ebinger479f52c2017-08-28 13:19:22 -0700544 getBooleanCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -0800545 CarrierConfigManager.KEY_CARRIER_VT_AVAILABLE_BOOL) &&
Brad Ebinger479f52c2017-08-28 13:19:22 -0700546 isGbaValid();
Brad Ebinger16417b42017-03-07 13:48:50 -0800547 }
548
549 /**
Etan Cohena7d32e82015-05-04 18:02:09 -0700550 * Returns the user configuration of VT setting
Brad Ebinger16417b42017-03-07 13:48:50 -0800551 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700552 * {@link #isVtEnabledByUser()} instead.
Etan Cohena7d32e82015-05-04 18:02:09 -0700553 */
554 public static boolean isVtEnabledByUser(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700555 ImsManager mgr = ImsManager.getInstance(context,
556 SubscriptionManager.getDefaultVoicePhoneId());
557 if (mgr != null) {
558 return mgr.isVtEnabledByUser();
559 }
560 loge("isVtEnabledByUser: ImsManager null, returning default value.");
561 return false;
Etan Cohena7d32e82015-05-04 18:02:09 -0700562 }
563
564 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800565 * Returns the user configuration of VT setting per slot.
566 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700567 public boolean isVtEnabledByUser() {
Brad Ebinger16417b42017-03-07 13:48:50 -0800568 int enabled = android.provider.Settings.Global.getInt(mContext.getContentResolver(),
569 android.provider.Settings.Global.VT_IMS_ENABLED,
570 ImsConfig.FeatureValueConstants.ON);
571 return (enabled == 1);
572 }
573
574 /**
Etan Cohena7d32e82015-05-04 18:02:09 -0700575 * Change persistent VT enabled setting
Brad Ebinger16417b42017-03-07 13:48:50 -0800576 *
Brad Ebinger479f52c2017-08-28 13:19:22 -0700577 * @deprecated Does not support MSIM devices. Please use {@link #setVtSetting(boolean)} instead.
Etan Cohena7d32e82015-05-04 18:02:09 -0700578 */
579 public static void setVtSetting(Context context, boolean enabled) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700580 ImsManager mgr = ImsManager.getInstance(context,
Etan Cohena7d32e82015-05-04 18:02:09 -0700581 SubscriptionManager.getDefaultVoicePhoneId());
Brad Ebinger479f52c2017-08-28 13:19:22 -0700582 if (mgr != null) {
583 mgr.setVtSetting(enabled);
Etan Cohena7d32e82015-05-04 18:02:09 -0700584 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700585 loge("setVtSetting: ImsManager null, can not set value.");
Etan Cohena7d32e82015-05-04 18:02:09 -0700586 }
587
Brad Ebinger16417b42017-03-07 13:48:50 -0800588 /**
589 * Change persistent VT enabled setting for slot.
590 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700591 public void setVtSetting(boolean enabled) {
Brad Ebinger16417b42017-03-07 13:48:50 -0800592 int value = enabled ? 1 : 0;
593 android.provider.Settings.Global.putInt(mContext.getContentResolver(),
594 android.provider.Settings.Global.VT_IMS_ENABLED, value);
595
596 try {
597 ImsConfig config = getConfigInterface();
598 config.setFeatureValue(ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_LTE,
599 TelephonyManager.NETWORK_TYPE_LTE,
600 enabled ? ImsConfig.FeatureValueConstants.ON
601 : ImsConfig.FeatureValueConstants.OFF,
602 mImsConfigListener);
603
604 if (enabled) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700605 log("setVtSetting(b) : turnOnIms");
Brad Ebinger16417b42017-03-07 13:48:50 -0800606 turnOnIms();
Brad Ebinger479f52c2017-08-28 13:19:22 -0700607 } else if (isVolteEnabledByPlatform()
608 && (!isVolteEnabledByPlatform()
609 || !isEnhanced4gLteModeSettingEnabledByUser())) {
610 log("setVtSetting(b) : imsServiceAllowTurnOff -> turnOffIms");
Brad Ebinger16417b42017-03-07 13:48:50 -0800611 turnOffIms();
612 }
613 } catch (ImsException e) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700614 loge("setVtSetting(b): ", e);
Brad Ebinger16417b42017-03-07 13:48:50 -0800615 }
616 }
617
618 /**
Meng Wang9352c432016-06-08 14:22:20 -0700619 * Returns whether turning off ims is allowed by platform.
620 * The platform property may override the carrier config.
Brad Ebinger16417b42017-03-07 13:48:50 -0800621 *
622 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700623 * {@link #isTurnOffImsAllowedByPlatform()} instead.
Meng Wang9352c432016-06-08 14:22:20 -0700624 */
625 private static boolean isTurnOffImsAllowedByPlatform(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700626 ImsManager mgr = ImsManager.getInstance(context,
627 SubscriptionManager.getDefaultVoicePhoneId());
628 if (mgr != null) {
629 return mgr.isTurnOffImsAllowedByPlatform();
Meng Wang9352c432016-06-08 14:22:20 -0700630 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700631 loge("isTurnOffImsAllowedByPlatform: ImsManager null, returning default value.");
632 return true;
Meng Wang9352c432016-06-08 14:22:20 -0700633 }
634
Etan Cohena7d32e82015-05-04 18:02:09 -0700635 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800636 * Returns whether turning off ims is allowed by platform.
637 * The platform property may override the carrier config.
638 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700639 private boolean isTurnOffImsAllowedByPlatform() {
Brad Ebinger16417b42017-03-07 13:48:50 -0800640 if (SystemProperties.getInt(PROPERTY_DBG_ALLOW_IMS_OFF_OVERRIDE,
641 PROPERTY_DBG_ALLOW_IMS_OFF_OVERRIDE_DEFAULT) == 1) {
642 return true;
643 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700644 return getBooleanCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -0800645 CarrierConfigManager.KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL);
646 }
647
648 /**
Etan Cohena00c9192014-12-23 15:02:29 -0800649 * Returns the user configuration of WFC setting
Brad Ebinger16417b42017-03-07 13:48:50 -0800650 *
651 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700652 * {@link #isWfcEnabledByUser()} instead.
Etan Cohena00c9192014-12-23 15:02:29 -0800653 */
654 public static boolean isWfcEnabledByUser(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700655 ImsManager mgr = ImsManager.getInstance(context,
656 SubscriptionManager.getDefaultVoicePhoneId());
657 if (mgr != null) {
658 return mgr.isWfcEnabledByUser();
659 }
660 loge("isWfcEnabledByUser: ImsManager null, returning default value.");
661 return true;
Etan Cohena00c9192014-12-23 15:02:29 -0800662 }
663
664 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800665 * Returns the user configuration of WFC setting for slot.
666 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700667 public boolean isWfcEnabledByUser() {
Brad Ebinger16417b42017-03-07 13:48:50 -0800668 int enabled = android.provider.Settings.Global.getInt(mContext.getContentResolver(),
669 android.provider.Settings.Global.WFC_IMS_ENABLED,
Brad Ebinger479f52c2017-08-28 13:19:22 -0700670 getBooleanCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -0800671 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL) ?
672 ImsConfig.FeatureValueConstants.ON : ImsConfig.FeatureValueConstants.OFF);
673 return enabled == 1;
674 }
675
676 /**
677 * Change persistent WFC enabled setting.
678 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700679 * {@link #setWfcSetting} instead.
Etan Cohena00c9192014-12-23 15:02:29 -0800680 */
681 public static void setWfcSetting(Context context, boolean enabled) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700682 ImsManager mgr = ImsManager.getInstance(context,
Etan Cohena00c9192014-12-23 15:02:29 -0800683 SubscriptionManager.getDefaultVoicePhoneId());
Brad Ebinger479f52c2017-08-28 13:19:22 -0700684 if (mgr != null) {
685 mgr.setWfcSetting(enabled);
Etan Cohena00c9192014-12-23 15:02:29 -0800686 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700687 loge("setWfcSetting: ImsManager null, can not set value.");
Etan Cohena00c9192014-12-23 15:02:29 -0800688 }
689
690 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800691 * Change persistent WFC enabled setting for slot.
692 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700693 public void setWfcSetting(boolean enabled) {
Brad Ebinger16417b42017-03-07 13:48:50 -0800694 int value = enabled ? 1 : 0;
695 android.provider.Settings.Global.putInt(mContext.getContentResolver(),
696 android.provider.Settings.Global.WFC_IMS_ENABLED, value);
697
Brad Ebinger479f52c2017-08-28 13:19:22 -0700698 setWfcNonPersistent(enabled, getWfcMode());
Meng Wang51c09072017-03-27 10:47:45 -0700699 }
700
701 /**
702 * Non-persistently change WFC enabled setting and WFC mode for slot
703 *
704 * @param wfcMode The WFC preference if WFC is enabled
705 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700706 public void setWfcNonPersistent(boolean enabled, int wfcMode) {
Meng Wang51c09072017-03-27 10:47:45 -0700707 int imsFeatureValue =
708 enabled ? ImsConfig.FeatureValueConstants.ON : ImsConfig.FeatureValueConstants.OFF;
709 // Force IMS to register over LTE when turning off WFC
710 int imsWfcModeFeatureValue =
711 enabled ? wfcMode : ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED;
712
Brad Ebinger16417b42017-03-07 13:48:50 -0800713 try {
714 ImsConfig config = getConfigInterface();
715 config.setFeatureValue(ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_WIFI,
716 TelephonyManager.NETWORK_TYPE_IWLAN,
Meng Wang51c09072017-03-27 10:47:45 -0700717 imsFeatureValue,
Brad Ebinger16417b42017-03-07 13:48:50 -0800718 mImsConfigListener);
719
720 if (enabled) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700721 log("setWfcSetting() : turnOnIms");
Brad Ebinger16417b42017-03-07 13:48:50 -0800722 turnOnIms();
Brad Ebinger479f52c2017-08-28 13:19:22 -0700723 } else if (isTurnOffImsAllowedByPlatform()
724 && (!isVolteEnabledByPlatform()
725 || !isEnhanced4gLteModeSettingEnabledByUser())) {
726 log("setWfcSetting() : imsServiceAllowTurnOff -> turnOffIms");
Brad Ebinger16417b42017-03-07 13:48:50 -0800727 turnOffIms();
728 }
729
Brad Ebinger479f52c2017-08-28 13:19:22 -0700730 setWfcModeInternal(imsWfcModeFeatureValue);
Brad Ebinger16417b42017-03-07 13:48:50 -0800731 } catch (ImsException e) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700732 loge("setWfcSetting(): ", e);
Brad Ebinger16417b42017-03-07 13:48:50 -0800733 }
734 }
735
736 /**
737 * Returns the user configuration of WFC preference setting.
738 *
Brad Ebinger479f52c2017-08-28 13:19:22 -0700739 * @deprecated Doesn't support MSIM devices. Use {@link #getWfcMode()} instead.
Etan Cohena00c9192014-12-23 15:02:29 -0800740 */
741 public static int getWfcMode(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700742 ImsManager mgr = ImsManager.getInstance(context,
743 SubscriptionManager.getDefaultVoicePhoneId());
744 if (mgr != null) {
745 return mgr.getWfcMode();
746 }
747 loge("getWfcMode: ImsManager null, returning default value.");
748 return ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY;
Etan Cohena00c9192014-12-23 15:02:29 -0800749 }
750
751 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800752 * Returns the user configuration of WFC preference setting
753 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700754 public int getWfcMode() {
Brad Ebinger16417b42017-03-07 13:48:50 -0800755 int setting = android.provider.Settings.Global.getInt(mContext.getContentResolver(),
Brad Ebinger479f52c2017-08-28 13:19:22 -0700756 android.provider.Settings.Global.WFC_IMS_MODE, getIntCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -0800757 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT));
758 if (DBG) log("getWfcMode - setting=" + setting);
759 return setting;
760 }
761
762 /**
763 * Change persistent WFC preference setting.
764 *
Brad Ebinger479f52c2017-08-28 13:19:22 -0700765 * @deprecated Doesn't support MSIM devices. Use {@link #setWfcMode(int)} instead.
Etan Cohena00c9192014-12-23 15:02:29 -0800766 */
767 public static void setWfcMode(Context context, int wfcMode) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700768 ImsManager mgr = ImsManager.getInstance(context,
769 SubscriptionManager.getDefaultVoicePhoneId());
770 if (mgr != null) {
771 mgr.setWfcMode(wfcMode);
772 }
773 loge("setWfcMode: ImsManager null, can not set value.");
Pavel Zhamaitsiak9e6eca22015-03-16 15:30:53 -0700774 }
775
Meng Wang37477012016-09-20 09:59:56 -0700776 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800777 * Change persistent WFC preference setting for slot.
778 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700779 public void setWfcMode(int wfcMode) {
780 if (DBG) log("setWfcMode(i) - setting=" + wfcMode);
Brad Ebinger16417b42017-03-07 13:48:50 -0800781 android.provider.Settings.Global.putInt(mContext.getContentResolver(),
782 android.provider.Settings.Global.WFC_IMS_MODE, wfcMode);
783
Brad Ebinger479f52c2017-08-28 13:19:22 -0700784 setWfcModeInternal(wfcMode);
Brad Ebinger16417b42017-03-07 13:48:50 -0800785 }
786
787 /**
Suresh Koleti76491082017-04-21 18:39:50 +0530788 * Changes the WFC mode to its default value for Carriers with non-editable WFC settings.
789 */
790 private void updateDefaultWfcMode() {
791 if (DBG) log("updateDefaultWfcMode");
Brad Ebinger479f52c2017-08-28 13:19:22 -0700792 if (!getBooleanCarrierConfig(CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL)) {
793 setWfcMode(getIntCarrierConfig(
Suresh Koleti76491082017-04-21 18:39:50 +0530794 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT));
795 }
796 }
797
798 /**
Meng Wang37477012016-09-20 09:59:56 -0700799 * Returns the user configuration of WFC preference setting
800 *
801 * @param roaming {@code false} for home network setting, {@code true} for roaming setting
Brad Ebinger16417b42017-03-07 13:48:50 -0800802 *
Brad Ebinger479f52c2017-08-28 13:19:22 -0700803 * @deprecated Doesn't support MSIM devices. Use {@link #getWfcMode(boolean)} instead.
Meng Wang37477012016-09-20 09:59:56 -0700804 */
805 public static int getWfcMode(Context context, boolean roaming) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700806 ImsManager mgr = ImsManager.getInstance(context,
807 SubscriptionManager.getDefaultVoicePhoneId());
808 if (mgr != null) {
809 return mgr.getWfcMode(roaming);
Meng Wang37477012016-09-20 09:59:56 -0700810 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700811 loge("getWfcMode: ImsManager null, returning default value.");
812 return ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY;
Meng Wang37477012016-09-20 09:59:56 -0700813 }
814
815 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800816 * Returns the user configuration of WFC preference setting for slot
817 *
818 * @param roaming {@code false} for home network setting, {@code true} for roaming setting
819 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700820 public int getWfcMode(boolean roaming) {
Brad Ebinger16417b42017-03-07 13:48:50 -0800821 int setting = 0;
822 if (!roaming) {
823 setting = android.provider.Settings.Global.getInt(mContext.getContentResolver(),
Brad Ebinger479f52c2017-08-28 13:19:22 -0700824 android.provider.Settings.Global.WFC_IMS_MODE, getIntCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -0800825 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT));
Brad Ebinger479f52c2017-08-28 13:19:22 -0700826 if (DBG) log("getWfcMode - setting=" + setting);
Brad Ebinger16417b42017-03-07 13:48:50 -0800827 } else {
828 setting = android.provider.Settings.Global.getInt(mContext.getContentResolver(),
829 android.provider.Settings.Global.WFC_IMS_ROAMING_MODE,
Brad Ebinger479f52c2017-08-28 13:19:22 -0700830 getIntCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -0800831 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_MODE_INT));
Brad Ebinger479f52c2017-08-28 13:19:22 -0700832 if (DBG) log("getWfcMode (roaming) - setting=" + setting);
Brad Ebinger16417b42017-03-07 13:48:50 -0800833 }
834 return setting;
835 }
836
837 /**
Meng Wang37477012016-09-20 09:59:56 -0700838 * Change persistent WFC preference setting
839 *
840 * @param roaming {@code false} for home network setting, {@code true} for roaming setting
Brad Ebinger16417b42017-03-07 13:48:50 -0800841 *
Brad Ebinger479f52c2017-08-28 13:19:22 -0700842 * @deprecated Doesn't support MSIM devices. Please use {@link #setWfcMode(int, boolean)}
843 * instead.
Meng Wang37477012016-09-20 09:59:56 -0700844 */
845 public static void setWfcMode(Context context, int wfcMode, boolean roaming) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700846 ImsManager mgr = ImsManager.getInstance(context,
847 SubscriptionManager.getDefaultVoicePhoneId());
848 if (mgr != null) {
849 mgr.setWfcMode(wfcMode, roaming);
Meng Wang37477012016-09-20 09:59:56 -0700850 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700851 loge("setWfcMode: ImsManager null, can not set value.");
Meng Wang37477012016-09-20 09:59:56 -0700852 }
853
Brad Ebinger16417b42017-03-07 13:48:50 -0800854 /**
855 * Change persistent WFC preference setting
856 *
857 * @param roaming {@code false} for home network setting, {@code true} for roaming setting
858 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700859 public void setWfcMode(int wfcMode, boolean roaming) {
Brad Ebinger16417b42017-03-07 13:48:50 -0800860 if (!roaming) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700861 if (DBG) log("setWfcMode(i,b) - setting=" + wfcMode);
Brad Ebinger16417b42017-03-07 13:48:50 -0800862 android.provider.Settings.Global.putInt(mContext.getContentResolver(),
863 android.provider.Settings.Global.WFC_IMS_MODE, wfcMode);
864 } else {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700865 if (DBG) log("setWfcMode(i,b) (roaming) - setting=" + wfcMode);
Brad Ebinger16417b42017-03-07 13:48:50 -0800866 android.provider.Settings.Global.putInt(mContext.getContentResolver(),
867 android.provider.Settings.Global.WFC_IMS_ROAMING_MODE, wfcMode);
868 }
869
Brad Ebinger479f52c2017-08-28 13:19:22 -0700870
871 TelephonyManager tm = (TelephonyManager)
872 mContext.getSystemService(Context.TELEPHONY_SERVICE);
873 if (roaming == tm.isNetworkRoaming(getSubId())) {
874 setWfcModeInternal(wfcMode);
875 }
876 }
877
878 private int getSubId() {
Brad Ebinger16417b42017-03-07 13:48:50 -0800879 int[] subIds = SubscriptionManager.getSubId(mPhoneId);
880 int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
881 if (subIds != null && subIds.length >= 1) {
882 subId = subIds[0];
883 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700884 return subId;
Brad Ebinger16417b42017-03-07 13:48:50 -0800885 }
886
Pavel Zhamaitsiak9e6eca22015-03-16 15:30:53 -0700887 private static void setWfcModeInternal(Context context, int wfcMode) {
Etan Cohena00c9192014-12-23 15:02:29 -0800888 final ImsManager imsManager = ImsManager.getInstance(context,
889 SubscriptionManager.getDefaultVoicePhoneId());
890 if (imsManager != null) {
891 final int value = wfcMode;
Pavel Zhamaitsiak47aeacf2016-03-30 18:54:55 -0700892 Thread thread = new Thread(new Runnable() {
Etan Cohena00c9192014-12-23 15:02:29 -0800893 public void run() {
894 try {
895 imsManager.getConfigInterface().setProvisionedValue(
896 ImsConfig.ConfigConstants.VOICE_OVER_WIFI_MODE,
897 value);
898 } catch (ImsException e) {
899 // do nothing
900 }
901 }
902 });
Pavel Zhamaitsiak47aeacf2016-03-30 18:54:55 -0700903 thread.start();
Etan Cohena00c9192014-12-23 15:02:29 -0800904 }
905 }
906
Brad Ebinger479f52c2017-08-28 13:19:22 -0700907 private void setWfcModeInternal(int wfcMode) {
Brad Ebinger16417b42017-03-07 13:48:50 -0800908 final int value = wfcMode;
909 Thread thread = new Thread(() -> {
910 try {
911 getConfigInterface().setProvisionedValue(
912 ImsConfig.ConfigConstants.VOICE_OVER_WIFI_MODE,
913 value);
914 } catch (ImsException e) {
915 // do nothing
916 }
917 });
918 thread.start();
919 }
920
Etan Cohena00c9192014-12-23 15:02:29 -0800921 /**
922 * Returns the user configuration of WFC roaming setting
Brad Ebinger16417b42017-03-07 13:48:50 -0800923 *
924 * @deprecated Does not support MSIM devices. Please use
Brad Ebinger479f52c2017-08-28 13:19:22 -0700925 * {@link #isWfcRoamingEnabledByUser()} instead.
Etan Cohena00c9192014-12-23 15:02:29 -0800926 */
927 public static boolean isWfcRoamingEnabledByUser(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700928 ImsManager mgr = ImsManager.getInstance(context,
929 SubscriptionManager.getDefaultVoicePhoneId());
930 if (mgr != null) {
931 return mgr.isWfcRoamingEnabledByUser();
932 }
933 loge("isWfcRoamingEnabledByUser: ImsManager null, returning default value.");
934 return false;
Etan Cohena00c9192014-12-23 15:02:29 -0800935 }
936
937 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800938 * Returns the user configuration of WFC roaming setting for slot
939 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700940 public boolean isWfcRoamingEnabledByUser() {
Brad Ebinger16417b42017-03-07 13:48:50 -0800941 int enabled = android.provider.Settings.Global.getInt(mContext.getContentResolver(),
942 android.provider.Settings.Global.WFC_IMS_ROAMING_ENABLED,
Brad Ebinger479f52c2017-08-28 13:19:22 -0700943 getBooleanCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -0800944 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_ENABLED_BOOL) ?
945 ImsConfig.FeatureValueConstants.ON : ImsConfig.FeatureValueConstants.OFF);
946 return (enabled == 1);
947 }
948
949 /**
Etan Cohena00c9192014-12-23 15:02:29 -0800950 * Change persistent WFC roaming enabled setting
951 */
952 public static void setWfcRoamingSetting(Context context, boolean enabled) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700953 ImsManager mgr = ImsManager.getInstance(context,
Etan Cohena00c9192014-12-23 15:02:29 -0800954 SubscriptionManager.getDefaultVoicePhoneId());
Brad Ebinger479f52c2017-08-28 13:19:22 -0700955 if (mgr != null) {
956 mgr.setWfcRoamingSetting(enabled);
Etan Cohena00c9192014-12-23 15:02:29 -0800957 }
Brad Ebinger479f52c2017-08-28 13:19:22 -0700958 loge("setWfcRoamingSetting: ImsManager null, value not set.");
Etan Cohena00c9192014-12-23 15:02:29 -0800959 }
960
961 /**
Brad Ebinger16417b42017-03-07 13:48:50 -0800962 * Change persistent WFC roaming enabled setting
963 */
Brad Ebinger479f52c2017-08-28 13:19:22 -0700964 public void setWfcRoamingSetting(boolean enabled) {
Brad Ebinger16417b42017-03-07 13:48:50 -0800965 android.provider.Settings.Global.putInt(mContext.getContentResolver(),
966 android.provider.Settings.Global.WFC_IMS_ROAMING_ENABLED,
967 enabled ? ImsConfig.FeatureValueConstants.ON
968 : ImsConfig.FeatureValueConstants.OFF);
969
970 setWfcRoamingSettingInternal(enabled);
971 }
972
973 private void setWfcRoamingSettingInternal(boolean enabled) {
974 final int value = enabled
975 ? ImsConfig.FeatureValueConstants.ON
976 : ImsConfig.FeatureValueConstants.OFF;
977 Thread thread = new Thread(() -> {
978 try {
979 getConfigInterface().setProvisionedValue(
980 ImsConfig.ConfigConstants.VOICE_OVER_WIFI_ROAMING,
981 value);
982 } catch (ImsException e) {
983 // do nothing
984 }
985 });
986 thread.start();
987 }
988
989 /**
Etan Cohena00c9192014-12-23 15:02:29 -0800990 * Returns a platform configuration for WFC which may override the user
991 * setting. Note: WFC presumes that VoLTE is enabled (these are
992 * configuration settings which must be done correctly).
Brad Ebinger16417b42017-03-07 13:48:50 -0800993 *
Brad Ebinger479f52c2017-08-28 13:19:22 -0700994 * @deprecated Doesn't work for MSIM devices. Use {@link #isWfcEnabledByPlatform()}
Brad Ebinger16417b42017-03-07 13:48:50 -0800995 * instead.
Etan Cohena00c9192014-12-23 15:02:29 -0800996 */
997 public static boolean isWfcEnabledByPlatform(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -0700998 ImsManager mgr = ImsManager.getInstance(context,
999 SubscriptionManager.getDefaultVoicePhoneId());
1000 if (mgr != null) {
1001 return mgr.isWfcEnabledByPlatform();
Etan Cohena00c9192014-12-23 15:02:29 -08001002 }
Brad Ebinger479f52c2017-08-28 13:19:22 -07001003 loge("isWfcEnabledByPlatform: ImsManager null, returning default value.");
1004 return false;
Pavel Zhamaitsiak57911d12015-10-20 14:26:34 -07001005 }
1006
1007 /**
Brad Ebinger16417b42017-03-07 13:48:50 -08001008 * Returns a platform configuration for WFC which may override the user
1009 * setting per slot. Note: WFC presumes that VoLTE is enabled (these are
1010 * configuration settings which must be done correctly).
1011 */
Brad Ebinger479f52c2017-08-28 13:19:22 -07001012 public boolean isWfcEnabledByPlatform() {
Brad Ebinger16417b42017-03-07 13:48:50 -08001013 if (SystemProperties.getInt(PROPERTY_DBG_WFC_AVAIL_OVERRIDE,
1014 PROPERTY_DBG_WFC_AVAIL_OVERRIDE_DEFAULT) == 1) {
1015 return true;
1016 }
1017
1018 return mContext.getResources().getBoolean(
1019 com.android.internal.R.bool.config_device_wfc_ims_available) &&
Brad Ebinger479f52c2017-08-28 13:19:22 -07001020 getBooleanCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -08001021 CarrierConfigManager.KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL) &&
Brad Ebinger479f52c2017-08-28 13:19:22 -07001022 isGbaValid();
Etan Cohena00c9192014-12-23 15:02:29 -08001023 }
1024
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001025 /**
Brad Ebinger16417b42017-03-07 13:48:50 -08001026 * If carrier requires that IMS is only available if GBA capable SIM is used,
1027 * then this function checks GBA bit in EF IST.
1028 *
1029 * Format of EF IST is defined in 3GPP TS 31.103 (Section 4.2.7).
1030 */
Brad Ebinger479f52c2017-08-28 13:19:22 -07001031 private boolean isGbaValid() {
1032 if (getBooleanCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -08001033 CarrierConfigManager.KEY_CARRIER_IMS_GBA_REQUIRED_BOOL)) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001034 final TelephonyManager telephonyManager = new TelephonyManager(mContext, getSubId());
Brad Ebinger16417b42017-03-07 13:48:50 -08001035 String efIst = telephonyManager.getIsimIst();
1036 if (efIst == null) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001037 loge("isGbaValid - ISF is NULL");
Brad Ebinger16417b42017-03-07 13:48:50 -08001038 return true;
1039 }
1040 boolean result = efIst != null && efIst.length() > 1 &&
1041 (0x02 & (byte)efIst.charAt(1)) != 0;
Brad Ebinger479f52c2017-08-28 13:19:22 -07001042 if (DBG) log("isGbaValid - GBA capable=" + result + ", ISF=" + efIst);
Brad Ebinger16417b42017-03-07 13:48:50 -08001043 return result;
1044 }
1045 return true;
1046 }
1047
1048 /**
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -07001049 * This function should be called when ImsConfig.ACTION_IMS_CONFIG_CHANGED is received.
1050 *
1051 * We cannot register receiver in ImsManager because this would lead to resource leak.
1052 * ImsManager can be created in different processes and it is not notified when that process
1053 * is about to be terminated.
1054 *
1055 * @hide
1056 * */
1057 public static void onProvisionedValueChanged(Context context, int item, String value) {
Amit Mahajan24f7b162016-07-21 16:33:53 -07001058 if (DBG) Rlog.d(TAG, "onProvisionedValueChanged: item=" + item + " val=" + value);
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -07001059 ImsManager mgr = ImsManager.getInstance(context,
1060 SubscriptionManager.getDefaultVoicePhoneId());
1061
1062 switch (item) {
1063 case ImsConfig.ConfigConstants.VLT_SETTING_ENABLED:
Amit Mahajan24f7b162016-07-21 16:33:53 -07001064 mgr.setVolteProvisionedProperty(value.equals("1"));
1065 if (DBG) Rlog.d(TAG,"isVoLteProvisioned = " + mgr.isVolteProvisioned());
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -07001066 break;
1067
1068 case ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED:
Amit Mahajan24f7b162016-07-21 16:33:53 -07001069 mgr.setWfcProvisionedProperty(value.equals("1"));
1070 if (DBG) Rlog.d(TAG,"isWfcProvisioned = " + mgr.isWfcProvisioned());
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -07001071 break;
1072
Nathan Harolda9fc7f12016-06-30 16:12:14 -07001073 case ImsConfig.ConfigConstants.LVC_SETTING_ENABLED:
Amit Mahajan24f7b162016-07-21 16:33:53 -07001074 mgr.setVtProvisionedProperty(value.equals("1"));
1075 if (DBG) Rlog.d(TAG,"isVtProvisioned = " + mgr.isVtProvisioned());
Nathan Harolda9fc7f12016-06-30 16:12:14 -07001076 break;
1077
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -07001078 }
1079 }
1080
Brad Ebingerbe6cb672017-08-25 14:55:00 -07001081 private class AsyncUpdateProvisionedValues extends AsyncTask<Void, Void, Boolean> {
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -07001082 @Override
Brad Ebingerbe6cb672017-08-25 14:55:00 -07001083 protected Boolean doInBackground(Void... params) {
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -07001084 // disable on any error
Amit Mahajan24f7b162016-07-21 16:33:53 -07001085 setVolteProvisionedProperty(false);
1086 setWfcProvisionedProperty(false);
1087 setVtProvisionedProperty(false);
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -07001088
1089 try {
1090 ImsConfig config = getConfigInterface();
1091 if (config != null) {
Amit Mahajan24f7b162016-07-21 16:33:53 -07001092 setVolteProvisionedProperty(getProvisionedBool(config,
1093 ImsConfig.ConfigConstants.VLT_SETTING_ENABLED));
1094 if (DBG) Rlog.d(TAG, "isVoLteProvisioned = " + isVolteProvisioned());
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -07001095
Amit Mahajan24f7b162016-07-21 16:33:53 -07001096 setWfcProvisionedProperty(getProvisionedBool(config,
1097 ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED));
1098 if (DBG) Rlog.d(TAG, "isWfcProvisioned = " + isWfcProvisioned());
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -07001099
Amit Mahajan24f7b162016-07-21 16:33:53 -07001100 setVtProvisionedProperty(getProvisionedBool(config,
1101 ImsConfig.ConfigConstants.LVC_SETTING_ENABLED));
1102 if (DBG) Rlog.d(TAG, "isVtProvisioned = " + isVtProvisioned());
Nathan Harolda9fc7f12016-06-30 16:12:14 -07001103
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -07001104 }
1105 } catch (ImsException ie) {
Meng Wangca7d4c42016-06-30 22:05:24 -07001106 Rlog.e(TAG, "AsyncUpdateProvisionedValues error: ", ie);
Brad Ebingerbe6cb672017-08-25 14:55:00 -07001107 return false;
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -07001108 }
1109
Brad Ebingerbe6cb672017-08-25 14:55:00 -07001110 return true;
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -07001111 }
1112
Brad Ebingerbe6cb672017-08-25 14:55:00 -07001113 @Override
1114 protected void onPostExecute(Boolean completed) {
1115 if (mProvisionBackoff == null) {
1116 return;
1117 }
1118 if (!completed) {
1119 mProvisionBackoff.notifyFailed();
1120 } else {
1121 mProvisionBackoff.stop();
1122 }
1123 }
1124
1125 /**
1126 * Will return with config value or throw an ImsException if we receive an error from
1127 * ImsConfig for that value.
1128 */
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -07001129 private boolean getProvisionedBool(ImsConfig config, int item) throws ImsException {
Brad Ebingerbe6cb672017-08-25 14:55:00 -07001130 int value = config.getProvisionedValue(item);
1131 if (value == ImsConfig.FeatureValueConstants.ERROR) {
1132 throw new ImsException("getProvisionedBool failed with error for item: " + item,
1133 ImsReasonInfo.CODE_LOCAL_INTERNAL_ERROR);
1134 }
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -07001135 return config.getProvisionedValue(item) == ImsConfig.FeatureValueConstants.ON;
1136 }
1137 }
1138
Brad Ebingerbe6cb672017-08-25 14:55:00 -07001139 // used internally only, use #updateProvisionedValues instead.
1140 private void handleUpdateProvisionedValues() {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001141 if (getBooleanCarrierConfig(
Pavel Zhamaitsiak002b2042016-06-03 16:05:31 -07001142 CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL)) {
1143
1144 new AsyncUpdateProvisionedValues().execute();
1145 }
1146 }
1147
1148 /**
Brad Ebingerbe6cb672017-08-25 14:55:00 -07001149 * Asynchronously get VoLTE, WFC, VT provisioning statuses. If ImsConfig is not available, we
1150 * will retry with exponential backoff.
1151 */
1152 private void updateProvisionedValues() {
1153 // Start trying to receive provisioning status after BACKOFF_INITIAL_DELAY_MS.
1154 if (mProvisionBackoff != null) {
1155 mProvisionBackoff.start();
1156 } else {
1157 // bypass and launch async thread once without backoff.
1158 handleUpdateProvisionedValues();
1159 }
1160 }
1161
1162 /**
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001163 * Sync carrier config and user settings with ImsConfig.
1164 *
1165 * @param context for the manager object
1166 * @param phoneId phone id
1167 * @param force update
Brad Ebinger16417b42017-03-07 13:48:50 -08001168 *
Brad Ebinger479f52c2017-08-28 13:19:22 -07001169 * @deprecated Doesn't support MSIM devices. Use {@link #updateImsServiceConfig(boolean)}
1170 * instead.
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001171 */
1172 public static void updateImsServiceConfig(Context context, int phoneId, boolean force) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001173 ImsManager mgr = ImsManager.getInstance(context, phoneId);
1174 if (mgr != null) {
1175 mgr.updateImsServiceConfig(force);
Pavel Zhamaitsiakfc202992016-03-29 18:07:38 -07001176 }
Brad Ebinger479f52c2017-08-28 13:19:22 -07001177 loge("updateImsServiceConfig: ImsManager null, returning without update.");
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001178 }
1179
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -07001180 /**
Brad Ebinger16417b42017-03-07 13:48:50 -08001181 * Sync carrier config and user settings with ImsConfig.
1182 *
1183 * @param context for the manager object
1184 * @param phoneId phone id
1185 * @param force update
1186 */
Brad Ebinger479f52c2017-08-28 13:19:22 -07001187 public void updateImsServiceConfig(boolean force) {
Brad Ebinger16417b42017-03-07 13:48:50 -08001188 if (!force) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001189 TelephonyManager tm = new TelephonyManager(mContext, getSubId());
1190 if (tm.getSimState() != TelephonyManager.SIM_STATE_READY) {
1191 log("updateImsServiceConfig: SIM not ready");
Brad Ebinger16417b42017-03-07 13:48:50 -08001192 // Don't disable IMS if SIM is not ready
1193 return;
1194 }
1195 }
1196
1197 if (!mConfigUpdated || force) {
1198 try {
1199 updateProvisionedValues();
1200
1201 // TODO: Extend ImsConfig API and set all feature values in single function call.
1202
1203 // Note: currently the order of updates is set to produce different order of
1204 // setFeatureValue() function calls from setAdvanced4GMode(). This is done to
1205 // differentiate this code path from vendor code perspective.
1206 boolean isImsUsed = updateVolteFeatureValue();
1207 isImsUsed |= updateWfcFeatureAndProvisionedValues();
1208 isImsUsed |= updateVideoCallFeatureValue();
1209
Brad Ebinger479f52c2017-08-28 13:19:22 -07001210 if (isImsUsed || !isTurnOffImsAllowedByPlatform()) {
Brad Ebinger16417b42017-03-07 13:48:50 -08001211 // Turn on IMS if it is used.
1212 // Also, if turning off is not allowed for current carrier,
1213 // we need to turn IMS on because it might be turned off before
1214 // phone switched to current carrier.
Brad Ebinger479f52c2017-08-28 13:19:22 -07001215 log("updateImsServiceConfig: turnOnIms");
Brad Ebinger16417b42017-03-07 13:48:50 -08001216 turnOnIms();
1217 } else {
1218 // Turn off IMS if it is not used AND turning off is allowed for carrier.
Brad Ebinger479f52c2017-08-28 13:19:22 -07001219 log("updateImsServiceConfig: turnOffIms");
Brad Ebinger16417b42017-03-07 13:48:50 -08001220 turnOffIms();
1221 }
1222
1223 mConfigUpdated = true;
1224 } catch (ImsException e) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001225 loge("updateImsServiceConfig: ", e);
Brad Ebinger16417b42017-03-07 13:48:50 -08001226 mConfigUpdated = false;
1227 }
1228 }
1229 }
1230
1231 /**
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -07001232 * Update VoLTE config
1233 * @return whether feature is On
1234 * @throws ImsException
1235 */
1236 private boolean updateVolteFeatureValue() throws ImsException {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001237 boolean available = isVolteEnabledByPlatform();
1238 boolean enabled = isEnhanced4gLteModeSettingEnabledByUser();
1239 boolean isNonTty = isNonTtyOrTtyOnVolteEnabled();
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -08001240 boolean isFeatureOn = available && enabled && isNonTty;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001241
1242 log("updateVolteFeatureValue: available = " + available
1243 + ", enabled = " + enabled
1244 + ", nonTTY = " + isNonTty);
1245
1246 getConfigInterface().setFeatureValue(
1247 ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE,
1248 TelephonyManager.NETWORK_TYPE_LTE,
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -08001249 isFeatureOn ?
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001250 ImsConfig.FeatureValueConstants.ON :
1251 ImsConfig.FeatureValueConstants.OFF,
Pavel Zhamaitsiakf4b90322016-01-26 14:34:09 -08001252 mImsConfigListener);
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -07001253
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -08001254 return isFeatureOn;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001255 }
1256
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -07001257 /**
Jack Yu643ffe42016-07-08 14:25:46 -07001258 * Update video call over LTE config
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -07001259 * @return whether feature is On
1260 * @throws ImsException
1261 */
1262 private boolean updateVideoCallFeatureValue() throws ImsException {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001263 boolean available = isVtEnabledByPlatform();
1264 boolean enabled = isVtEnabledByUser();
1265 boolean isNonTty = isNonTtyOrTtyOnVolteEnabled();
Amit Mahajan24f7b162016-07-21 16:33:53 -07001266 boolean isDataEnabled = isDataEnabled();
Brad Ebinger479f52c2017-08-28 13:19:22 -07001267 boolean ignoreDataEnabledChanged = getBooleanCarrierConfig(
Jack Yu57781852016-11-16 17:20:38 -08001268 CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS);
Jack Yu643ffe42016-07-08 14:25:46 -07001269
Jack Yu57781852016-11-16 17:20:38 -08001270 boolean isFeatureOn = available && enabled && isNonTty
1271 && (ignoreDataEnabledChanged || isDataEnabled);
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001272
1273 log("updateVideoCallFeatureValue: available = " + available
1274 + ", enabled = " + enabled
Jack Yu643ffe42016-07-08 14:25:46 -07001275 + ", nonTTY = " + isNonTty
Amit Mahajan24f7b162016-07-21 16:33:53 -07001276 + ", data enabled = " + isDataEnabled);
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001277
1278 getConfigInterface().setFeatureValue(
1279 ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_LTE,
1280 TelephonyManager.NETWORK_TYPE_LTE,
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -08001281 isFeatureOn ?
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001282 ImsConfig.FeatureValueConstants.ON :
1283 ImsConfig.FeatureValueConstants.OFF,
Pavel Zhamaitsiakf4b90322016-01-26 14:34:09 -08001284 mImsConfigListener);
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -07001285
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -08001286 return isFeatureOn;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001287 }
1288
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -07001289 /**
1290 * Update WFC config
1291 * @return whether feature is On
1292 * @throws ImsException
1293 */
1294 private boolean updateWfcFeatureAndProvisionedValues() throws ImsException {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001295 TelephonyManager tm = new TelephonyManager(mContext, getSubId());
1296 boolean isNetworkRoaming = tm.isNetworkRoaming();
1297 boolean available = isWfcEnabledByPlatform();
1298 boolean enabled = isWfcEnabledByUser();
Suresh Koleti76491082017-04-21 18:39:50 +05301299 updateDefaultWfcMode();
Brad Ebinger479f52c2017-08-28 13:19:22 -07001300 int mode = getWfcMode(isNetworkRoaming);
1301 boolean roaming = isWfcRoamingEnabledByUser();
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -08001302 boolean isFeatureOn = available && enabled;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001303
1304 log("updateWfcFeatureAndProvisionedValues: available = " + available
1305 + ", enabled = " + enabled
1306 + ", mode = " + mode
1307 + ", roaming = " + roaming);
1308
1309 getConfigInterface().setFeatureValue(
Pavel Zhamaitsiake6f99432015-09-11 10:29:30 -07001310 ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_WIFI,
1311 TelephonyManager.NETWORK_TYPE_IWLAN,
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -08001312 isFeatureOn ?
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001313 ImsConfig.FeatureValueConstants.ON :
1314 ImsConfig.FeatureValueConstants.OFF,
Pavel Zhamaitsiakf4b90322016-01-26 14:34:09 -08001315 mImsConfigListener);
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001316
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -08001317 if (!isFeatureOn) {
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001318 mode = ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED;
1319 roaming = false;
1320 }
1321 setWfcModeInternal(mContext, mode);
Brad Ebinger16417b42017-03-07 13:48:50 -08001322 setWfcRoamingSettingInternal(roaming);
Pavel Zhamaitsiakdc16e452015-09-08 17:12:06 -07001323
Pavel Zhamaitsiak9510b1c2015-12-18 11:30:49 -08001324 return isFeatureOn;
Pavel Zhamaitsiak8ca52ff2015-09-04 17:08:35 -07001325 }
1326
Brad Ebinger16780ff2017-01-26 11:18:21 -08001327 /**
Brad Ebinger479f52c2017-08-28 13:19:22 -07001328 * Do NOT use this directly, instead use {@link #getInstance(Context, int)}.
Brad Ebinger16780ff2017-01-26 11:18:21 -08001329 */
1330 @VisibleForTesting
1331 public ImsManager(Context context, int phoneId) {
Wink Savilleef36ef62014-06-11 08:39:38 -07001332 mContext = context;
Etan Cohenabbd7882014-09-26 22:35:35 -07001333 mPhoneId = phoneId;
Brad Ebinger16780ff2017-01-26 11:18:21 -08001334 mConfigDynamicBind = mContext.getResources().getBoolean(
1335 com.android.internal.R.bool.config_dynamic_bind_ims);
Brad Ebinger16417b42017-03-07 13:48:50 -08001336 mConfigManager = (CarrierConfigManager) context.getSystemService(
1337 Context.CARRIER_CONFIG_SERVICE);
Brad Ebingerbe6cb672017-08-25 14:55:00 -07001338 if (Looper.getMainLooper() != null) {
1339 mProvisionBackoff = new ExponentialBackoff(BACKOFF_INITIAL_DELAY_MS,
1340 BACKOFF_MAX_DELAY_MS, BACKOFF_MULTIPLIER,
1341 new Handler(Looper.getMainLooper()), this::handleUpdateProvisionedValues);
1342 }
Brad Ebinger16780ff2017-01-26 11:18:21 -08001343 createImsService();
1344 }
1345
1346 /**
Brad Ebinger16780ff2017-01-26 11:18:21 -08001347 * @return Whether or not ImsManager is configured to Dynamically bind or not to support legacy
1348 * devices.
1349 */
1350 public boolean isDynamicBinding() {
1351 return mConfigDynamicBind;
Wink Savilleef36ef62014-06-11 08:39:38 -07001352 }
1353
Etan Cohenf4311122015-02-26 17:47:13 -08001354 /*
Brad Ebingerff097922017-06-19 15:43:08 -07001355 * Returns a flag indicating whether the IMS service is available. If it is not available,
1356 * it will try to connect before reporting failure.
Etan Cohenf4311122015-02-26 17:47:13 -08001357 */
1358 public boolean isServiceAvailable() {
Brad Ebingerff097922017-06-19 15:43:08 -07001359 connectIfServiceIsAvailable();
Brad Ebinger16780ff2017-01-26 11:18:21 -08001360 // mImsServiceProxy will always create an ImsServiceProxy.
1361 return mImsServiceProxy.isBinderAlive();
Etan Cohenf4311122015-02-26 17:47:13 -08001362 }
1363
Brad Ebingerff097922017-06-19 15:43:08 -07001364 /**
1365 * If the service is available, try to reconnect.
1366 */
1367 public void connectIfServiceIsAvailable() {
1368 if (mImsServiceProxy == null || !mImsServiceProxy.isBinderAlive()) {
1369 createImsService();
1370 }
1371 }
1372
Pavel Zhamaitsiakf4b90322016-01-26 14:34:09 -08001373 public void setImsConfigListener(ImsConfigListener listener) {
1374 mImsConfigListener = listener;
1375 }
1376
Brad Ebingerb10b61e2017-04-18 11:45:26 -07001377
1378 /**
1379 * Adds a callback for status changed events if the binder is already available. If it is not,
1380 * this method will throw an ImsException.
1381 */
1382 public void addNotifyStatusChangedCallbackIfAvailable(ImsServiceProxy.INotifyStatusChanged c)
1383 throws ImsException {
1384 if (!mImsServiceProxy.isBinderAlive()) {
1385 throw new ImsException("Binder is not active!",
1386 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1387 }
Brad Ebinger16780ff2017-01-26 11:18:21 -08001388 if (c != null) {
1389 mStatusCallbacks.add(c);
1390 }
1391 }
1392
Wink Savilleef36ef62014-06-11 08:39:38 -07001393 /**
1394 * Opens the IMS service for making calls and/or receiving generic IMS calls.
1395 * The caller may make subsquent calls through {@link #makeCall}.
1396 * The IMS service will register the device to the operator's network with the credentials
1397 * (from ISIM) periodically in order to receive calls from the operator's network.
1398 * When the IMS service receives a new call, it will send out an intent with
1399 * the provided action string.
1400 * The intent contains a call ID extra {@link getCallId} and it can be used to take a call.
1401 *
1402 * @param serviceClass a service class specified in {@link ImsServiceClass}
1403 * For VoLTE service, it MUST be a {@link ImsServiceClass#MMTEL}.
1404 * @param incomingCallPendingIntent When an incoming call is received,
1405 * the IMS service will call {@link PendingIntent#send(Context, int, Intent)} to
1406 * send back the intent to the caller with {@link #INCOMING_CALL_RESULT_CODE}
1407 * as the result code and the intent to fill in the call ID; It cannot be null
1408 * @param listener To listen to IMS registration events; It cannot be null
1409 * @return identifier (greater than 0) for the specified service
1410 * @throws NullPointerException if {@code incomingCallPendingIntent}
1411 * or {@code listener} is null
1412 * @throws ImsException if calling the IMS service results in an error
1413 * @see #getCallId
Brad Ebinger16780ff2017-01-26 11:18:21 -08001414 * @see #getImsSessionId
Wink Savilleef36ef62014-06-11 08:39:38 -07001415 */
1416 public int open(int serviceClass, PendingIntent incomingCallPendingIntent,
1417 ImsConnectionStateListener listener) throws ImsException {
1418 checkAndThrowExceptionIfServiceUnavailable();
1419
1420 if (incomingCallPendingIntent == null) {
1421 throw new NullPointerException("incomingCallPendingIntent can't be null");
1422 }
1423
1424 if (listener == null) {
1425 throw new NullPointerException("listener can't be null");
1426 }
1427
1428 int result = 0;
1429
1430 try {
Brad Ebinger57b11892017-06-13 16:21:35 -07001431 // Register a stub implementation of the ImsRegistrationListener. There is the
1432 // possibility that if we use the real implementation of the ImsRegistrationListener,
1433 // it will be added twice.
1434 // TODO: Remove ImsRegistrationListener from startSession API (b/62588776)
Brad Ebinger16780ff2017-01-26 11:18:21 -08001435 result = mImsServiceProxy.startSession(incomingCallPendingIntent,
Brad Ebinger57b11892017-06-13 16:21:35 -07001436 new ImsRegistrationListenerBase());
1437 addRegistrationListener(listener);
1438 log("open: Session started and registration listener added.");
Wink Savilleef36ef62014-06-11 08:39:38 -07001439 } catch (RemoteException e) {
1440 throw new ImsException("open()", e,
1441 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1442 }
1443
1444 if (result <= 0) {
1445 // If the return value is a minus value,
1446 // it means that an error occurred in the service.
1447 // So, it needs to convert to the reason code specified in ImsReasonInfo.
1448 throw new ImsException("open()", (result * (-1)));
1449 }
1450
1451 return result;
1452 }
1453
1454 /**
Pavel Zhamaitsiakce410172016-04-15 10:55:56 -07001455 * Adds registration listener to the IMS service.
1456 *
1457 * @param serviceClass a service class specified in {@link ImsServiceClass}
1458 * For VoLTE service, it MUST be a {@link ImsServiceClass#MMTEL}.
1459 * @param listener To listen to IMS registration events; It cannot be null
1460 * @throws NullPointerException if {@code listener} is null
1461 * @throws ImsException if calling the IMS service results in an error
Brad Ebinger9a0280c2017-06-01 15:58:48 -07001462 *
1463 * @deprecated Use {@link #addRegistrationListener(ImsConnectionStateListener)} instead.
Pavel Zhamaitsiakce410172016-04-15 10:55:56 -07001464 */
1465 public void addRegistrationListener(int serviceClass, ImsConnectionStateListener listener)
1466 throws ImsException {
Brad Ebinger9a0280c2017-06-01 15:58:48 -07001467 addRegistrationListener(listener);
1468 }
1469
1470 /**
1471 * Adds registration listener to the IMS service.
1472 *
1473 * @param listener To listen to IMS registration events; It cannot be null
1474 * @throws NullPointerException if {@code listener} is null
1475 * @throws ImsException if calling the IMS service results in an error
1476 */
1477 public void addRegistrationListener(ImsConnectionStateListener listener)
1478 throws ImsException {
Pavel Zhamaitsiakce410172016-04-15 10:55:56 -07001479
1480 if (listener == null) {
1481 throw new NullPointerException("listener can't be null");
1482 }
Brad Ebinger57b11892017-06-13 16:21:35 -07001483 // We only want this Proxy registered once.
Brad Ebinger9a0280c2017-06-01 15:58:48 -07001484 synchronized (mHasRegisteredLock) {
1485 if (!mHasRegisteredForProxy) {
1486 try {
Brad Ebinger57b11892017-06-13 16:21:35 -07001487 checkAndThrowExceptionIfServiceUnavailable();
Brad Ebinger9a0280c2017-06-01 15:58:48 -07001488 mImsServiceProxy.addRegistrationListener(mRegistrationListenerProxy);
Brad Ebinger57b11892017-06-13 16:21:35 -07001489 log("RegistrationListenerProxy registered.");
Brad Ebinger9a0280c2017-06-01 15:58:48 -07001490 // Only record if there isn't a RemoteException.
1491 mHasRegisteredForProxy = true;
1492 } catch (RemoteException e) {
1493 throw new ImsException("addRegistrationListener()", e,
1494 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1495 }
1496 }
1497 }
1498 synchronized (mRegistrationListeners) {
Brad Ebinger57b11892017-06-13 16:21:35 -07001499 log("Local registration listener added: " + listener);
Brad Ebinger9a0280c2017-06-01 15:58:48 -07001500 mRegistrationListeners.add(listener);
Pavel Zhamaitsiakce410172016-04-15 10:55:56 -07001501 }
1502 }
1503
1504 /**
Brad Ebinger16780ff2017-01-26 11:18:21 -08001505 * Removes the registration listener from the IMS service.
1506 *
Brad Ebinger16780ff2017-01-26 11:18:21 -08001507 * @param listener Previously registered listener that will be removed. Can not be null.
1508 * @throws NullPointerException if {@code listener} is null
1509 * @throws ImsException if calling the IMS service results in an error
1510 * instead.
1511 */
Brad Ebingerb5f30c72017-02-17 14:54:31 -08001512 public void removeRegistrationListener(ImsConnectionStateListener listener)
Brad Ebinger16780ff2017-01-26 11:18:21 -08001513 throws ImsException {
Brad Ebinger16780ff2017-01-26 11:18:21 -08001514 if (listener == null) {
1515 throw new NullPointerException("listener can't be null");
1516 }
1517
Brad Ebinger9a0280c2017-06-01 15:58:48 -07001518 synchronized (mRegistrationListeners) {
Brad Ebinger57b11892017-06-13 16:21:35 -07001519 log("Local registration listener removed: " + listener);
Brad Ebinger9a0280c2017-06-01 15:58:48 -07001520 mRegistrationListeners.remove(listener);
Brad Ebinger16780ff2017-01-26 11:18:21 -08001521 }
1522 }
1523
1524 /**
Wink Savilleef36ef62014-06-11 08:39:38 -07001525 * Closes the specified service ({@link ImsServiceClass}) not to make/receive calls.
1526 * All the resources that were allocated to the service are also released.
1527 *
Brad Ebinger16780ff2017-01-26 11:18:21 -08001528 * @param sessionId a session id to be closed which is obtained from {@link ImsManager#open}
Wink Savilleef36ef62014-06-11 08:39:38 -07001529 * @throws ImsException if calling the IMS service results in an error
1530 */
Brad Ebinger16780ff2017-01-26 11:18:21 -08001531 public void close(int sessionId) throws ImsException {
Wink Savilleef36ef62014-06-11 08:39:38 -07001532 checkAndThrowExceptionIfServiceUnavailable();
1533
1534 try {
Brad Ebinger16780ff2017-01-26 11:18:21 -08001535 mImsServiceProxy.endSession(sessionId);
Wink Savilleef36ef62014-06-11 08:39:38 -07001536 } catch (RemoteException e) {
1537 throw new ImsException("close()", e,
1538 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1539 } finally {
1540 mUt = null;
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -05001541 mConfig = null;
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -07001542 mEcbm = null;
Tyler Gunn4d128b62016-04-13 15:44:38 -07001543 mMultiEndpoint = null;
Wink Savilleef36ef62014-06-11 08:39:38 -07001544 }
1545 }
1546
1547 /**
1548 * Gets the configuration interface to provision / withdraw the supplementary service settings.
1549 *
Wink Savilleef36ef62014-06-11 08:39:38 -07001550 * @return the Ut interface instance
1551 * @throws ImsException if getting the Ut interface results in an error
1552 */
Brad Ebingerb5f30c72017-02-17 14:54:31 -08001553 public ImsUtInterface getSupplementaryServiceConfiguration()
Wink Savilleef36ef62014-06-11 08:39:38 -07001554 throws ImsException {
Brad Ebinger16780ff2017-01-26 11:18:21 -08001555 // FIXME: manage the multiple Ut interfaces based on the session id
Brad Ebinger138b4a62017-06-20 16:29:50 -07001556 if (mUt != null && mUt.isBinderAlive()) {
1557 return mUt;
Wink Savilleef36ef62014-06-11 08:39:38 -07001558 }
1559
Brad Ebinger138b4a62017-06-20 16:29:50 -07001560 checkAndThrowExceptionIfServiceUnavailable();
1561 try {
1562 IImsUt iUt = mImsServiceProxy.getUtInterface();
1563
1564 if (iUt == null) {
1565 throw new ImsException("getSupplementaryServiceConfiguration()",
1566 ImsReasonInfo.CODE_UT_NOT_SUPPORTED);
1567 }
1568
1569 mUt = new ImsUt(iUt);
1570 } catch (RemoteException e) {
1571 throw new ImsException("getSupplementaryServiceConfiguration()", e,
1572 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1573 }
Wink Savilleef36ef62014-06-11 08:39:38 -07001574 return mUt;
1575 }
1576
1577 /**
1578 * Checks if the IMS service has successfully registered to the IMS network
1579 * with the specified service & call type.
1580 *
Wink Savilleef36ef62014-06-11 08:39:38 -07001581 * @param serviceType a service type that is specified in {@link ImsCallProfile}
1582 * {@link ImsCallProfile#SERVICE_TYPE_NORMAL}
1583 * {@link ImsCallProfile#SERVICE_TYPE_EMERGENCY}
1584 * @param callType a call type that is specified in {@link ImsCallProfile}
1585 * {@link ImsCallProfile#CALL_TYPE_VOICE_N_VIDEO}
1586 * {@link ImsCallProfile#CALL_TYPE_VOICE}
1587 * {@link ImsCallProfile#CALL_TYPE_VT}
1588 * {@link ImsCallProfile#CALL_TYPE_VS}
1589 * @return true if the specified service id is connected to the IMS network;
1590 * false otherwise
1591 * @throws ImsException if calling the IMS service results in an error
1592 */
Brad Ebingerb5f30c72017-02-17 14:54:31 -08001593 public boolean isConnected(int serviceType, int callType)
Wink Savilleef36ef62014-06-11 08:39:38 -07001594 throws ImsException {
1595 checkAndThrowExceptionIfServiceUnavailable();
1596
1597 try {
Brad Ebingerb5f30c72017-02-17 14:54:31 -08001598 return mImsServiceProxy.isConnected(serviceType, callType);
Wink Savilleef36ef62014-06-11 08:39:38 -07001599 } catch (RemoteException e) {
1600 throw new ImsException("isServiceConnected()", e,
1601 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1602 }
1603 }
1604
1605 /**
1606 * Checks if the specified IMS service is opend.
1607 *
Wink Savilleef36ef62014-06-11 08:39:38 -07001608 * @return true if the specified service id is opened; false otherwise
1609 * @throws ImsException if calling the IMS service results in an error
1610 */
Brad Ebingerb5f30c72017-02-17 14:54:31 -08001611 public boolean isOpened() throws ImsException {
Wink Savilleef36ef62014-06-11 08:39:38 -07001612 checkAndThrowExceptionIfServiceUnavailable();
1613
1614 try {
Brad Ebingerb5f30c72017-02-17 14:54:31 -08001615 return mImsServiceProxy.isOpened();
Wink Savilleef36ef62014-06-11 08:39:38 -07001616 } catch (RemoteException e) {
1617 throw new ImsException("isOpened()", e,
1618 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1619 }
1620 }
1621
1622 /**
1623 * Creates a {@link ImsCallProfile} from the service capabilities & IMS registration state.
1624 *
Brad Ebinger16780ff2017-01-26 11:18:21 -08001625 * @param sessionId a session id which is obtained from {@link ImsManager#open}
Wink Savilleef36ef62014-06-11 08:39:38 -07001626 * @param serviceType a service type that is specified in {@link ImsCallProfile}
1627 * {@link ImsCallProfile#SERVICE_TYPE_NONE}
1628 * {@link ImsCallProfile#SERVICE_TYPE_NORMAL}
1629 * {@link ImsCallProfile#SERVICE_TYPE_EMERGENCY}
1630 * @param callType a call type that is specified in {@link ImsCallProfile}
1631 * {@link ImsCallProfile#CALL_TYPE_VOICE}
1632 * {@link ImsCallProfile#CALL_TYPE_VT}
1633 * {@link ImsCallProfile#CALL_TYPE_VT_TX}
1634 * {@link ImsCallProfile#CALL_TYPE_VT_RX}
1635 * {@link ImsCallProfile#CALL_TYPE_VT_NODIR}
1636 * {@link ImsCallProfile#CALL_TYPE_VS}
1637 * {@link ImsCallProfile#CALL_TYPE_VS_TX}
1638 * {@link ImsCallProfile#CALL_TYPE_VS_RX}
1639 * @return a {@link ImsCallProfile} object
1640 * @throws ImsException if calling the IMS service results in an error
1641 */
Brad Ebingerb5f30c72017-02-17 14:54:31 -08001642 public ImsCallProfile createCallProfile(int sessionId, int serviceType, int callType)
1643 throws ImsException {
Wink Savilleef36ef62014-06-11 08:39:38 -07001644 checkAndThrowExceptionIfServiceUnavailable();
1645
1646 try {
Brad Ebinger16780ff2017-01-26 11:18:21 -08001647 return mImsServiceProxy.createCallProfile(sessionId, serviceType, callType);
Wink Savilleef36ef62014-06-11 08:39:38 -07001648 } catch (RemoteException e) {
1649 throw new ImsException("createCallProfile()", e,
1650 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1651 }
1652 }
1653
1654 /**
1655 * Creates a {@link ImsCall} to make a call.
1656 *
Brad Ebinger16780ff2017-01-26 11:18:21 -08001657 * @param sessionId a session id which is obtained from {@link ImsManager#open}
Wink Savilleef36ef62014-06-11 08:39:38 -07001658 * @param profile a call profile to make the call
1659 * (it contains service type, call type, media information, etc.)
1660 * @param participants participants to invite the conference call
1661 * @param listener listen to the call events from {@link ImsCall}
1662 * @return a {@link ImsCall} object
1663 * @throws ImsException if calling the IMS service results in an error
1664 */
Brad Ebinger16780ff2017-01-26 11:18:21 -08001665 public ImsCall makeCall(int sessionId, ImsCallProfile profile, String[] callees,
Wink Savilleef36ef62014-06-11 08:39:38 -07001666 ImsCall.Listener listener) throws ImsException {
1667 if (DBG) {
Brad Ebinger16780ff2017-01-26 11:18:21 -08001668 log("makeCall :: sessionId=" + sessionId
fionaxu7b3107c2016-07-06 14:04:06 -07001669 + ", profile=" + profile);
Wink Savilleef36ef62014-06-11 08:39:38 -07001670 }
1671
1672 checkAndThrowExceptionIfServiceUnavailable();
1673
1674 ImsCall call = new ImsCall(mContext, profile);
1675
1676 call.setListener(listener);
Brad Ebinger16780ff2017-01-26 11:18:21 -08001677 ImsCallSession session = createCallSession(sessionId, profile);
Wink Savilleef36ef62014-06-11 08:39:38 -07001678
1679 if ((callees != null) && (callees.length == 1)) {
1680 call.start(session, callees[0]);
1681 } else {
1682 call.start(session, callees);
1683 }
1684
1685 return call;
1686 }
1687
1688 /**
1689 * Creates a {@link ImsCall} to take an incoming call.
1690 *
Brad Ebinger16780ff2017-01-26 11:18:21 -08001691 * @param sessionId a session id which is obtained from {@link ImsManager#open}
Wink Savilleef36ef62014-06-11 08:39:38 -07001692 * @param incomingCallIntent the incoming call broadcast intent
1693 * @param listener to listen to the call events from {@link ImsCall}
1694 * @return a {@link ImsCall} object
1695 * @throws ImsException if calling the IMS service results in an error
1696 */
Brad Ebinger16780ff2017-01-26 11:18:21 -08001697 public ImsCall takeCall(int sessionId, Intent incomingCallIntent,
Wink Savilleef36ef62014-06-11 08:39:38 -07001698 ImsCall.Listener listener) throws ImsException {
1699 if (DBG) {
Brad Ebinger16780ff2017-01-26 11:18:21 -08001700 log("takeCall :: sessionId=" + sessionId
Wink Savilleef36ef62014-06-11 08:39:38 -07001701 + ", incomingCall=" + incomingCallIntent);
1702 }
1703
1704 checkAndThrowExceptionIfServiceUnavailable();
1705
1706 if (incomingCallIntent == null) {
1707 throw new ImsException("Can't retrieve session with null intent",
1708 ImsReasonInfo.CODE_LOCAL_ILLEGAL_ARGUMENT);
1709 }
1710
Brad Ebinger16780ff2017-01-26 11:18:21 -08001711 int incomingServiceId = getImsSessionId(incomingCallIntent);
Wink Savilleef36ef62014-06-11 08:39:38 -07001712
Brad Ebinger16780ff2017-01-26 11:18:21 -08001713 if (sessionId != incomingServiceId) {
Wink Savilleef36ef62014-06-11 08:39:38 -07001714 throw new ImsException("Service id is mismatched in the incoming call intent",
1715 ImsReasonInfo.CODE_LOCAL_ILLEGAL_ARGUMENT);
1716 }
1717
1718 String callId = getCallId(incomingCallIntent);
1719
1720 if (callId == null) {
1721 throw new ImsException("Call ID missing in the incoming call intent",
1722 ImsReasonInfo.CODE_LOCAL_ILLEGAL_ARGUMENT);
1723 }
1724
1725 try {
Brad Ebinger16780ff2017-01-26 11:18:21 -08001726 IImsCallSession session = mImsServiceProxy.getPendingCallSession(sessionId, callId);
Wink Savilleef36ef62014-06-11 08:39:38 -07001727
1728 if (session == null) {
1729 throw new ImsException("No pending session for the call",
1730 ImsReasonInfo.CODE_LOCAL_NO_PENDING_CALL);
1731 }
1732
1733 ImsCall call = new ImsCall(mContext, session.getCallProfile());
1734
1735 call.attachSession(new ImsCallSession(session));
1736 call.setListener(listener);
1737
1738 return call;
1739 } catch (Throwable t) {
1740 throw new ImsException("takeCall()", t, ImsReasonInfo.CODE_UNSPECIFIED);
1741 }
1742 }
1743
1744 /**
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -05001745 * Gets the config interface to get/set service/capability parameters.
1746 *
1747 * @return the ImsConfig instance.
1748 * @throws ImsException if getting the setting interface results in an error.
1749 */
1750 public ImsConfig getConfigInterface() throws ImsException {
Brad Ebinger138b4a62017-06-20 16:29:50 -07001751 if (mConfig != null && mConfig.isBinderAlive()) {
1752 return mConfig;
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -05001753 }
Brad Ebinger138b4a62017-06-20 16:29:50 -07001754
1755 checkAndThrowExceptionIfServiceUnavailable();
1756 try {
1757 IImsConfig config = mImsServiceProxy.getConfigInterface();
1758 if (config == null) {
1759 throw new ImsException("getConfigInterface()",
1760 ImsReasonInfo.CODE_LOCAL_SERVICE_UNAVAILABLE);
1761 }
1762 mConfig = new ImsConfig(config, mContext);
1763 } catch (RemoteException e) {
1764 throw new ImsException("getConfigInterface()", e,
1765 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1766 }
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -05001767 return mConfig;
1768 }
1769
Hall Liue511a202017-08-17 15:49:58 -07001770 /**
1771 * Set the TTY mode. This is the actual tty mode (varies depending on peripheral status)
1772 */
1773 public void setTtyMode(int ttyMode) throws ImsException {
Brad Ebinger479f52c2017-08-28 13:19:22 -07001774 if (!getBooleanCarrierConfig(
Hall Liue511a202017-08-17 15:49:58 -07001775 CarrierConfigManager.KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL)) {
1776 setAdvanced4GMode((ttyMode == TelecomManager.TTY_MODE_OFF) &&
Brad Ebinger479f52c2017-08-28 13:19:22 -07001777 isEnhanced4gLteModeSettingEnabledByUser());
Hall Liue511a202017-08-17 15:49:58 -07001778 }
1779 }
1780
1781 /**
1782 * Sets the UI TTY mode. This is the preferred TTY mode that the user sets in the call
1783 * settings screen.
1784 */
Brad Ebingerb5f30c72017-02-17 14:54:31 -08001785 public void setUiTTYMode(Context context, int uiTtyMode, Message onComplete)
Shriram Ganeshc403b7b2014-08-14 14:18:57 +05301786 throws ImsException {
1787
Etan Cohen82f78122014-12-15 10:10:14 -08001788 checkAndThrowExceptionIfServiceUnavailable();
Shriram Ganeshc403b7b2014-08-14 14:18:57 +05301789
Etan Cohen82f78122014-12-15 10:10:14 -08001790 try {
Brad Ebingerb5f30c72017-02-17 14:54:31 -08001791 mImsServiceProxy.setUiTTYMode(uiTtyMode, onComplete);
Etan Cohen82f78122014-12-15 10:10:14 -08001792 } catch (RemoteException e) {
1793 throw new ImsException("setTTYMode()", e,
1794 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1795 }
Shriram Ganeshc403b7b2014-08-14 14:18:57 +05301796 }
1797
Naveen Kalla525c3a22017-02-06 14:46:42 -08001798 private ImsReasonInfo makeACopy(ImsReasonInfo imsReasonInfo) {
1799 Parcel p = Parcel.obtain();
1800 imsReasonInfo.writeToParcel(p, 0);
1801 p.setDataPosition(0);
1802 ImsReasonInfo clonedReasonInfo = ImsReasonInfo.CREATOR.createFromParcel(p);
1803 p.recycle();
1804 return clonedReasonInfo;
1805 }
1806
1807 /**
1808 * Get Recent IMS Disconnect Reasons.
1809 *
1810 * @return ArrayList of ImsReasonInfo objects. MAX size of the arraylist
1811 * is MAX_RECENT_DISCONNECT_REASONS. The objects are in the
1812 * chronological order.
1813 */
1814 public ArrayList<ImsReasonInfo> getRecentImsDisconnectReasons() {
1815 ArrayList<ImsReasonInfo> disconnectReasons = new ArrayList<>();
1816
1817 for (ImsReasonInfo reason : mRecentDisconnectReasons) {
1818 disconnectReasons.add(makeACopy(reason));
1819 }
1820 return disconnectReasons;
1821 }
Brad Ebinger16417b42017-03-07 13:48:50 -08001822
Brad Ebinger16780ff2017-01-26 11:18:21 -08001823 public int getImsServiceStatus() throws ImsException {
Brad Ebinger16780ff2017-01-26 11:18:21 -08001824 return mImsServiceProxy.getFeatureStatus();
1825 }
Naveen Kalla525c3a22017-02-06 14:46:42 -08001826
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -05001827 /**
Junda Liue7663c02015-06-23 11:16:26 -07001828 * Get the boolean config from carrier config manager.
1829 *
Brad Ebinger16417b42017-03-07 13:48:50 -08001830 * @param key config key defined in CarrierConfigManager
1831 * @return boolean value of corresponding key.
1832 */
Brad Ebinger479f52c2017-08-28 13:19:22 -07001833 private boolean getBooleanCarrierConfig(String key) {
Brad Ebinger16417b42017-03-07 13:48:50 -08001834 int[] subIds = SubscriptionManager.getSubId(mPhoneId);
1835 int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1836 if (subIds != null && subIds.length >= 1) {
1837 subId = subIds[0];
1838 }
1839 PersistableBundle b = null;
1840 if (mConfigManager != null) {
1841 // If an invalid subId is used, this bundle will contain default values.
1842 b = mConfigManager.getConfigForSubId(subId);
1843 }
1844 if (b != null) {
1845 return b.getBoolean(key);
1846 } else {
1847 // Return static default defined in CarrierConfigManager.
1848 return CarrierConfigManager.getDefaultConfig().getBoolean(key);
1849 }
1850 }
1851
1852 /**
fionaxu5803ef02016-03-08 11:48:48 -08001853 * Get the int config from carrier config manager.
1854 *
Brad Ebinger16417b42017-03-07 13:48:50 -08001855 * @param key config key defined in CarrierConfigManager
1856 * @return integer value of corresponding key.
1857 */
Brad Ebinger479f52c2017-08-28 13:19:22 -07001858 private int getIntCarrierConfig(String key) {
Brad Ebinger16417b42017-03-07 13:48:50 -08001859 int[] subIds = SubscriptionManager.getSubId(mPhoneId);
1860 int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1861 if (subIds != null && subIds.length >= 1) {
1862 subId = subIds[0];
1863 }
1864 PersistableBundle b = null;
1865 if (mConfigManager != null) {
1866 // If an invalid subId is used, this bundle will contain default values.
1867 b = mConfigManager.getConfigForSubId(subId);
1868 }
1869 if (b != null) {
1870 return b.getInt(key);
1871 } else {
1872 // Return static default defined in CarrierConfigManager.
1873 return CarrierConfigManager.getDefaultConfig().getInt(key);
1874 }
1875 }
1876
1877 /**
Wink Savilleef36ef62014-06-11 08:39:38 -07001878 * Gets the call ID from the specified incoming call broadcast intent.
1879 *
1880 * @param incomingCallIntent the incoming call broadcast intent
1881 * @return the call ID or null if the intent does not contain it
1882 */
1883 private static String getCallId(Intent incomingCallIntent) {
1884 if (incomingCallIntent == null) {
1885 return null;
1886 }
1887
1888 return incomingCallIntent.getStringExtra(EXTRA_CALL_ID);
1889 }
1890
1891 /**
1892 * Gets the service type from the specified incoming call broadcast intent.
1893 *
1894 * @param incomingCallIntent the incoming call broadcast intent
Brad Ebinger16780ff2017-01-26 11:18:21 -08001895 * @return the session identifier or -1 if the intent does not contain it
Wink Savilleef36ef62014-06-11 08:39:38 -07001896 */
Brad Ebinger16780ff2017-01-26 11:18:21 -08001897 private static int getImsSessionId(Intent incomingCallIntent) {
Wink Savilleef36ef62014-06-11 08:39:38 -07001898 if (incomingCallIntent == null) {
1899 return (-1);
1900 }
1901
1902 return incomingCallIntent.getIntExtra(EXTRA_SERVICE_ID, -1);
1903 }
1904
1905 /**
Brad Ebingerb10b61e2017-04-18 11:45:26 -07001906 * Checks to see if the ImsService Binder is connected. If it is not, we try to create the
1907 * connection again.
Wink Savilleef36ef62014-06-11 08:39:38 -07001908 */
1909 private void checkAndThrowExceptionIfServiceUnavailable()
1910 throws ImsException {
Brad Ebinger16780ff2017-01-26 11:18:21 -08001911 if (mImsServiceProxy == null || !mImsServiceProxy.isBinderAlive()) {
1912 createImsService();
Wink Savilleef36ef62014-06-11 08:39:38 -07001913
Brad Ebinger16780ff2017-01-26 11:18:21 -08001914 if (mImsServiceProxy == null) {
Wink Savilleef36ef62014-06-11 08:39:38 -07001915 throw new ImsException("Service is unavailable",
1916 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1917 }
1918 }
1919 }
1920
Brad Ebinger16780ff2017-01-26 11:18:21 -08001921 /**
1922 * Binds the IMS service to make/receive the call. Supports two methods of exposing an
1923 * ImsService:
1924 * 1) com.android.ims.ImsService implementation in ServiceManager (deprecated).
1925 * 2) android.telephony.ims.ImsService implementation through ImsResolver.
1926 */
1927 private void createImsService() {
1928 if (!mConfigDynamicBind) {
1929 // Old method of binding
1930 Rlog.i(TAG, "Creating ImsService using ServiceManager");
1931 mImsServiceProxy = getServiceProxyCompat();
1932 } else {
1933 Rlog.i(TAG, "Creating ImsService using ImsResolver");
1934 mImsServiceProxy = getServiceProxy();
1935 }
Brad Ebinger9a0280c2017-06-01 15:58:48 -07001936 // We have created a new ImsService connection, signal for re-registration
1937 synchronized (mHasRegisteredLock) {
1938 mHasRegisteredForProxy = false;
1939 }
Etan Cohend7727462014-07-12 14:54:10 -07001940 }
1941
Brad Ebinger16780ff2017-01-26 11:18:21 -08001942 // Deprecated method of binding with the ImsService defined in the ServiceManager.
1943 private ImsServiceProxyCompat getServiceProxyCompat() {
1944 IBinder binder = ServiceManager.checkService(IMS_SERVICE);
Wink Savilleef36ef62014-06-11 08:39:38 -07001945
Brad Ebinger16780ff2017-01-26 11:18:21 -08001946 if (binder != null) {
Wink Savilleef36ef62014-06-11 08:39:38 -07001947 try {
Brad Ebinger16780ff2017-01-26 11:18:21 -08001948 binder.linkToDeath(mDeathRecipient, 0);
Wink Savilleef36ef62014-06-11 08:39:38 -07001949 } catch (RemoteException e) {
1950 }
1951 }
1952
Brad Ebinger16780ff2017-01-26 11:18:21 -08001953 return new ImsServiceProxyCompat(mPhoneId, binder);
1954 }
1955
1956 // New method of binding with the ImsResolver
1957 private ImsServiceProxy getServiceProxy() {
1958 TelephonyManager tm = (TelephonyManager)
1959 mContext.getSystemService(Context.TELEPHONY_SERVICE);
1960 ImsServiceProxy serviceProxy = new ImsServiceProxy(mPhoneId, ImsFeature.MMTEL);
Brad Ebingerb10b61e2017-04-18 11:45:26 -07001961 serviceProxy.setStatusCallback(() -> mStatusCallbacks.forEach(
1962 ImsServiceProxy.INotifyStatusChanged::notifyStatusChanged));
Brad Ebinger16780ff2017-01-26 11:18:21 -08001963 // Returns null if the service is not available.
1964 IImsServiceController b = tm.getImsServiceControllerAndListen(mPhoneId,
1965 ImsFeature.MMTEL, serviceProxy.getListener());
1966 if (b != null) {
1967 serviceProxy.setBinder(b.asBinder());
Brad Ebinger16780ff2017-01-26 11:18:21 -08001968 // Trigger the cache to be updated for feature status.
1969 serviceProxy.getFeatureStatus();
Brad Ebinger16780ff2017-01-26 11:18:21 -08001970 } else {
1971 Rlog.w(TAG, "getServiceProxy: b is null! Phone Id: " + mPhoneId);
1972 }
1973 return serviceProxy;
Wink Savilleef36ef62014-06-11 08:39:38 -07001974 }
1975
1976 /**
1977 * Creates a {@link ImsCallSession} with the specified call profile.
1978 * Use other methods, if applicable, instead of interacting with
1979 * {@link ImsCallSession} directly.
1980 *
1981 * @param serviceId a service id which is obtained from {@link ImsManager#open}
1982 * @param profile a call profile to make the call
1983 */
1984 private ImsCallSession createCallSession(int serviceId,
1985 ImsCallProfile profile) throws ImsException {
1986 try {
Brad Ebingerb10b61e2017-04-18 11:45:26 -07001987 // Throws an exception if the ImsService Feature is not ready to accept commands.
Brad Ebinger16780ff2017-01-26 11:18:21 -08001988 return new ImsCallSession(mImsServiceProxy.createCallSession(serviceId, profile, null));
Wink Savilleef36ef62014-06-11 08:39:38 -07001989 } catch (RemoteException e) {
Brad Ebingerb10b61e2017-04-18 11:45:26 -07001990 Rlog.w(TAG, "CreateCallSession: Error, remote exception: " + e.getMessage());
1991 throw new ImsException("createCallSession()", e,
1992 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
1993
Wink Savilleef36ef62014-06-11 08:39:38 -07001994 }
1995 }
1996
Etan Cohena00c9192014-12-23 15:02:29 -08001997 private static void log(String s) {
Wink Savilleef36ef62014-06-11 08:39:38 -07001998 Rlog.d(TAG, s);
1999 }
2000
Etan Cohena00c9192014-12-23 15:02:29 -08002001 private static void loge(String s) {
Wink Savilleef36ef62014-06-11 08:39:38 -07002002 Rlog.e(TAG, s);
2003 }
2004
Etan Cohena00c9192014-12-23 15:02:29 -08002005 private static void loge(String s, Throwable t) {
Wink Savilleef36ef62014-06-11 08:39:38 -07002006 Rlog.e(TAG, s, t);
2007 }
2008
2009 /**
ram7da5a112014-07-16 20:59:27 +05302010 * Used for turning on IMS.if its off already
2011 */
Etan Cohen82f78122014-12-15 10:10:14 -08002012 private void turnOnIms() throws ImsException {
Etan Cohen0c9c09e2014-07-25 11:09:12 -07002013 checkAndThrowExceptionIfServiceUnavailable();
2014
ram7da5a112014-07-16 20:59:27 +05302015 try {
Brad Ebingerb5f30c72017-02-17 14:54:31 -08002016 mImsServiceProxy.turnOnIms();
ram7da5a112014-07-16 20:59:27 +05302017 } catch (RemoteException e) {
2018 throw new ImsException("turnOnIms() ", e, ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
2019 }
2020 }
2021
Omkar Kolangade75f3ca32014-10-24 11:10:52 -07002022 private boolean isImsTurnOffAllowed() {
Brad Ebinger479f52c2017-08-28 13:19:22 -07002023 return isTurnOffImsAllowedByPlatform()
2024 && (!isWfcEnabledByPlatform()
2025 || !isWfcEnabledByUser());
Omkar Kolangade75f3ca32014-10-24 11:10:52 -07002026 }
2027
Amit Mahajan9cba36d2016-08-11 10:17:23 -07002028 private void setLteFeatureValues(boolean turnOn) {
2029 log("setLteFeatureValues: " + turnOn);
Omkar Kolangade75f3ca32014-10-24 11:10:52 -07002030 try {
2031 ImsConfig config = getConfigInterface();
Amit Mahajan9cba36d2016-08-11 10:17:23 -07002032 if (config != null) {
Omkar Kolangade75f3ca32014-10-24 11:10:52 -07002033 config.setFeatureValue(ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE,
Pavel Zhamaitsiakf4b90322016-01-26 14:34:09 -08002034 TelephonyManager.NETWORK_TYPE_LTE, turnOn ? 1 : 0, mImsConfigListener);
Pavel Zhamaitsiakff29b9d2016-04-15 12:16:57 -07002035
Brad Ebinger479f52c2017-08-28 13:19:22 -07002036 if (isVolteEnabledByPlatform()) {
2037 boolean ignoreDataEnabledChanged = getBooleanCarrierConfig(
Jack Yu57781852016-11-16 17:20:38 -08002038 CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS);
Brad Ebinger479f52c2017-08-28 13:19:22 -07002039 boolean enableViLte = turnOn && isVtEnabledByUser() &&
Jack Yu57781852016-11-16 17:20:38 -08002040 (ignoreDataEnabledChanged || isDataEnabled());
Pavel Zhamaitsiakff29b9d2016-04-15 12:16:57 -07002041 config.setFeatureValue(ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_LTE,
2042 TelephonyManager.NETWORK_TYPE_LTE,
2043 enableViLte ? 1 : 0,
2044 mImsConfigListener);
2045 }
Etan Cohenb651fa52014-10-22 10:51:29 -07002046 }
Omkar Kolangade75f3ca32014-10-24 11:10:52 -07002047 } catch (ImsException e) {
Amit Mahajan9cba36d2016-08-11 10:17:23 -07002048 loge("setLteFeatureValues: exception ", e);
Etan Cohencfc784d2014-08-07 18:40:31 -07002049 }
Amit Mahajan9cba36d2016-08-11 10:17:23 -07002050 }
2051
2052 private void setAdvanced4GMode(boolean turnOn) throws ImsException {
2053 checkAndThrowExceptionIfServiceUnavailable();
2054
2055 // if turnOn: first set feature values then call turnOnIms()
2056 // if turnOff: only set feature values if IMS turn off is not allowed. If turn off is
2057 // allowed, first call turnOffIms() then set feature values
Etan Cohencfc784d2014-08-07 18:40:31 -07002058 if (turnOn) {
Amit Mahajan9cba36d2016-08-11 10:17:23 -07002059 setLteFeatureValues(turnOn);
2060 log("setAdvanced4GMode: turnOnIms");
Etan Cohencfc784d2014-08-07 18:40:31 -07002061 turnOnIms();
Amit Mahajan9cba36d2016-08-11 10:17:23 -07002062 } else {
2063 if (isImsTurnOffAllowed()) {
2064 log("setAdvanced4GMode: turnOffIms");
2065 turnOffIms();
2066 }
2067 setLteFeatureValues(turnOn);
Etan Cohencfc784d2014-08-07 18:40:31 -07002068 }
2069 }
2070
ram7da5a112014-07-16 20:59:27 +05302071 /**
2072 * Used for turning off IMS completely in order to make the device CSFB'ed.
2073 * Once turned off, all calls will be over CS.
2074 */
Etan Cohen82f78122014-12-15 10:10:14 -08002075 private void turnOffIms() throws ImsException {
Etan Cohen0c9c09e2014-07-25 11:09:12 -07002076 checkAndThrowExceptionIfServiceUnavailable();
2077
ram7da5a112014-07-16 20:59:27 +05302078 try {
Brad Ebingerb5f30c72017-02-17 14:54:31 -08002079 mImsServiceProxy.turnOffIms();
ram7da5a112014-07-16 20:59:27 +05302080 } catch (RemoteException e) {
2081 throw new ImsException("turnOffIms() ", e, ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
2082 }
2083 }
2084
Naveen Kalla525c3a22017-02-06 14:46:42 -08002085 private void addToRecentDisconnectReasons(ImsReasonInfo reason) {
2086 if (reason == null) return;
2087 while (mRecentDisconnectReasons.size() >= MAX_RECENT_DISCONNECT_REASONS) {
2088 mRecentDisconnectReasons.removeFirst();
2089 }
2090 mRecentDisconnectReasons.addLast(reason);
2091 }
2092
ram7da5a112014-07-16 20:59:27 +05302093 /**
Wink Savilleef36ef62014-06-11 08:39:38 -07002094 * Death recipient class for monitoring IMS service.
2095 */
2096 private class ImsServiceDeathRecipient implements IBinder.DeathRecipient {
2097 @Override
2098 public void binderDied() {
Brad Ebinger16780ff2017-01-26 11:18:21 -08002099 mImsServiceProxy = null;
Wink Savilleef36ef62014-06-11 08:39:38 -07002100 mUt = null;
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -05002101 mConfig = null;
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -07002102 mEcbm = null;
Tyler Gunn4d128b62016-04-13 15:44:38 -07002103 mMultiEndpoint = null;
Wink Savilleef36ef62014-06-11 08:39:38 -07002104 }
2105 }
2106
2107 /**
Brad Ebinger57b11892017-06-13 16:21:35 -07002108 * Stub implementation of the Registration listener that provides no functionality.
2109 */
2110 private class ImsRegistrationListenerBase extends IImsRegistrationListener.Stub {
2111
2112 @Override
2113 public void registrationConnected() throws RemoteException {
2114 }
2115
2116 @Override
2117 public void registrationProgressing() throws RemoteException {
2118 }
2119
2120 @Override
2121 public void registrationConnectedWithRadioTech(int imsRadioTech) throws RemoteException {
2122 }
2123
2124 @Override
2125 public void registrationProgressingWithRadioTech(int imsRadioTech) throws RemoteException {
2126 }
2127
2128 @Override
2129 public void registrationDisconnected(ImsReasonInfo imsReasonInfo) throws RemoteException {
2130 }
2131
2132 @Override
2133 public void registrationResumed() throws RemoteException {
2134 }
2135
2136 @Override
2137 public void registrationSuspended() throws RemoteException {
2138 }
2139
2140 @Override
2141 public void registrationServiceCapabilityChanged(int serviceClass, int event)
2142 throws RemoteException {
2143 }
2144
2145 @Override
2146 public void registrationFeatureCapabilityChanged(int serviceClass, int[] enabledFeatures,
2147 int[] disabledFeatures) throws RemoteException {
2148 }
2149
2150 @Override
2151 public void voiceMessageCountUpdate(int count) throws RemoteException {
2152 }
2153
2154 @Override
2155 public void registrationAssociatedUriChanged(Uri[] uris) throws RemoteException {
2156 }
2157
2158 @Override
2159 public void registrationChangeFailed(int targetAccessTech, ImsReasonInfo imsReasonInfo)
2160 throws RemoteException {
2161 }
2162 }
2163
2164 /**
Wink Savilleef36ef62014-06-11 08:39:38 -07002165 * Adapter class for {@link IImsRegistrationListener}.
2166 */
Naveen Kalla196fd3b2017-02-14 14:55:24 -08002167 private class ImsRegistrationListenerProxy extends IImsRegistrationListener.Stub {
Wink Savilleef36ef62014-06-11 08:39:38 -07002168
Omkar Kolangadea7ced642015-05-04 17:55:13 -07002169 @Deprecated
Wink Savilleef36ef62014-06-11 08:39:38 -07002170 public void registrationConnected() {
2171 if (DBG) {
2172 log("registrationConnected ::");
2173 }
2174
Brad Ebinger9a0280c2017-06-01 15:58:48 -07002175 synchronized (mRegistrationListeners) {
2176 mRegistrationListeners.forEach(l -> l.onImsConnected(
2177 ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN));
Wink Savilleef36ef62014-06-11 08:39:38 -07002178 }
2179 }
2180
Omkar Kolangadea7ced642015-05-04 17:55:13 -07002181 @Deprecated
Rekha Kumar14631742015-02-04 10:47:00 -08002182 public void registrationProgressing() {
Wink Savilleef36ef62014-06-11 08:39:38 -07002183 if (DBG) {
Rekha Kumar14631742015-02-04 10:47:00 -08002184 log("registrationProgressing ::");
Wink Savilleef36ef62014-06-11 08:39:38 -07002185 }
2186
Brad Ebinger9a0280c2017-06-01 15:58:48 -07002187 synchronized (mRegistrationListeners) {
2188 mRegistrationListeners.forEach(l -> l.onImsProgressing(
2189 ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN));
Rekha Kumar14631742015-02-04 10:47:00 -08002190 }
2191 }
2192
2193 @Override
Omkar Kolangadea7ced642015-05-04 17:55:13 -07002194 public void registrationConnectedWithRadioTech(int imsRadioTech) {
2195 // Note: imsRadioTech value maps to RIL_RADIO_TECHNOLOGY
2196 // values in ServiceState.java.
2197 if (DBG) {
2198 log("registrationConnectedWithRadioTech :: imsRadioTech=" + imsRadioTech);
2199 }
2200
Brad Ebinger9a0280c2017-06-01 15:58:48 -07002201 synchronized (mRegistrationListeners) {
2202 mRegistrationListeners.forEach(l -> l.onImsConnected(imsRadioTech));
Omkar Kolangadea7ced642015-05-04 17:55:13 -07002203 }
2204 }
2205
2206 @Override
2207 public void registrationProgressingWithRadioTech(int imsRadioTech) {
2208 // Note: imsRadioTech value maps to RIL_RADIO_TECHNOLOGY
2209 // values in ServiceState.java.
2210 if (DBG) {
2211 log("registrationProgressingWithRadioTech :: imsRadioTech=" + imsRadioTech);
2212 }
2213
Brad Ebinger9a0280c2017-06-01 15:58:48 -07002214 synchronized (mRegistrationListeners) {
2215 mRegistrationListeners.forEach(l -> l.onImsProgressing(imsRadioTech));
Omkar Kolangadea7ced642015-05-04 17:55:13 -07002216 }
2217 }
2218
2219 @Override
Rekha Kumar14631742015-02-04 10:47:00 -08002220 public void registrationDisconnected(ImsReasonInfo imsReasonInfo) {
2221 if (DBG) {
2222 log("registrationDisconnected :: imsReasonInfo" + imsReasonInfo);
2223 }
2224
Naveen Kalla525c3a22017-02-06 14:46:42 -08002225 addToRecentDisconnectReasons(imsReasonInfo);
Brad Ebinger9a0280c2017-06-01 15:58:48 -07002226 synchronized (mRegistrationListeners) {
2227 mRegistrationListeners.forEach(l -> l.onImsDisconnected(imsReasonInfo));
Wink Savilleef36ef62014-06-11 08:39:38 -07002228 }
2229 }
2230
2231 @Override
2232 public void registrationResumed() {
2233 if (DBG) {
2234 log("registrationResumed ::");
2235 }
2236
Brad Ebinger9a0280c2017-06-01 15:58:48 -07002237 synchronized (mRegistrationListeners) {
2238 mRegistrationListeners.forEach(ImsConnectionStateListener::onImsResumed);
Wink Savilleef36ef62014-06-11 08:39:38 -07002239 }
2240 }
2241
2242 @Override
2243 public void registrationSuspended() {
2244 if (DBG) {
2245 log("registrationSuspended ::");
2246 }
2247
Brad Ebinger9a0280c2017-06-01 15:58:48 -07002248 synchronized (mRegistrationListeners) {
2249 mRegistrationListeners.forEach(ImsConnectionStateListener::onImsSuspended);
Wink Savilleef36ef62014-06-11 08:39:38 -07002250 }
2251 }
2252
2253 @Override
2254 public void registrationServiceCapabilityChanged(int serviceClass, int event) {
2255 log("registrationServiceCapabilityChanged :: serviceClass=" +
2256 serviceClass + ", event=" + event);
2257
Brad Ebinger9a0280c2017-06-01 15:58:48 -07002258 synchronized (mRegistrationListeners) {
2259 mRegistrationListeners.forEach(l -> l.onImsConnected(
2260 ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN));
Wink Savilleef36ef62014-06-11 08:39:38 -07002261 }
2262 }
ram7da5a112014-07-16 20:59:27 +05302263
2264 @Override
2265 public void registrationFeatureCapabilityChanged(int serviceClass,
2266 int[] enabledFeatures, int[] disabledFeatures) {
2267 log("registrationFeatureCapabilityChanged :: serviceClass=" +
2268 serviceClass);
Brad Ebinger9a0280c2017-06-01 15:58:48 -07002269
2270 synchronized (mRegistrationListeners) {
2271 mRegistrationListeners.forEach(l -> l.onFeatureCapabilityChanged(serviceClass,
2272 enabledFeatures, disabledFeatures));
Libin.Tang@motorola.come2296782014-08-19 14:20:01 -05002273 }
ram7da5a112014-07-16 20:59:27 +05302274 }
2275
Shriram Ganeshd3adfad2015-05-31 10:06:15 -07002276 @Override
2277 public void voiceMessageCountUpdate(int count) {
2278 log("voiceMessageCountUpdate :: count=" + count);
2279
Brad Ebinger9a0280c2017-06-01 15:58:48 -07002280 synchronized (mRegistrationListeners) {
2281 mRegistrationListeners.forEach(l -> l.onVoiceMessageCountChanged(count));
Shriram Ganeshd3adfad2015-05-31 10:06:15 -07002282 }
2283 }
2284
Pavel Zhamaitsiak4de9cbb2016-02-11 17:21:05 -08002285 @Override
2286 public void registrationAssociatedUriChanged(Uri[] uris) {
2287 if (DBG) log("registrationAssociatedUriChanged ::");
2288
Brad Ebinger9a0280c2017-06-01 15:58:48 -07002289 synchronized (mRegistrationListeners) {
2290 mRegistrationListeners.forEach(l -> l.registrationAssociatedUriChanged(uris));
Pavel Zhamaitsiak4de9cbb2016-02-11 17:21:05 -08002291 }
2292 }
Meng Wangbb98b9b2016-12-07 16:27:15 -08002293
2294 @Override
2295 public void registrationChangeFailed(int targetAccessTech, ImsReasonInfo imsReasonInfo) {
2296 if (DBG) log("registrationChangeFailed :: targetAccessTech=" + targetAccessTech +
2297 ", imsReasonInfo=" + imsReasonInfo);
2298
Brad Ebinger9a0280c2017-06-01 15:58:48 -07002299 synchronized (mRegistrationListeners) {
2300 mRegistrationListeners.forEach(l -> l.onRegistrationChangeFailed(targetAccessTech,
2301 imsReasonInfo));
Meng Wangbb98b9b2016-12-07 16:27:15 -08002302 }
2303 }
Wink Savilleef36ef62014-06-11 08:39:38 -07002304 }
Tyler Gunn4d128b62016-04-13 15:44:38 -07002305
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -07002306 /**
2307 * Gets the ECBM interface to request ECBM exit.
2308 *
2309 * @param serviceId a service id which is obtained from {@link ImsManager#open}
2310 * @return the ECBM interface instance
2311 * @throws ImsException if getting the ECBM interface results in an error
2312 */
2313 public ImsEcbm getEcbmInterface(int serviceId) throws ImsException {
Brad Ebinger138b4a62017-06-20 16:29:50 -07002314 if (mEcbm != null && mEcbm.isBinderAlive()) {
2315 return mEcbm;
2316 }
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -07002317
Brad Ebinger138b4a62017-06-20 16:29:50 -07002318 checkAndThrowExceptionIfServiceUnavailable();
2319 try {
2320 IImsEcbm iEcbm = mImsServiceProxy.getEcbmInterface();
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -07002321
Brad Ebinger138b4a62017-06-20 16:29:50 -07002322 if (iEcbm == null) {
2323 throw new ImsException("getEcbmInterface()",
2324 ImsReasonInfo.CODE_ECBM_NOT_SUPPORTED);
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -07002325 }
Brad Ebinger138b4a62017-06-20 16:29:50 -07002326 mEcbm = new ImsEcbm(iEcbm);
2327 } catch (RemoteException e) {
2328 throw new ImsException("getEcbmInterface()", e,
2329 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
Uma Maheswari Ramalingam4f2161d2014-07-31 16:01:47 -07002330 }
2331 return mEcbm;
2332 }
Pavel Zhamaitsiak8c065f52015-11-10 14:36:44 -08002333
2334 /**
Tyler Gunn4d128b62016-04-13 15:44:38 -07002335 * Gets the Multi-Endpoint interface to subscribe to multi-enpoint notifications..
2336 *
2337 * @param serviceId a service id which is obtained from {@link ImsManager#open}
2338 * @return the multi-endpoint interface instance
2339 * @throws ImsException if getting the multi-endpoint interface results in an error
2340 */
2341 public ImsMultiEndpoint getMultiEndpointInterface(int serviceId) throws ImsException {
Brad Ebinger138b4a62017-06-20 16:29:50 -07002342 if (mMultiEndpoint != null && mMultiEndpoint.isBinderAlive()) {
2343 return mMultiEndpoint;
Tyler Gunn4d128b62016-04-13 15:44:38 -07002344 }
Brad Ebinger138b4a62017-06-20 16:29:50 -07002345
2346 checkAndThrowExceptionIfServiceUnavailable();
2347 try {
2348 IImsMultiEndpoint iImsMultiEndpoint = mImsServiceProxy.getMultiEndpointInterface();
2349
2350 if (iImsMultiEndpoint == null) {
2351 throw new ImsException("getMultiEndpointInterface()",
2352 ImsReasonInfo.CODE_MULTIENDPOINT_NOT_SUPPORTED);
2353 }
2354 mMultiEndpoint = new ImsMultiEndpoint(iImsMultiEndpoint);
2355 } catch (RemoteException e) {
2356 throw new ImsException("getMultiEndpointInterface()", e,
2357 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
2358 }
2359
Tyler Gunn4d128b62016-04-13 15:44:38 -07002360 return mMultiEndpoint;
2361 }
2362
2363 /**
Pavel Zhamaitsiak8c065f52015-11-10 14:36:44 -08002364 * Resets ImsManager settings back to factory defaults.
2365 *
Brad Ebinger479f52c2017-08-28 13:19:22 -07002366 * @deprecated Doesn't support MSIM devices. Use {@link #factoryReset()} instead.
Brad Ebinger16417b42017-03-07 13:48:50 -08002367 *
Pavel Zhamaitsiak8c065f52015-11-10 14:36:44 -08002368 * @hide
2369 */
2370 public static void factoryReset(Context context) {
Brad Ebinger479f52c2017-08-28 13:19:22 -07002371 ImsManager mgr = ImsManager.getInstance(context,
2372 SubscriptionManager.getDefaultVoicePhoneId());
2373 if (mgr != null) {
2374 mgr.factoryReset();
2375 }
2376 loge("factoryReset: ImsManager null.");
Pavel Zhamaitsiak8c065f52015-11-10 14:36:44 -08002377 }
Jack Yu2f102bd2015-12-28 15:31:48 -08002378
Brad Ebinger16417b42017-03-07 13:48:50 -08002379 /**
2380 * Resets ImsManager settings back to factory defaults.
2381 *
2382 * @hide
2383 */
Brad Ebinger479f52c2017-08-28 13:19:22 -07002384 public void factoryReset() {
Brad Ebinger16417b42017-03-07 13:48:50 -08002385 // Set VoLTE to default
2386 android.provider.Settings.Global.putInt(mContext.getContentResolver(),
2387 android.provider.Settings.Global.ENHANCED_4G_MODE_ENABLED,
2388 ImsConfig.FeatureValueConstants.ON);
2389
2390 // Set VoWiFi to default
2391 android.provider.Settings.Global.putInt(mContext.getContentResolver(),
2392 android.provider.Settings.Global.WFC_IMS_ENABLED,
Brad Ebinger479f52c2017-08-28 13:19:22 -07002393 getBooleanCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -08002394 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL) ?
2395 ImsConfig.FeatureValueConstants.ON : ImsConfig.FeatureValueConstants.OFF);
2396
2397 // Set VoWiFi mode to default
2398 android.provider.Settings.Global.putInt(mContext.getContentResolver(),
2399 android.provider.Settings.Global.WFC_IMS_MODE,
Brad Ebinger479f52c2017-08-28 13:19:22 -07002400 getIntCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -08002401 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT));
2402
2403 // Set VoWiFi roaming to default
2404 android.provider.Settings.Global.putInt(mContext.getContentResolver(),
2405 android.provider.Settings.Global.WFC_IMS_ROAMING_ENABLED,
Brad Ebinger479f52c2017-08-28 13:19:22 -07002406 getBooleanCarrierConfig(
Brad Ebinger16417b42017-03-07 13:48:50 -08002407 CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_ENABLED_BOOL) ?
2408 ImsConfig.FeatureValueConstants.ON : ImsConfig.FeatureValueConstants.OFF);
2409
2410 // Set VT to default
2411 android.provider.Settings.Global.putInt(mContext.getContentResolver(),
2412 android.provider.Settings.Global.VT_IMS_ENABLED,
2413 ImsConfig.FeatureValueConstants.ON);
2414
2415 // Push settings to ImsConfig
Brad Ebinger479f52c2017-08-28 13:19:22 -07002416 updateImsServiceConfig(true);
Brad Ebinger16417b42017-03-07 13:48:50 -08002417 }
2418
Amit Mahajan24f7b162016-07-21 16:33:53 -07002419 private boolean isDataEnabled() {
2420 return SystemProperties.getBoolean(DATA_ENABLED_PROP, true);
2421 }
2422
Jack Yu643ffe42016-07-08 14:25:46 -07002423 /**
2424 * Set data enabled/disabled flag.
2425 * @param enabled True if data is enabled, otherwise disabled.
2426 */
2427 public void setDataEnabled(boolean enabled) {
2428 log("setDataEnabled: " + enabled);
Amit Mahajan24f7b162016-07-21 16:33:53 -07002429 SystemProperties.set(DATA_ENABLED_PROP, enabled ? TRUE : FALSE);
2430 }
2431
2432 private boolean isVolteProvisioned() {
2433 return SystemProperties.getBoolean(VOLTE_PROVISIONED_PROP, true);
2434 }
2435
2436 private void setVolteProvisionedProperty(boolean provisioned) {
2437 SystemProperties.set(VOLTE_PROVISIONED_PROP, provisioned ? TRUE : FALSE);
2438 }
2439
2440 private boolean isWfcProvisioned() {
2441 return SystemProperties.getBoolean(WFC_PROVISIONED_PROP, true);
2442 }
2443
2444 private void setWfcProvisionedProperty(boolean provisioned) {
2445 SystemProperties.set(WFC_PROVISIONED_PROP, provisioned ? TRUE : FALSE);
2446 }
2447
2448 private boolean isVtProvisioned() {
2449 return SystemProperties.getBoolean(VT_PROVISIONED_PROP, true);
2450 }
2451
2452 private void setVtProvisionedProperty(boolean provisioned) {
2453 SystemProperties.set(VT_PROVISIONED_PROP, provisioned ? TRUE : FALSE);
Jack Yu643ffe42016-07-08 14:25:46 -07002454 }
2455
Jack Yu2f102bd2015-12-28 15:31:48 -08002456 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2457 pw.println("ImsManager:");
2458 pw.println(" mPhoneId = " + mPhoneId);
2459 pw.println(" mConfigUpdated = " + mConfigUpdated);
Brad Ebinger16780ff2017-01-26 11:18:21 -08002460 pw.println(" mImsServiceProxy = " + mImsServiceProxy);
Amit Mahajan24f7b162016-07-21 16:33:53 -07002461 pw.println(" mDataEnabled = " + isDataEnabled());
Brad Ebinger479f52c2017-08-28 13:19:22 -07002462 pw.println(" ignoreDataEnabledChanged = " + getBooleanCarrierConfig(
Jack Yu57781852016-11-16 17:20:38 -08002463 CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS));
Jack Yu2f102bd2015-12-28 15:31:48 -08002464
Brad Ebinger479f52c2017-08-28 13:19:22 -07002465 pw.println(" isGbaValid = " + isGbaValid());
Jack Yu2f102bd2015-12-28 15:31:48 -08002466 pw.println(" isImsTurnOffAllowed = " + isImsTurnOffAllowed());
Brad Ebinger479f52c2017-08-28 13:19:22 -07002467 pw.println(" isNonTtyOrTtyOnVolteEnabled = " + isNonTtyOrTtyOnVolteEnabled());
Jack Yu2f102bd2015-12-28 15:31:48 -08002468
Brad Ebinger479f52c2017-08-28 13:19:22 -07002469 pw.println(" isVolteEnabledByPlatform = " + isVolteEnabledByPlatform());
2470 pw.println(" isVolteProvisionedOnDevice = " + isVolteProvisionedOnDevice());
Jack Yu2f102bd2015-12-28 15:31:48 -08002471 pw.println(" isEnhanced4gLteModeSettingEnabledByUser = " +
Brad Ebinger479f52c2017-08-28 13:19:22 -07002472 isEnhanced4gLteModeSettingEnabledByUser());
2473 pw.println(" isVtEnabledByPlatform = " + isVtEnabledByPlatform());
2474 pw.println(" isVtEnabledByUser = " + isVtEnabledByUser());
Jack Yu2f102bd2015-12-28 15:31:48 -08002475
Brad Ebinger479f52c2017-08-28 13:19:22 -07002476 pw.println(" isWfcEnabledByPlatform = " + isWfcEnabledByPlatform());
2477 pw.println(" isWfcEnabledByUser = " + isWfcEnabledByUser());
2478 pw.println(" getWfcMode = " + getWfcMode());
2479 pw.println(" isWfcRoamingEnabledByUser = " + isWfcRoamingEnabledByUser());
Jack Yu2f102bd2015-12-28 15:31:48 -08002480
Brad Ebinger479f52c2017-08-28 13:19:22 -07002481 pw.println(" isVtProvisionedOnDevice = " + isVtProvisionedOnDevice());
2482 pw.println(" isWfcProvisionedOnDevice = " + isWfcProvisionedOnDevice());
Jack Yu2f102bd2015-12-28 15:31:48 -08002483 pw.flush();
2484 }
Wink Savilleef36ef62014-06-11 08:39:38 -07002485}