Home | History | Annotate | Download | only in ims
      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