blob: fd19f806f3c7674a7b3884b21b012916c761ad00 [file] [log] [blame]
/*
* Copyright 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.telephony.ims;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.os.IBinder;
import android.os.PersistableBundle;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
import android.telephony.ims.stub.ImsConfigImplBase;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.ims.ImsConfig;
import com.android.ims.ImsManager;
import com.android.ims.MmTelFeatureConnection;
import com.android.internal.telephony.TelephonyTest;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import java.util.Hashtable;
public class ImsManagerTest extends TelephonyTest {
private static final String UNSET_PROVISIONED_STRING = "unset";
private static final boolean ENHANCED_4G_MODE_DEFAULT_VAL = true;
private static final boolean ENHANCED_4G_MODE_EDITABLE = true;
private static final boolean WFC_IMS_ENABLE_DEFAULT_VAL = false;
private static final boolean WFC_IMS_ROAMING_ENABLE_DEFAULT_VAL = true;
private static final boolean VT_IMS_ENABLE_DEFAULT_VAL = true;
private static final boolean WFC_IMS_EDITABLE_VAL = true;
private static final boolean WFC_IMS_NOT_EDITABLE_VAL = false;
private static final int WFC_IMS_MODE_DEFAULT_VAL =
ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED;
private static final int WFC_IMS_ROAMING_MODE_DEFAULT_VAL =
ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED;
PersistableBundle mBundle;
@Mock
IBinder mBinder;
@Mock
ImsConfigImplBase mImsConfigImplBaseMock;
Hashtable<Integer, Integer> mProvisionedIntVals = new Hashtable<>();
Hashtable<Integer, String> mProvisionedStringVals = new Hashtable<>();
ImsConfigImplBase.ImsConfigStub mImsConfigStub;
@Mock MmTelFeatureConnection mMmTelFeatureConnection;
private final int[] mSubId = {0};
private int mPhoneId;
@Before
public void setUp() throws Exception {
super.setUp("SubscriptionControllerTest");
mPhoneId = mPhone.getPhoneId();
mBundle = mContextFixture.getCarrierConfigBundle();
doReturn(mSubId).when(mSubscriptionController).getSubId(mPhoneId);
doReturn(mSubscriptionController).when(mBinder).queryLocalInterface(anyString());
mServiceManagerMockedServices.put("isub", mBinder);
doReturn(true).when(mMmTelFeatureConnection).isBinderAlive();
mImsManagerInstances.remove(mPhoneId);
setDefaultValues();
}
@After
public void tearDown() throws Exception {
super.tearDown();
}
private void setDefaultValues() {
mBundle.putBoolean(CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL,
ENHANCED_4G_MODE_EDITABLE);
mBundle.putBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL,
WFC_IMS_EDITABLE_VAL);
mBundle.putBoolean(CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL,
WFC_IMS_ENABLE_DEFAULT_VAL);
mBundle.putBoolean(CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_ENABLED_BOOL,
WFC_IMS_ROAMING_ENABLE_DEFAULT_VAL);
mBundle.putInt(CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT,
WFC_IMS_MODE_DEFAULT_VAL);
mBundle.putInt(CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_MODE_INT,
WFC_IMS_ROAMING_MODE_DEFAULT_VAL);
mBundle.putBoolean(CarrierConfigManager.KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL,
ENHANCED_4G_MODE_DEFAULT_VAL);
mBundle.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL, true);
}
@Test @SmallTest
public void testGetDefaultValues() {
doReturn("-1").when(mSubscriptionController)
.getSubscriptionProperty(anyInt(), anyString(), anyString());
ImsManager imsManager = ImsManager.getInstance(mContext, mPhoneId);
assertEquals(WFC_IMS_ENABLE_DEFAULT_VAL, imsManager.isWfcEnabledByUser());
verify(mSubscriptionController, times(1)).getSubscriptionProperty(
anyInt(),
eq(SubscriptionManager.WFC_IMS_ENABLED),
anyString());
assertEquals(ENHANCED_4G_MODE_DEFAULT_VAL,
imsManager.isEnhanced4gLteModeSettingEnabledByUser());
verify(mSubscriptionController, times(1)).getSubscriptionProperty(
anyInt(),
eq(SubscriptionManager.ENHANCED_4G_MODE_ENABLED),
anyString());
assertEquals(WFC_IMS_MODE_DEFAULT_VAL, imsManager.getWfcMode(false));
verify(mSubscriptionController, times(1)).getSubscriptionProperty(
anyInt(),
eq(SubscriptionManager.WFC_IMS_MODE),
anyString());
assertEquals(WFC_IMS_ROAMING_MODE_DEFAULT_VAL, imsManager.getWfcMode(true));
verify(mSubscriptionController, times(1)).getSubscriptionProperty(
anyInt(),
eq(SubscriptionManager.WFC_IMS_ROAMING_MODE),
anyString());
assertEquals(VT_IMS_ENABLE_DEFAULT_VAL, imsManager.isVtEnabledByUser());
verify(mSubscriptionController, times(1)).getSubscriptionProperty(
anyInt(),
eq(SubscriptionManager.VT_IMS_ENABLED),
anyString());
}
@Test @SmallTest
public void testSetValues() {
ImsManager imsManager = ImsManager.getInstance(mContext, mPhoneId);
imsManager.setWfcMode(ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED);
verify(mSubscriptionController, times(1)).setSubscriptionProperty(
eq(mSubId[0]),
eq(SubscriptionManager.WFC_IMS_MODE),
eq("1"));
imsManager.setWfcMode(ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED, true);
verify(mSubscriptionController, times(1)).setSubscriptionProperty(
eq(mSubId[0]),
eq(SubscriptionManager.WFC_IMS_ROAMING_MODE),
eq("1"));
imsManager.setVtSetting(false);
verify(mSubscriptionController, times(1)).setSubscriptionProperty(
eq(mSubId[0]),
eq(SubscriptionManager.VT_IMS_ENABLED),
eq("0"));
// enhanced 4g mode must be editable to use setEnhanced4gLteModeSetting
mBundle.putBoolean(CarrierConfigManager.KEY_EDITABLE_ENHANCED_4G_LTE_BOOL,
ENHANCED_4G_MODE_EDITABLE);
imsManager.setEnhanced4gLteModeSetting(true);
verify(mSubscriptionController, times(1)).setSubscriptionProperty(
eq(mSubId[0]),
eq(SubscriptionManager.ENHANCED_4G_MODE_ENABLED),
eq("1"));
imsManager.setWfcSetting(true);
verify(mSubscriptionController, times(1)).setSubscriptionProperty(
eq(mSubId[0]),
eq(SubscriptionManager.WFC_IMS_ENABLED),
eq("1"));
}
@Test
public void testGetProvisionedValues() throws Exception {
ImsManager imsManager = initializeProvisionedValues();
assertEquals(true, imsManager.isWfcProvisionedOnDevice());
verify(mImsConfigImplBaseMock, times(1)).getConfigInt(
eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED));
assertEquals(true, imsManager.isVtProvisionedOnDevice());
verify(mImsConfigImplBaseMock, times(1)).getConfigInt(
eq(ImsConfig.ConfigConstants.LVC_SETTING_ENABLED));
assertEquals(true, imsManager.isVolteProvisionedOnDevice());
verify(mImsConfigImplBaseMock, times(1)).getConfigInt(
eq(ImsConfig.ConfigConstants.VLT_SETTING_ENABLED));
// If we call get again, times should still be one because the value should be fetched
// from cache.
assertEquals(true, imsManager.isWfcProvisionedOnDevice());
verify(mImsConfigImplBaseMock, times(1)).getConfigInt(
eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED));
assertEquals(true, imsManager.isVtProvisionedOnDevice());
verify(mImsConfigImplBaseMock, times(1)).getConfigInt(
eq(ImsConfig.ConfigConstants.LVC_SETTING_ENABLED));
assertEquals(true, imsManager.isVolteProvisionedOnDevice());
verify(mImsConfigImplBaseMock, times(1)).getConfigInt(
eq(ImsConfig.ConfigConstants.VLT_SETTING_ENABLED));
}
@Test
public void testSetProvisionedValues() throws Exception {
ImsManager imsManager = initializeProvisionedValues();
assertEquals(true, imsManager.isWfcProvisionedOnDevice());
verify(mImsConfigImplBaseMock, times(1)).getConfigInt(
eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED));
imsManager.getConfigInterface().setProvisionedValue(
ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED,
ImsConfig.FeatureValueConstants.OFF);
assertEquals(0, (int) mProvisionedIntVals.get(
ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED));
assertEquals(false, imsManager.isWfcProvisionedOnDevice());
verify(mImsConfigImplBaseMock, times(1)).setConfig(
eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED),
eq(0));
verify(mImsConfigImplBaseMock, times(1)).getConfigInt(
eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED));
}
/**
* Tests that when a WFC mode is set for home/roaming, that setting is sent to the ImsService
* correctly.
*
* Preconditions:
* - CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL = true
*/
@Test @SmallTest
public void testSetWfcSetting_true_shouldSetWfcModeWrtRoamingState() throws Exception {
// First, Set WFC home/roaming mode that is not the Carrier Config default.
doReturn(String.valueOf(ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED))
.when(mSubscriptionController).getSubscriptionProperty(
anyInt(),
eq(SubscriptionManager.WFC_IMS_MODE),
anyString());
doReturn(String.valueOf(ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED))
.when(mSubscriptionController).getSubscriptionProperty(
anyInt(),
eq(SubscriptionManager.WFC_IMS_ROAMING_MODE),
anyString());
ImsManager imsManager = initializeProvisionedValues();
// Roaming
doReturn(true).when(mTelephonyManager).isNetworkRoaming(eq(mSubId[0]));
// Turn on WFC
imsManager.setWfcSetting(true);
// Roaming mode (CELLULAR_PREFERRED) should be set. With 1000 ms timeout.
verify(mImsConfigImplBaseMock, timeout(1000)).setConfig(
eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_MODE),
eq(ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED));
// Not roaming
doReturn(false).when(mTelephonyManager).isNetworkRoaming(eq(mSubId[0]));
// Turn on WFC
imsManager.setWfcSetting(true);
// Home mode (WIFI_PREFERRED) should be set. With 1000 ms timeout.
verify(mImsConfigImplBaseMock, timeout(1000)).setConfig(
eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_MODE),
eq(ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED));
}
/**
* Tests that the settings for WFC mode are ignored if the Carrier sets the settings to not
* editable.
*
* Preconditions:
* - CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL = false
*/
@Test @SmallTest
public void testSetWfcSetting_wfcNotEditable() throws Exception {
mBundle.putBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL,
WFC_IMS_NOT_EDITABLE_VAL);
// Set some values that are different than the defaults for WFC mode.
doReturn(String.valueOf(ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY))
.when(mSubscriptionController).getSubscriptionProperty(
anyInt(),
eq(SubscriptionManager.WFC_IMS_MODE),
anyString());
doReturn(String.valueOf(ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY))
.when(mSubscriptionController).getSubscriptionProperty(
anyInt(),
eq(SubscriptionManager.WFC_IMS_ROAMING_MODE),
anyString());
ImsManager imsManager = initializeProvisionedValues();
// Roaming
doReturn(true).when(mTelephonyManager).isNetworkRoaming(eq(mSubId[0]));
// Turn on WFC
imsManager.setWfcSetting(true);
// User defined setting for Roaming mode (WIFI_ONLY) should be set independent of whether or
// not WFC mode is editable. With 1000 ms timeout.
verify(mImsConfigImplBaseMock, timeout(1000)).setConfig(
eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_MODE),
eq(ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY));
// Not roaming
doReturn(false).when(mTelephonyManager).isNetworkRoaming(eq(mSubId[0]));
// Turn on WFC
imsManager.setWfcSetting(true);
// Default Home mode (CELLULAR_PREFERRED) should be set. With 1000 ms timeout.
verify(mImsConfigImplBaseMock, timeout(1000)).setConfig(
eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_MODE),
eq(WFC_IMS_MODE_DEFAULT_VAL));
}
/**
* Tests that the CarrierConfig defaults will be used if no setting is set in the Subscription
* Manager.
*
* Preconditions:
* - CarrierConfigManager.KEY_EDITABLE_WFC_MODE_BOOL = true
* - CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT = Carrier preferred
* - CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_MODE_INT = WiFi preferred
*/
@Test @SmallTest
public void testSetWfcSetting_noUserSettingSet() throws Exception {
ImsManager imsManager = initializeProvisionedValues();
// Roaming
doReturn(true).when(mTelephonyManager).isNetworkRoaming(eq(mSubId[0]));
// Turn on WFC
imsManager.setWfcSetting(true);
// Default Roaming mode (WIFI_PREFERRED) for carrier should be set. With 1000 ms timeout.
verify(mImsConfigImplBaseMock, timeout(1000)).setConfig(
eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_MODE),
eq(WFC_IMS_ROAMING_MODE_DEFAULT_VAL));
// Not roaming
doReturn(false).when(mTelephonyManager).isNetworkRoaming(eq(mSubId[0]));
// Turn on WFC
imsManager.setWfcSetting(true);
// Default Home mode (CELLULAR_PREFERRED) for carrier should be set. With 1000 ms timeout.
verify(mImsConfigImplBaseMock, timeout(1000)).setConfig(
eq(ImsConfig.ConfigConstants.VOICE_OVER_WIFI_MODE),
eq(WFC_IMS_MODE_DEFAULT_VAL));
}
private ImsManager initializeProvisionedValues() throws Exception {
when(mImsConfigImplBaseMock.getConfigInt(anyInt()))
.thenAnswer(invocation -> {
return getProvisionedInt((Integer) (invocation.getArguments()[0]));
});
when(mImsConfigImplBaseMock.setConfig(anyInt(), anyInt()))
.thenAnswer(invocation -> {
mProvisionedIntVals.put((Integer) (invocation.getArguments()[0]),
(Integer) (invocation.getArguments()[1]));
return ImsConfig.OperationStatusConstants.SUCCESS;
});
// Configure ImsConfigStub
mImsConfigStub = new ImsConfigImplBase.ImsConfigStub(mImsConfigImplBaseMock);
doReturn(mImsConfigStub).when(mMmTelFeatureConnection).getConfigInterface();
// Configure ImsManager
ImsManager imsManager = ImsManager.getInstance(mContext, mPhoneId);
try {
replaceInstance(ImsManager.class, "mMmTelFeatureConnection", imsManager,
mMmTelFeatureConnection);
} catch (Exception ex) {
fail("failed with " + ex);
}
return imsManager;
}
// If the value is ever set, return the set value. If not, return a constant value 1000.
private int getProvisionedInt(int item) {
if (mProvisionedIntVals.containsKey(item)) {
return mProvisionedIntVals.get(item);
} else {
return ImsConfig.FeatureValueConstants.ON;
}
}
// If the value is ever set, return the set value. If not, return a constant value "unset".
private String getProvisionedString(int item) {
if (mProvisionedStringVals.containsKey(item)) {
return mProvisionedStringVals.get(item);
} else {
return UNSET_PROVISIONED_STRING;
}
}
}