1 /* 2 * Copyright 2017 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 17 package com.android.internal.telephony.ims; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.fail; 21 import static org.mockito.ArgumentMatchers.eq; 22 import static org.mockito.Mockito.anyInt; 23 import static org.mockito.Mockito.anyString; 24 import static org.mockito.Mockito.doReturn; 25 import static org.mockito.Mockito.timeout; 26 import static org.mockito.Mockito.times; 27 import static org.mockito.Mockito.verify; 28 import static org.mockito.Mockito.when; 29 30 import android.os.IBinder; 31 import android.os.PersistableBundle; 32 import android.telephony.CarrierConfigManager; 33 import android.telephony.SubscriptionManager; 34 import android.telephony.ims.stub.ImsConfigImplBase; 35 import android.test.suitebuilder.annotation.SmallTest; 36 37 import com.android.ims.ImsConfig; 38 import com.android.ims.ImsManager; 39 import com.android.ims.MmTelFeatureConnection; 40 import com.android.internal.telephony.TelephonyTest; 41 42 import org.junit.After; 43 import org.junit.Before; 44 import org.junit.Test; 45 import org.mockito.Mock; 46 47 import java.util.Hashtable; 48 49 public class ImsManagerTest extends TelephonyTest { 50 private static final String UNSET_PROVISIONED_STRING = "unset"; 51 private static final boolean ENHANCED_4G_MODE_DEFAULT_VAL = true; 52 private static final boolean ENHANCED_4G_MODE_EDITABLE = true; 53 private static final boolean WFC_IMS_ENABLE_DEFAULT_VAL = false; 54 private static final boolean WFC_IMS_ROAMING_ENABLE_DEFAULT_VAL = true; 55 private static final boolean VT_IMS_ENABLE_DEFAULT_VAL = true; 56 private static final boolean WFC_IMS_EDITABLE_VAL = true; 57 private static final boolean WFC_IMS_NOT_EDITABLE_VAL = false; 58 private static final int WFC_IMS_MODE_DEFAULT_VAL = 59 ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED; 60 private static final int WFC_IMS_ROAMING_MODE_DEFAULT_VAL = 61 ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED; 62 63 PersistableBundle mBundle; 64 @Mock IBinder mBinder; 65 @Mock ImsConfigImplBase mImsConfigImplBaseMock; 66 Hashtable<Integer, Integer> mProvisionedIntVals = new Hashtable<>(); 67 Hashtable<Integer, String> mProvisionedStringVals = new Hashtable<>(); 68 ImsConfigImplBase.ImsConfigStub mImsConfigStub; 69 @Mock MmTelFeatureConnection mMmTelFeatureConnection; 70 71 private final int[] mSubId = {0}; 72 private int mPhoneId; 73 74 @Before 75 public void setUp() throws Exception { 76 super.setUp("SubscriptionControllerTest"); 77 mPhoneId = mPhone.getPhoneId(); 78 mBundle = mContextFixture.getCarrierConfigBundle(); 79 80 doReturn(mSubId).when(mSubscriptionController).getSubId(mPhoneId); 81 82 doReturn(mSubscriptionController).when(mBinder).queryLocalInterface(anyString()); 83 mServiceManagerMockedServices.put("isub", mBinder); 84 85 doReturn(true).when(mMmTelFeatureConnection).isBinderAlive(); 86 87 mImsManagerInstances.remove(mPhoneId); 88 89 setDefaultValues(); 90 } 91 92 @After 93 public void tearDown() throws Exception { 94 super.tearDown(); 95 } 96 97 private void setDefaultValues() { 98 mBundle.putBoolean(CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL, 99 ENHANCED_4G_MODE_EDITABLE); 100 mBundle.putBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL, 101 WFC_IMS_EDITABLE_VAL); 102 mBundle.putBoolean(CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL, 103 WFC_IMS_ENABLE_DEFAULT_VAL); 104 mBundle.putBoolean(CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_ENABLED_BOOL, 105 WFC_IMS_ROAMING_ENABLE_DEFAULT_VAL); 106 mBundle.putInt(CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT, 107 WFC_IMS_MODE_DEFAULT_VAL); 108 mBundle.putInt(CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_MODE_INT, 109 WFC_IMS_ROAMING_MODE_DEFAULT_VAL); 110 mBundle.putBoolean(CarrierConfigManager.KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL, 111 ENHANCED_4G_MODE_DEFAULT_VAL); 112 mBundle.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL, true); 113 } 114 115 @Test @SmallTest 116 public void testGetDefaultValues() { 117 doReturn("-1").when(mSubscriptionController) 118 .getSubscriptionProperty(anyInt(), anyString(), anyString()); 119 120 ImsManager imsManager = ImsManager.getInstance(mContext, mPhoneId); 121 122 assertEquals(WFC_IMS_ENABLE_DEFAULT_VAL, imsManager.isWfcEnabledByUser()); 123 verify(mSubscriptionController, times(1)).getSubscriptionProperty( 124 anyInt(), 125 eq(SubscriptionManager.WFC_IMS_ENABLED), 126 anyString()); 127 128 assertEquals(ENHANCED_4G_MODE_DEFAULT_VAL, 129 imsManager.isEnhanced4gLteModeSettingEnabledByUser()); 130 verify(mSubscriptionController, times(1)).getSubscriptionProperty( 131 anyInt(), 132 eq(SubscriptionManager.ENHANCED_4G_MODE_ENABLED), 133 anyString()); 134 135 assertEquals(WFC_IMS_MODE_DEFAULT_VAL, imsManager.getWfcMode(false)); 136 verify(mSubscriptionController, times(1)).getSubscriptionProperty( 137 anyInt(), 138 eq(SubscriptionManager.WFC_IMS_MODE), 139 anyString()); 140 141 assertEquals(WFC_IMS_ROAMING_MODE_DEFAULT_VAL, imsManager.getWfcMode(true)); 142 verify(mSubscriptionController, times(1)).getSubscriptionProperty( 143 anyInt(), 144 eq(SubscriptionManager.WFC_IMS_ROAMING_MODE), 145 anyString()); 146 147 assertEquals(VT_IMS_ENABLE_DEFAULT_VAL, imsManager.isVtEnabledByUser()); 148 verify(mSubscriptionController, times(1)).getSubscriptionProperty( 149 anyInt(), 150 eq(SubscriptionManager.VT_IMS_ENABLED), 151 anyString()); 152 } 153 154 @Test @SmallTest 155 public void testSetValues() { 156 ImsManager imsManager = ImsManager.getInstance(mContext, mPhoneId); 157 158 imsManager.setWfcMode(ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED); 159 verify(mSubscriptionController, times(1)).setSubscriptionProperty( 160 eq(mSubId[0]), 161 eq(SubscriptionManager.WFC_IMS_MODE), 162 eq("1")); 163 164 imsManager.setWfcMode(ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED, true); 165 verify(mSubscriptionController, times(1)).setSubscriptionProperty( 166 eq(mSubId[0]), 167 eq(SubscriptionManager.WFC_IMS_ROAMING_MODE), 168 eq("1")); 169 170 imsManager.setVtSetting(false); 171 verify(mSubscriptionController, times(1)).setSubscriptionProperty( 172 eq(mSubId[0]), 173 eq(SubscriptionManager.VT_IMS_ENABLED), 174 eq("0")); 175 176 // enhanced 4g mode must be editable to use setEnhanced4gLteModeSetting 177 mBundle.putBoolean(CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL, 178 ENHANCED_4G_MODE_EDITABLE); 179 imsManager.setEnhanced4gLteModeSetting(true); 180 verify(mSubscriptionController, times(1)).setSubscriptionProperty( 181 eq(mSubId[0]), 182 eq(SubscriptionManager.ENHANCED_4G_MODE_ENABLED), 183 eq("1")); 184 185 imsManager.setWfcSetting(true); 186 verify(mSubscriptionController, times(1)).setSubscriptionProperty( 187 eq(mSubId[0]), 188 eq(SubscriptionManager.WFC_IMS_ENABLED), 189 eq("1")); 190 } 191 @Test 192 public void testGetProvisionedValues() throws Exception { 193 ImsManager imsManager = initializeProvisionedValues(); 194 195 assertEquals(true, imsManager.isWfcProvisionedOnDevice()); 196 verify(mImsConfigImplBaseMock, times(1)).getConfigInt( 197 eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED)); 198 199 assertEquals(true, imsManager.isVtProvisionedOnDevice()); 200 verify(mImsConfigImplBaseMock, times(1)).getConfigInt( 201 eq(ImsConfig.ConfigConstants.LVC_SETTING_ENABLED)); 202 203 assertEquals(true, imsManager.isVolteProvisionedOnDevice()); 204 verify(mImsConfigImplBaseMock, times(1)).getConfigInt( 205 eq(ImsConfig.ConfigConstants.VLT_SETTING_ENABLED)); 206 207 // If we call get again, times should still be one because the value should be fetched 208 // from cache. 209 assertEquals(true, imsManager.isWfcProvisionedOnDevice()); 210 verify(mImsConfigImplBaseMock, times(1)).getConfigInt( 211 eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED)); 212 213 assertEquals(true, imsManager.isVtProvisionedOnDevice()); 214 verify(mImsConfigImplBaseMock, times(1)).getConfigInt( 215 eq(ImsConfig.ConfigConstants.LVC_SETTING_ENABLED)); 216 217 assertEquals(true, imsManager.isVolteProvisionedOnDevice()); 218 verify(mImsConfigImplBaseMock, times(1)).getConfigInt( 219 eq(ImsConfig.ConfigConstants.VLT_SETTING_ENABLED)); 220 } 221 222 @Test 223 public void testSetProvisionedValues() throws Exception { 224 ImsManager imsManager = initializeProvisionedValues(); 225 226 assertEquals(true, imsManager.isWfcProvisionedOnDevice()); 227 verify(mImsConfigImplBaseMock, times(1)).getConfigInt( 228 eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED)); 229 230 imsManager.getConfigInterface().setProvisionedValue( 231 ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED, 232 ImsConfig.FeatureValueConstants.OFF); 233 234 assertEquals(0, (int) mProvisionedIntVals.get( 235 ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED)); 236 237 assertEquals(false, imsManager.isWfcProvisionedOnDevice()); 238 239 verify(mImsConfigImplBaseMock, times(1)).setConfig( 240 eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED), 241 eq(0)); 242 verify(mImsConfigImplBaseMock, times(1)).getConfigInt( 243 eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED)); 244 245 } 246 247 /** 248 * Tests that when a WFC mode is set for home/roaming, that setting is sent to the ImsService 249 * correctly. 250 * 251 * Preconditions: 252 * - CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL = true 253 */ 254 @Test @SmallTest 255 public void testSetWfcSetting_true_shouldSetWfcModeWrtRoamingState() throws Exception { 256 // First, Set WFC home/roaming mode that is not the Carrier Config default. 257 doReturn(String.valueOf(ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED)) 258 .when(mSubscriptionController).getSubscriptionProperty( 259 anyInt(), 260 eq(SubscriptionManager.WFC_IMS_MODE), 261 anyString()); 262 doReturn(String.valueOf(ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED)) 263 .when(mSubscriptionController).getSubscriptionProperty( 264 anyInt(), 265 eq(SubscriptionManager.WFC_IMS_ROAMING_MODE), 266 anyString()); 267 ImsManager imsManager = initializeProvisionedValues(); 268 269 // Roaming 270 doReturn(true).when(mTelephonyManager).isNetworkRoaming(eq(mSubId[0])); 271 // Turn on WFC 272 imsManager.setWfcSetting(true); 273 // Roaming mode (CELLULAR_PREFERRED) should be set. With 1000 ms timeout. 274 verify(mImsConfigImplBaseMock, timeout(1000)).setConfig( 275 eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_MODE), 276 eq(ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED)); 277 278 // Not roaming 279 doReturn(false).when(mTelephonyManager).isNetworkRoaming(eq(mSubId[0])); 280 // Turn on WFC 281 imsManager.setWfcSetting(true); 282 // Home mode (WIFI_PREFERRED) should be set. With 1000 ms timeout. 283 verify(mImsConfigImplBaseMock, timeout(1000)).setConfig( 284 eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_MODE), 285 eq(ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED)); 286 } 287 288 /** 289 * Tests that the settings for WFC mode are ignored if the Carrier sets the settings to not 290 * editable. 291 * 292 * Preconditions: 293 * - CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL = false 294 */ 295 @Test @SmallTest 296 public void testSetWfcSetting_wfcNotEditable() throws Exception { 297 mBundle.putBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL, 298 WFC_IMS_NOT_EDITABLE_VAL); 299 // Set some values that are different than the defaults for WFC mode. 300 doReturn(String.valueOf(ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY)) 301 .when(mSubscriptionController).getSubscriptionProperty( 302 anyInt(), 303 eq(SubscriptionManager.WFC_IMS_MODE), 304 anyString()); 305 doReturn(String.valueOf(ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY)) 306 .when(mSubscriptionController).getSubscriptionProperty( 307 anyInt(), 308 eq(SubscriptionManager.WFC_IMS_ROAMING_MODE), 309 anyString()); 310 ImsManager imsManager = initializeProvisionedValues(); 311 312 // Roaming 313 doReturn(true).when(mTelephonyManager).isNetworkRoaming(eq(mSubId[0])); 314 // Turn on WFC 315 imsManager.setWfcSetting(true); 316 // User defined setting for Roaming mode (WIFI_ONLY) should be set independent of whether or 317 // not WFC mode is editable. With 1000 ms timeout. 318 verify(mImsConfigImplBaseMock, timeout(1000)).setConfig( 319 eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_MODE), 320 eq(ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY)); 321 322 // Not roaming 323 doReturn(false).when(mTelephonyManager).isNetworkRoaming(eq(mSubId[0])); 324 // Turn on WFC 325 imsManager.setWfcSetting(true); 326 // Default Home mode (CELLULAR_PREFERRED) should be set. With 1000 ms timeout. 327 verify(mImsConfigImplBaseMock, timeout(1000)).setConfig( 328 eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_MODE), 329 eq(WFC_IMS_MODE_DEFAULT_VAL)); 330 } 331 332 /** 333 * Tests that the CarrierConfig defaults will be used if no setting is set in the Subscription 334 * Manager. 335 * 336 * Preconditions: 337 * - CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL = true 338 * - CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT = Carrier preferred 339 * - CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_MODE_INT = WiFi preferred 340 */ 341 @Test @SmallTest 342 public void testSetWfcSetting_noUserSettingSet() throws Exception { 343 ImsManager imsManager = initializeProvisionedValues(); 344 345 // Roaming 346 doReturn(true).when(mTelephonyManager).isNetworkRoaming(eq(mSubId[0])); 347 // Turn on WFC 348 imsManager.setWfcSetting(true); 349 350 // Default Roaming mode (WIFI_PREFERRED) for carrier should be set. With 1000 ms timeout. 351 verify(mImsConfigImplBaseMock, timeout(1000)).setConfig( 352 eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_MODE), 353 eq(WFC_IMS_ROAMING_MODE_DEFAULT_VAL)); 354 355 // Not roaming 356 doReturn(false).when(mTelephonyManager).isNetworkRoaming(eq(mSubId[0])); 357 // Turn on WFC 358 imsManager.setWfcSetting(true); 359 360 // Default Home mode (CELLULAR_PREFERRED) for carrier should be set. With 1000 ms timeout. 361 verify(mImsConfigImplBaseMock, timeout(1000)).setConfig( 362 eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_MODE), 363 eq(WFC_IMS_MODE_DEFAULT_VAL)); 364 } 365 366 private ImsManager initializeProvisionedValues() throws Exception { 367 when(mImsConfigImplBaseMock.getConfigInt(anyInt())) 368 .thenAnswer(invocation -> { 369 return getProvisionedInt((Integer) (invocation.getArguments()[0])); 370 }); 371 372 when(mImsConfigImplBaseMock.setConfig(anyInt(), anyInt())) 373 .thenAnswer(invocation -> { 374 mProvisionedIntVals.put((Integer) (invocation.getArguments()[0]), 375 (Integer) (invocation.getArguments()[1])); 376 return ImsConfig.OperationStatusConstants.SUCCESS; 377 }); 378 379 380 // Configure ImsConfigStub 381 mImsConfigStub = new ImsConfigImplBase.ImsConfigStub(mImsConfigImplBaseMock); 382 doReturn(mImsConfigStub).when(mMmTelFeatureConnection).getConfigInterface(); 383 384 // Configure ImsManager 385 ImsManager imsManager = ImsManager.getInstance(mContext, mPhoneId); 386 try { 387 replaceInstance(ImsManager.class, "mMmTelFeatureConnection", imsManager, 388 mMmTelFeatureConnection); 389 } catch (Exception ex) { 390 fail("failed with " + ex); 391 } 392 393 return imsManager; 394 } 395 396 // If the value is ever set, return the set value. If not, return a constant value 1000. 397 private int getProvisionedInt(int item) { 398 if (mProvisionedIntVals.containsKey(item)) { 399 return mProvisionedIntVals.get(item); 400 } else { 401 return ImsConfig.FeatureValueConstants.ON; 402 } 403 } 404 405 // If the value is ever set, return the set value. If not, return a constant value "unset". 406 private String getProvisionedString(int item) { 407 if (mProvisionedStringVals.containsKey(item)) { 408 return mProvisionedStringVals.get(item); 409 } else { 410 return UNSET_PROVISIONED_STRING; 411 } 412 } 413 } 414