CreateConnectionProcessorTest.java revision a3799ae6aafba8ccd6448a7c4337acd3460b49f2
1/* 2 * Copyright (C) 2015 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.server.telecom.tests; 18 19import android.content.ComponentName; 20import android.graphics.drawable.Icon; 21import android.net.Uri; 22import android.os.Binder; 23import android.os.Debug; 24import android.telecom.DisconnectCause; 25import android.telecom.PhoneAccount; 26import android.telecom.PhoneAccountHandle; 27import android.test.suitebuilder.annotation.SmallTest; 28 29import com.android.server.telecom.Call; 30import com.android.server.telecom.CallIdMapper; 31import com.android.server.telecom.ConnectionServiceRepository; 32import com.android.server.telecom.ConnectionServiceWrapper; 33import com.android.server.telecom.CreateConnectionProcessor; 34import com.android.server.telecom.CreateConnectionResponse; 35import com.android.server.telecom.PhoneAccountRegistrar; 36 37import org.mockito.Mock; 38import org.mockito.MockitoAnnotations; 39 40import java.util.ArrayList; 41 42import static org.mockito.Matchers.any; 43import static org.mockito.Matchers.eq; 44import static org.mockito.Mockito.mock; 45import static org.mockito.Mockito.never; 46import static org.mockito.Mockito.reset; 47import static org.mockito.Mockito.verify; 48import static org.mockito.Mockito.when; 49 50/** 51 * Unit testing for CreateConnectionProcessor as well as CreateConnectionTimeout classes. 52 */ 53public class CreateConnectionProcessorTest extends TelecomTestCase { 54 55 private static final String TEST_PACKAGE = "com.android.server.telecom.tests"; 56 private static final String TEST_CLASS = 57 "com.android.server.telecom.tests.MockConnectionService"; 58 59 @Mock 60 ConnectionServiceRepository mMockConnectionServiceRepository; 61 @Mock 62 PhoneAccountRegistrar mMockAccountRegistrar; 63 @Mock 64 CreateConnectionResponse mMockCreateConnectionResponse; 65 @Mock 66 Call mMockCall; 67 68 CreateConnectionProcessor mTestCreateConnectionProcessor; 69 70 @Override 71 public void setUp() throws Exception { 72 super.setUp(); 73 MockitoAnnotations.initMocks(this); 74 mContext = mComponentContextFixture.getTestDouble().getApplicationContext(); 75 76 mTestCreateConnectionProcessor = new CreateConnectionProcessor(mMockCall, 77 mMockConnectionServiceRepository, mMockCreateConnectionResponse, 78 mMockAccountRegistrar, mContext); 79 } 80 81 @Override 82 public void tearDown() throws Exception { 83 mTestCreateConnectionProcessor = null; 84 super.tearDown(); 85 } 86 87 @SmallTest 88 public void testSimPhoneAccountSuccess() throws Exception { 89 PhoneAccountHandle pAHandle = getNewTargetPhoneAccountHandle("tel_acct"); 90 when(mMockCall.isEmergencyCall()).thenReturn(false); 91 // No Connection Manager in this case 92 when(mMockAccountRegistrar.getSimCallManagerFromCall(any(Call.class))).thenReturn(null); 93 ConnectionServiceWrapper service = makeConnectionServiceWrapper(); 94 95 mTestCreateConnectionProcessor.process(); 96 97 verify(mMockCall).setConnectionManagerPhoneAccount(eq(pAHandle)); 98 verify(mMockCall).setTargetPhoneAccount(eq(pAHandle)); 99 verify(mMockCall).setConnectionService(eq(service)); 100 verify(service).createConnection(eq(mMockCall), any(CreateConnectionResponse.class)); 101 // Notify successful connection to call 102 CallIdMapper mockCallIdMapper = mock(CallIdMapper.class); 103 mTestCreateConnectionProcessor.handleCreateConnectionSuccess(mockCallIdMapper, null); 104 verify(mMockCreateConnectionResponse).handleCreateConnectionSuccess(mockCallIdMapper, null); 105 } 106 107 @SmallTest 108 public void testbadPhoneAccount() throws Exception { 109 PhoneAccountHandle pAHandle = null; 110 when(mMockCall.isEmergencyCall()).thenReturn(false); 111 when(mMockCall.getTargetPhoneAccount()).thenReturn(pAHandle); 112 givePhoneAccountBindPermission(pAHandle); 113 // No Connection Manager in this case 114 when(mMockAccountRegistrar.getSimCallManagerFromCall(any(Call.class))).thenReturn(null); 115 ConnectionServiceWrapper service = makeConnectionServiceWrapper(); 116 117 mTestCreateConnectionProcessor.process(); 118 119 verify(service, never()).createConnection(eq(mMockCall), 120 any(CreateConnectionResponse.class)); 121 verify(mMockCreateConnectionResponse).handleCreateConnectionFailure( 122 eq(new DisconnectCause(DisconnectCause.ERROR))); 123 } 124 125 @SmallTest 126 public void testConnectionManagerSuccess() throws Exception { 127 PhoneAccountHandle pAHandle = getNewTargetPhoneAccountHandle("tel_acct"); 128 when(mMockCall.isEmergencyCall()).thenReturn(false); 129 // Include a Connection Manager 130 PhoneAccountHandle callManagerPAHandle = getNewConnectionMangerHandle("cm_acct"); 131 ConnectionServiceWrapper service = makeConnectionServiceWrapper(); 132 // Make sure the target phone account has the correct permissions 133 PhoneAccount mFakeTargetPhoneAccount = makeQuickAccount("cm_acct", 134 PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION); 135 when(mMockAccountRegistrar.getPhoneAccountUnchecked(pAHandle)).thenReturn( 136 mFakeTargetPhoneAccount); 137 138 mTestCreateConnectionProcessor.process(); 139 140 verify(mMockCall).setConnectionManagerPhoneAccount(eq(callManagerPAHandle)); 141 verify(mMockCall).setTargetPhoneAccount(eq(pAHandle)); 142 verify(mMockCall).setConnectionService(eq(service)); 143 verify(service).createConnection(eq(mMockCall), any(CreateConnectionResponse.class)); 144 // Notify successful connection to call 145 CallIdMapper mockCallIdMapper = mock(CallIdMapper.class); 146 mTestCreateConnectionProcessor.handleCreateConnectionSuccess(mockCallIdMapper, null); 147 verify(mMockCreateConnectionResponse).handleCreateConnectionSuccess(mockCallIdMapper, null); 148 } 149 150 @SmallTest 151 public void testConnectionManagerFailedFallToSim() throws Exception { 152 PhoneAccountHandle pAHandle = getNewTargetPhoneAccountHandle("tel_acct"); 153 when(mMockCall.isEmergencyCall()).thenReturn(false); 154 // Include a Connection Manager 155 PhoneAccountHandle callManagerPAHandle = getNewConnectionMangerHandle("cm_acct"); 156 ConnectionServiceWrapper service = makeConnectionServiceWrapper(); 157 when(mMockCall.getConnectionManagerPhoneAccount()).thenReturn(callManagerPAHandle); 158 PhoneAccount mFakeTargetPhoneAccount = makeQuickAccount("cm_acct", 159 PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION); 160 when(mMockAccountRegistrar.getPhoneAccountUnchecked(pAHandle)).thenReturn( 161 mFakeTargetPhoneAccount); 162 when(mMockCall.getConnectionService()).thenReturn(service); 163 // Put CreateConnectionProcessor in correct state to fail with ConnectionManager 164 mTestCreateConnectionProcessor.process(); 165 reset(mMockCall); 166 reset(service); 167 168 // Notify that the ConnectionManager has denied the call. 169 when(mMockCall.getConnectionManagerPhoneAccount()).thenReturn(callManagerPAHandle); 170 when(mMockCall.getConnectionService()).thenReturn(service); 171 mTestCreateConnectionProcessor.handleCreateConnectionFailure( 172 new DisconnectCause(DisconnectCause.CONNECTION_MANAGER_NOT_SUPPORTED)); 173 174 // Verify that the Sim Phone Account is used correctly 175 verify(mMockCall).setConnectionManagerPhoneAccount(eq(pAHandle)); 176 verify(mMockCall).setTargetPhoneAccount(eq(pAHandle)); 177 verify(mMockCall).setConnectionService(eq(service)); 178 verify(service).createConnection(eq(mMockCall), any(CreateConnectionResponse.class)); 179 // Notify successful connection to call 180 CallIdMapper mockCallIdMapper = mock(CallIdMapper.class); 181 mTestCreateConnectionProcessor.handleCreateConnectionSuccess(mockCallIdMapper, null); 182 verify(mMockCreateConnectionResponse).handleCreateConnectionSuccess(mockCallIdMapper, null); 183 } 184 185 @SmallTest 186 public void testConnectionManagerFailedDoNotFallToSim() throws Exception { 187 PhoneAccountHandle pAHandle = getNewTargetPhoneAccountHandle("tel_acct"); 188 when(mMockCall.isEmergencyCall()).thenReturn(false); 189 // Include a Connection Manager 190 PhoneAccountHandle callManagerPAHandle = getNewConnectionMangerHandle("cm_acct"); 191 ConnectionServiceWrapper service = makeConnectionServiceWrapper(); 192 when(mMockCall.getConnectionManagerPhoneAccount()).thenReturn(callManagerPAHandle); 193 PhoneAccount mFakeTargetPhoneAccount = makeQuickAccount("cm_acct", 194 PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION); 195 when(mMockAccountRegistrar.getPhoneAccountUnchecked(pAHandle)).thenReturn( 196 mFakeTargetPhoneAccount); 197 when(mMockCall.getConnectionService()).thenReturn(service); 198 // Put CreateConnectionProcessor in correct state to fail with ConnectionManager 199 mTestCreateConnectionProcessor.process(); 200 reset(mMockCall); 201 reset(service); 202 203 // Notify that the ConnectionManager has rejected the call. 204 when(mMockCall.getConnectionManagerPhoneAccount()).thenReturn(callManagerPAHandle); 205 when(mMockCall.getConnectionService()).thenReturn(service); 206 when(service.isServiceValid("createConnection")).thenReturn(true); 207 mTestCreateConnectionProcessor.handleCreateConnectionFailure( 208 new DisconnectCause(DisconnectCause.OTHER)); 209 210 // Verify call connection rejected 211 verify(mMockCreateConnectionResponse).handleCreateConnectionFailure( 212 new DisconnectCause(DisconnectCause.OTHER)); 213 } 214 215 @SmallTest 216 public void testEmergencyCallToSim() throws Exception { 217 when(mMockCall.isEmergencyCall()).thenReturn(true); 218 // Put in a regular phone account to be sure it doesn't call that 219 PhoneAccountHandle pAHandle = getNewTargetPhoneAccountHandle("tel_acct"); 220 // Include a Connection Manager to be sure it doesn't call that 221 PhoneAccount callManagerPA = getNewConnectionManagerPhoneAccount("cm_acct", 0); 222 ConnectionServiceWrapper service = makeConnectionServiceWrapper(); 223 PhoneAccount emergencyPhoneAccount = makeEmergencyPhoneAccount("tel_emer"); 224 PhoneAccountHandle emergencyPhoneAccountHandle = emergencyPhoneAccount.getAccountHandle(); 225 226 mTestCreateConnectionProcessor.process(); 227 228 verify(mMockCall).setConnectionManagerPhoneAccount(eq(emergencyPhoneAccountHandle)); 229 verify(mMockCall).setTargetPhoneAccount(eq(emergencyPhoneAccountHandle)); 230 verify(mMockCall).setConnectionService(eq(service)); 231 verify(service).createConnection(eq(mMockCall), any(CreateConnectionResponse.class)); 232 // Notify successful connection to call 233 CallIdMapper mockCallIdMapper = mock(CallIdMapper.class); 234 mTestCreateConnectionProcessor.handleCreateConnectionSuccess(mockCallIdMapper, null); 235 verify(mMockCreateConnectionResponse).handleCreateConnectionSuccess(mockCallIdMapper, null); 236 } 237 238 @SmallTest 239 public void testEmergencyCallSimFailToConnectionManager() throws Exception { 240 when(mMockCall.isEmergencyCall()).thenReturn(true); 241 when(mMockCall.getHandle()).thenReturn(Uri.parse("")); 242 // Put in a regular phone account to be sure it doesn't call that 243 PhoneAccountHandle pAHandle = getNewTargetPhoneAccountHandle("tel_acct"); 244 when(mMockAccountRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser( 245 any(String.class))).thenReturn(pAHandle); 246 // Include a normal Connection Manager to be sure it doesn't call that 247 PhoneAccount callManagerPA = getNewConnectionManagerPhoneAccount("cm_acct", 0); 248 // Include a connection Manager for the user with the capability to make calls 249 PhoneAccount emerCallManagerPA = getNewEmergencyConnectionManagerPhoneAccount("cm_acct", 250 PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS); 251 ConnectionServiceWrapper service = makeConnectionServiceWrapper(); 252 PhoneAccount emergencyPhoneAccount = makeEmergencyPhoneAccount("tel_emer"); 253 mTestCreateConnectionProcessor.process(); 254 reset(mMockCall); 255 reset(service); 256 when(mMockCall.isEmergencyCall()).thenReturn(true); 257 258 // When Notify SIM connection fails, fall back to connection manager 259 mTestCreateConnectionProcessor.handleCreateConnectionFailure(new DisconnectCause( 260 DisconnectCause.REJECTED)); 261 262 verify(mMockCall).setConnectionManagerPhoneAccount( 263 eq(emerCallManagerPA.getAccountHandle())); 264 verify(mMockCall).setTargetPhoneAccount(eq(pAHandle)); 265 verify(mMockCall).setConnectionService(eq(service)); 266 verify(service).createConnection(eq(mMockCall), any(CreateConnectionResponse.class)); 267 } 268 269 private PhoneAccount makeEmergencyPhoneAccount(String id) { 270 final PhoneAccount emergencyPhoneAccount = makeQuickAccount(id, 271 PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS | 272 PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION); 273 PhoneAccountHandle emergencyPhoneAccountHandle = emergencyPhoneAccount.getAccountHandle(); 274 givePhoneAccountBindPermission(emergencyPhoneAccountHandle); 275 ArrayList<PhoneAccount> phoneAccounts = new ArrayList<PhoneAccount>() {{ 276 add(emergencyPhoneAccount); 277 }}; 278 when(mMockAccountRegistrar.getAllPhoneAccountsOfCurrentUser()).thenReturn(phoneAccounts); 279 return emergencyPhoneAccount; 280 } 281 282 private void givePhoneAccountBindPermission(PhoneAccountHandle handle) { 283 when(mMockAccountRegistrar.phoneAccountRequiresBindPermission(eq(handle))).thenReturn(true); 284 } 285 286 private PhoneAccountHandle getNewConnectionMangerHandle(String id) { 287 PhoneAccountHandle callManagerPAHandle = makeQuickAccountHandle(id); 288 when(mMockAccountRegistrar.getSimCallManagerFromCall(any(Call.class))).thenReturn( 289 callManagerPAHandle); 290 givePhoneAccountBindPermission(callManagerPAHandle); 291 return callManagerPAHandle; 292 } 293 294 private PhoneAccountHandle getNewTargetPhoneAccountHandle(String id) { 295 PhoneAccountHandle pAHandle = makeQuickAccountHandle(id); 296 when(mMockCall.getTargetPhoneAccount()).thenReturn(pAHandle); 297 givePhoneAccountBindPermission(pAHandle); 298 return pAHandle; 299 } 300 301 private PhoneAccount getNewConnectionManagerPhoneAccount(String id, int capability) { 302 PhoneAccount callManagerPA = makeQuickAccount(id, capability); 303 when(mMockAccountRegistrar.getSimCallManagerFromCall(any(Call.class))).thenReturn( 304 callManagerPA.getAccountHandle()); 305 givePhoneAccountBindPermission(callManagerPA.getAccountHandle()); 306 when(mMockAccountRegistrar.getPhoneAccountUnchecked( 307 callManagerPA.getAccountHandle())).thenReturn(callManagerPA); 308 return callManagerPA; 309 } 310 311 private PhoneAccount getNewEmergencyConnectionManagerPhoneAccount(String id, int capability) { 312 PhoneAccount callManagerPA = makeQuickAccount(id, capability); 313 when(mMockAccountRegistrar.getSimCallManagerOfCurrentUser()).thenReturn( 314 callManagerPA.getAccountHandle()); 315 givePhoneAccountBindPermission(callManagerPA.getAccountHandle()); 316 when(mMockAccountRegistrar.getPhoneAccountUnchecked( 317 callManagerPA.getAccountHandle())).thenReturn(callManagerPA); 318 return callManagerPA; 319 } 320 321 private static ComponentName makeQuickConnectionServiceComponentName() { 322 return new ComponentName(TEST_PACKAGE, TEST_CLASS); 323 } 324 325 private ConnectionServiceWrapper makeConnectionServiceWrapper() { 326 ConnectionServiceWrapper wrapper = mock(ConnectionServiceWrapper.class); 327 when(mMockConnectionServiceRepository.getService( 328 eq(makeQuickConnectionServiceComponentName()), 329 eq(Binder.getCallingUserHandle()))).thenReturn(wrapper); 330 return wrapper; 331 } 332 333 private static PhoneAccountHandle makeQuickAccountHandle(String id) { 334 return new PhoneAccountHandle(makeQuickConnectionServiceComponentName(), id, 335 Binder.getCallingUserHandle()); 336 } 337 338 private PhoneAccount.Builder makeQuickAccountBuilder(String id, int idx) { 339 return new PhoneAccount.Builder(makeQuickAccountHandle(id), "label" + idx); 340 } 341 342 private PhoneAccount makeQuickAccount(String id, int idx) { 343 return makeQuickAccountBuilder(id, idx) 344 .setAddress(Uri.parse("http://foo.com/" + idx)) 345 .setSubscriptionAddress(Uri.parse("tel:555-000" + idx)) 346 .setCapabilities(idx) 347 .setIcon(Icon.createWithResource( 348 "com.android.server.telecom.tests", R.drawable.stat_sys_phone_call)) 349 .setShortDescription("desc" + idx) 350 .setIsEnabled(true) 351 .build(); 352 } 353}