1 /* 2 * Copyright (C) 2018 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 android.telephony.ims; 18 19 import static junit.framework.Assert.assertEquals; 20 import static junit.framework.Assert.assertFalse; 21 import static junit.framework.Assert.assertNull; 22 import static junit.framework.Assert.assertTrue; 23 import static junit.framework.Assert.fail; 24 25 import static org.junit.Assert.assertNotNull; 26 import static org.mockito.Matchers.eq; 27 import static org.mockito.Mockito.mock; 28 import static org.mockito.Mockito.never; 29 import static org.mockito.Mockito.times; 30 import static org.mockito.Mockito.verify; 31 import static org.mockito.Mockito.when; 32 33 import android.content.Context; 34 import android.content.Intent; 35 import android.os.IBinder; 36 import android.os.RemoteException; 37 import android.telephony.ims.aidl.IImsMmTelFeature; 38 import android.telephony.ims.aidl.IImsServiceController; 39 import android.telephony.ims.feature.ImsFeature; 40 import android.telephony.ims.feature.MmTelFeature; 41 import android.telephony.ims.stub.ImsFeatureConfiguration; 42 import android.test.suitebuilder.annotation.SmallTest; 43 44 import androidx.test.runner.AndroidJUnit4; 45 46 import com.android.ims.internal.IImsFeatureStatusCallback; 47 48 import org.junit.After; 49 import org.junit.Before; 50 import org.junit.Test; 51 import org.junit.runner.RunWith; 52 53 /** 54 * Unit tests for ImsService 55 */ 56 @RunWith(AndroidJUnit4.class) 57 public class ImsServiceTest { 58 59 private static final int TEST_SLOT_0 = 0; 60 private static final int TEST_SLOT_1 = 1; 61 private static final int TEST_SUB_2 = 2; 62 private static final int TEST_SUB_3 = 3; 63 64 private TestImsServiceCompat mTestImsServiceCompat; 65 private TestImsService mTestImsService; 66 private IImsServiceController mTestImsServiceCompatBinder; 67 private IImsServiceController mTestImsServiceBinder; 68 69 private Context mMockContext; 70 private IImsFeatureStatusCallback mTestCallback; 71 private IBinder mImsFeatureStatusCallbackBinder; 72 73 @Before setUp()74 public void setUp() throws Exception { 75 mMockContext = mock(Context.class); 76 mTestCallback = mock(IImsFeatureStatusCallback.class); 77 mImsFeatureStatusCallbackBinder = mock(IBinder.class); 78 when(mTestCallback.asBinder()).thenReturn(mImsFeatureStatusCallbackBinder); 79 // Create an ImsService that uses slotId and not subId to test compatibility. 80 mTestImsServiceCompat = new TestImsServiceCompat(mMockContext); 81 mTestImsServiceCompatBinder = (IImsServiceController) mTestImsServiceCompat.onBind( 82 new Intent(ImsService.SERVICE_INTERFACE)); 83 84 mTestImsService = new TestImsService(mMockContext); 85 mTestImsServiceBinder = (IImsServiceController) mTestImsService.onBind( 86 new Intent(ImsService.SERVICE_INTERFACE)); 87 } 88 89 @After tearDown()90 public void tearDown() throws Exception { 91 mMockContext = null; 92 mTestCallback = null; 93 mTestImsServiceCompat = null; 94 mTestImsServiceCompatBinder = null; 95 mTestImsService = null; 96 mTestImsServiceBinder = null; 97 } 98 99 @Test 100 @SmallTest testCreateMMTelFeatureCompat()101 public void testCreateMMTelFeatureCompat() throws RemoteException { 102 IImsMmTelFeature f = mTestImsServiceCompatBinder.createMmTelFeature(TEST_SLOT_0, 103 TEST_SUB_2); 104 mTestImsServiceCompatBinder.addFeatureStatusCallback(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL, 105 mTestCallback); 106 mTestImsServiceCompat.mTestMmTelFeature.sendSetFeatureState(ImsFeature.STATE_READY); 107 108 ImsFeature featureToVerify = mTestImsServiceCompat.getImsFeature(TEST_SLOT_0, 109 ImsFeature.FEATURE_MMTEL); 110 MmTelFeature testMMTelFeature = null; 111 if (featureToVerify instanceof MmTelFeature) { 112 testMMTelFeature = (MmTelFeature) featureToVerify; 113 } else { 114 fail(); 115 } 116 assertTrue(mTestImsServiceCompat.isImsFeatureCreatedForSlot(TEST_SLOT_0, 117 ImsFeature.FEATURE_MMTEL)); 118 assertEquals(mTestImsServiceCompat.mSpyMmTelFeature, testMMTelFeature); 119 // Verify that upon creating a feature, we assign the callback and get the set feature state 120 // when querying it. 121 verify(mTestImsServiceCompat.mSpyMmTelFeature) 122 .addImsFeatureStatusCallback(eq(mTestCallback)); 123 assertEquals(ImsFeature.STATE_READY, f.getFeatureState()); 124 } 125 126 @Test 127 @SmallTest testNotCreateMMTelFeatureCompat()128 public void testNotCreateMMTelFeatureCompat() throws RemoteException { 129 IImsMmTelFeature f = mTestImsServiceCompatBinder.createMmTelFeature(TEST_SLOT_0, 130 TEST_SUB_2); 131 mTestImsServiceCompatBinder.addFeatureStatusCallback(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL, 132 mTestCallback); 133 mTestImsServiceCompat.mTestMmTelFeature.sendSetFeatureState(ImsFeature.STATE_READY); 134 135 ImsFeature featureToVerify = mTestImsServiceCompat.getImsFeature(TEST_SLOT_0, 136 ImsFeature.FEATURE_MMTEL); 137 MmTelFeature testMMTelFeature = null; 138 if (featureToVerify instanceof MmTelFeature) { 139 testMMTelFeature = (MmTelFeature) featureToVerify; 140 } else { 141 fail(); 142 } 143 assertTrue(mTestImsServiceCompat.isImsFeatureCreatedForSlot(TEST_SLOT_0, 144 ImsFeature.FEATURE_MMTEL)); 145 assertEquals(mTestImsServiceCompat.mSpyMmTelFeature, testMMTelFeature); 146 // Verify that upon creating a feature, we assign the callback and get the set feature state 147 // when querying it. 148 verify(mTestImsServiceCompat.mSpyMmTelFeature) 149 .addImsFeatureStatusCallback(eq(mTestCallback)); 150 assertEquals(ImsFeature.STATE_READY, f.getFeatureState()); 151 // Ensures feature is not created if already have one. 152 IImsMmTelFeature f2 = mTestImsServiceCompatBinder.createMmTelFeature(TEST_SLOT_0, 153 TEST_SUB_3); 154 mTestImsServiceCompatBinder.addFeatureStatusCallback(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL, 155 mTestCallback); 156 assertEquals(mTestImsServiceCompat.createMmtelfeatureCount, 1); 157 verify(mTestImsServiceCompat.mSpyMmTelFeature, times(2)) 158 .addImsFeatureStatusCallback(eq(mTestCallback)); 159 } 160 161 @Test 162 @SmallTest testRemoveMMTelFeatureCompat()163 public void testRemoveMMTelFeatureCompat() throws RemoteException { 164 mTestImsServiceCompatBinder.createMmTelFeature(TEST_SLOT_0, TEST_SUB_2); 165 mTestImsServiceCompatBinder.addFeatureStatusCallback(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL, 166 mTestCallback); 167 assertTrue(mTestImsServiceCompat.isImsFeatureCreatedForSlot(TEST_SLOT_0, 168 ImsFeature.FEATURE_MMTEL)); 169 170 mTestImsServiceCompatBinder.removeFeatureStatusCallback(TEST_SLOT_0, 171 ImsFeature.FEATURE_MMTEL, mTestCallback); 172 mTestImsServiceCompatBinder.removeImsFeature(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL, false); 173 174 verify(mTestImsServiceCompat.mSpyMmTelFeature).onFeatureRemoved(); 175 verify(mTestImsServiceCompat.mSpyMmTelFeature).removeImsFeatureStatusCallback( 176 mTestCallback); 177 assertNull(mTestImsServiceCompat.getImsFeature(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL)); 178 assertFalse(mTestImsServiceCompat.isImsFeatureCreatedForSlot(TEST_SLOT_0, 179 ImsFeature.FEATURE_MMTEL)); 180 } 181 182 @Test 183 @SmallTest testNotRemoveMMTelFeatureCompat()184 public void testNotRemoveMMTelFeatureCompat() throws RemoteException { 185 mTestImsServiceCompatBinder.createMmTelFeature(TEST_SLOT_0, TEST_SUB_2); 186 mTestImsServiceCompatBinder.addFeatureStatusCallback(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL, 187 mTestCallback); 188 assertTrue(mTestImsServiceCompat.isImsFeatureCreatedForSlot(TEST_SLOT_0, 189 ImsFeature.FEATURE_MMTEL)); 190 191 mTestImsServiceCompatBinder.removeFeatureStatusCallback(TEST_SLOT_0, 192 ImsFeature.FEATURE_MMTEL, mTestCallback); 193 mTestImsServiceCompatBinder.removeImsFeature(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL, true); 194 // make sure the feature is not removed because it is created with slot ID so is not 195 // affected by sub ID changing 196 verify(mTestImsServiceCompat.mSpyMmTelFeature, never()).onFeatureRemoved(); 197 verify(mTestImsServiceCompat.mSpyMmTelFeature).removeImsFeatureStatusCallback( 198 mTestCallback); 199 assertNotNull(mTestImsServiceCompat.getImsFeature(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL)); 200 assertTrue(mTestImsServiceCompat.isImsFeatureCreatedForSlot(TEST_SLOT_0, 201 ImsFeature.FEATURE_MMTEL)); 202 } 203 204 @Test 205 @SmallTest testCreateMMTelFeature()206 public void testCreateMMTelFeature() throws RemoteException { 207 IImsMmTelFeature f = mTestImsServiceBinder.createMmTelFeature(TEST_SLOT_0, TEST_SUB_2); 208 mTestImsServiceBinder.addFeatureStatusCallback(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL, 209 mTestCallback); 210 mTestImsService.mTestMmTelFeature.sendSetFeatureState(ImsFeature.STATE_READY); 211 212 ImsFeature featureToVerify = mTestImsService.getImsFeature(TEST_SLOT_0, 213 ImsFeature.FEATURE_MMTEL); 214 MmTelFeature testMMTelFeature = null; 215 if (featureToVerify instanceof MmTelFeature) { 216 testMMTelFeature = (MmTelFeature) featureToVerify; 217 } else { 218 fail(); 219 } 220 assertFalse(mTestImsServiceCompat.isImsFeatureCreatedForSlot(TEST_SLOT_0, 221 ImsFeature.FEATURE_MMTEL)); 222 assertEquals(mTestImsService.mSpyMmTelFeature, testMMTelFeature); 223 // Verify that upon creating a feature, we assign the callback and get the set feature state 224 // when querying it. 225 verify(mTestImsService.mSpyMmTelFeature).addImsFeatureStatusCallback(eq(mTestCallback)); 226 assertEquals(ImsFeature.STATE_READY, f.getFeatureState()); 227 } 228 229 @Test 230 @SmallTest testRemoveMMTelFeature()231 public void testRemoveMMTelFeature() throws RemoteException { 232 mTestImsServiceBinder.createMmTelFeature(TEST_SLOT_0, TEST_SUB_2); 233 mTestImsServiceBinder.addFeatureStatusCallback(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL, 234 mTestCallback); 235 236 mTestImsServiceBinder.removeFeatureStatusCallback(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL, 237 mTestCallback); 238 mTestImsServiceBinder.removeImsFeature(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL, true); 239 240 verify(mTestImsService.mSpyMmTelFeature).onFeatureRemoved(); 241 verify(mTestImsService.mSpyMmTelFeature).removeImsFeatureStatusCallback(mTestCallback); 242 assertNull(mTestImsService.getImsFeature(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL)); 243 } 244 245 @Test 246 @SmallTest testCallMethodOnCreatedFeature()247 public void testCallMethodOnCreatedFeature() throws RemoteException { 248 IImsMmTelFeature f = mTestImsServiceBinder.createMmTelFeature(TEST_SLOT_0, TEST_SUB_2); 249 mTestImsServiceBinder.addFeatureStatusCallback(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL, 250 mTestCallback); 251 252 f.getUtInterface(); 253 254 assertTrue(mTestImsService.mTestMmTelFeature.isUtInterfaceCalled); 255 } 256 257 /** 258 * Tests that the ImsService will return the correct ImsFeatureConfiguration when queried. 259 */ 260 @Test 261 @SmallTest testQuerySupportedImsFeatures()262 public void testQuerySupportedImsFeatures() throws RemoteException { 263 ImsFeatureConfiguration config = new ImsFeatureConfiguration.Builder() 264 .addFeature(0, ImsFeature.FEATURE_MMTEL) 265 .addFeature(0, ImsFeature.FEATURE_RCS) 266 .build(); 267 mTestImsService.testFeatureConfig = config; 268 269 ImsFeatureConfiguration result = mTestImsServiceBinder.querySupportedImsFeatures(); 270 271 assertEquals(config, result); 272 } 273 274 /** 275 * Tests that ImsService capability sanitization works correctly. 276 */ 277 @Test 278 @SmallTest testCapsSanitized()279 public void testCapsSanitized() throws RemoteException { 280 long validCaps = ImsService.CAPABILITY_SIP_DELEGATE_CREATION; 281 // emergency over MMTEL should not be set here, but rather internally in Telephony. 282 long invalidCaps = 0xDEADBEEF00000000L | ImsService.CAPABILITY_EMERGENCY_OVER_MMTEL; 283 invalidCaps |= validCaps; 284 285 mTestImsService.testCaps = validCaps; 286 assertEquals(validCaps, mTestImsServiceBinder.getImsServiceCapabilities()); 287 mTestImsService.testCaps = invalidCaps; 288 // The extra bits should have been removed, leaving only the valid remaining 289 assertEquals(validCaps, mTestImsServiceBinder.getImsServiceCapabilities()); 290 } 291 } 292