BasicCallTests.java revision bcf23de07aed59ed34d0121a76d29b6ed9a14288
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 static org.mockito.Matchers.any; 20import static org.mockito.Matchers.anyInt; 21import static org.mockito.Matchers.anyString; 22import static org.mockito.Matchers.eq; 23import static org.mockito.Matchers.isNull; 24import static org.mockito.Mockito.never; 25import static org.mockito.Mockito.timeout; 26import static org.mockito.Mockito.verify; 27import static org.mockito.Mockito.verifyZeroInteractions; 28import static org.mockito.Mockito.when; 29 30import android.content.Context; 31import android.content.IContentProvider; 32import android.media.AudioManager; 33import android.net.Uri; 34import android.os.Bundle; 35import android.os.Handler; 36import android.os.Looper; 37import android.os.Process; 38import android.provider.BlockedNumberContract; 39import android.telecom.Call; 40import android.telecom.CallAudioState; 41import android.telecom.Connection; 42import android.telecom.ConnectionRequest; 43import android.telecom.DisconnectCause; 44import android.telecom.Log; 45import android.telecom.ParcelableCall; 46import android.telecom.PhoneAccount; 47import android.telecom.PhoneAccountHandle; 48import android.telecom.TelecomManager; 49import android.telecom.VideoProfile; 50import android.support.test.filters.FlakyTest; 51import android.test.suitebuilder.annotation.LargeTest; 52import android.test.suitebuilder.annotation.MediumTest; 53 54import com.android.internal.telecom.IInCallAdapter; 55import com.android.internal.telephony.CallerInfo; 56 57import com.google.common.base.Predicate; 58 59import org.mockito.invocation.InvocationOnMock; 60import org.mockito.stubbing.Answer; 61 62import java.util.concurrent.BrokenBarrierException; 63import java.util.concurrent.CountDownLatch; 64import java.util.concurrent.CyclicBarrier; 65import java.util.concurrent.TimeUnit; 66 67import org.mockito.ArgumentCaptor; 68 69/** 70 * Performs various basic call tests in Telecom. 71 */ 72public class BasicCallTests extends TelecomSystemTest { 73 private static final String TEST_BUNDLE_KEY = "android.telecom.extra.TEST"; 74 private static final String TEST_EVENT = "android.telecom.event.TEST"; 75 76 @LargeTest 77 public void testSingleOutgoingCallLocalDisconnect() throws Exception { 78 IdPair ids = startAndMakeActiveOutgoingCall("650-555-1212", 79 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 80 81 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId); 82 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 83 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 84 85 when(mClockProxy.currentTimeMillis()).thenReturn(TEST_DISCONNECT_TIME); 86 when(mClockProxy.elapsedRealtime()).thenReturn(TEST_DISCONNECT_ELAPSED_TIME); 87 mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL); 88 assertEquals(Call.STATE_DISCONNECTED, 89 mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 90 assertEquals(Call.STATE_DISCONNECTED, 91 mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 92 assertEquals(TEST_CONNECT_TIME, 93 mInCallServiceFixtureX.getCall(ids.mCallId).getConnectTimeMillis()); 94 assertEquals(TEST_CONNECT_TIME, 95 mInCallServiceFixtureY.getCall(ids.mCallId).getConnectTimeMillis()); 96 assertEquals(TEST_CREATE_TIME, 97 mInCallServiceFixtureX.getCall(ids.mCallId).getCreationTimeMillis()); 98 assertEquals(TEST_CREATE_TIME, 99 mInCallServiceFixtureY.getCall(ids.mCallId).getCreationTimeMillis()); 100 101 verifyNoBlockChecks(); 102 } 103 104 @LargeTest 105 public void testSingleOutgoingCallRemoteDisconnect() throws Exception { 106 IdPair ids = startAndMakeActiveOutgoingCall("650-555-1212", 107 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 108 109 when(mClockProxy.currentTimeMillis()).thenReturn(TEST_DISCONNECT_TIME); 110 when(mClockProxy.elapsedRealtime()).thenReturn(TEST_DISCONNECT_ELAPSED_TIME); 111 mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL); 112 assertEquals(Call.STATE_DISCONNECTED, 113 mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 114 assertEquals(Call.STATE_DISCONNECTED, 115 mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 116 verifyNoBlockChecks(); 117 } 118 119 /** 120 * Tests the {@link TelecomManager#acceptRingingCall()} API. Tests simple case of an incoming 121 * audio-only call. 122 * 123 * @throws Exception 124 */ 125 @LargeTest 126 public void testTelecomManagerAcceptRingingCall() throws Exception { 127 IdPair ids = startIncomingPhoneCall("650-555-1212", mPhoneAccountA0.getAccountHandle(), 128 mConnectionServiceFixtureA); 129 130 assertEquals(Call.STATE_RINGING, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 131 assertEquals(Call.STATE_RINGING, mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 132 133 // Use TelecomManager API to answer the ringing call. 134 TelecomManager telecomManager = (TelecomManager) mComponentContextFixture.getTestDouble() 135 .getApplicationContext().getSystemService(Context.TELECOM_SERVICE); 136 telecomManager.acceptRingingCall(); 137 138 verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT)) 139 .answer(eq(ids.mConnectionId), any()); 140 mConnectionServiceFixtureA.sendSetActive(ids.mConnectionId); 141 142 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId); 143 } 144 145 /** 146 * Tests the {@link TelecomManager#acceptRingingCall()} API. Tests simple case of an incoming 147 * video call, which should be answered as video. 148 * 149 * @throws Exception 150 */ 151 @LargeTest 152 public void testTelecomManagerAcceptRingingVideoCall() throws Exception { 153 IdPair ids = startIncomingPhoneCall("650-555-1212", mPhoneAccountA0.getAccountHandle(), 154 VideoProfile.STATE_BIDIRECTIONAL, mConnectionServiceFixtureA); 155 156 assertEquals(Call.STATE_RINGING, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 157 assertEquals(Call.STATE_RINGING, mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 158 159 // Use TelecomManager API to answer the ringing call; the default expected behavior is to 160 // answer using whatever video state the ringing call requests. 161 TelecomManager telecomManager = (TelecomManager) mComponentContextFixture.getTestDouble() 162 .getApplicationContext().getSystemService(Context.TELECOM_SERVICE); 163 telecomManager.acceptRingingCall(); 164 165 // Answer video API should be called 166 verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT)) 167 .answerVideo(eq(ids.mConnectionId), eq(VideoProfile.STATE_BIDIRECTIONAL), any()); 168 mConnectionServiceFixtureA.sendSetActive(ids.mConnectionId); 169 170 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId); 171 } 172 173 /** 174 * Tests the {@link TelecomManager#acceptRingingCall(int)} API. Tests answering a video call 175 * as an audio call. 176 * 177 * @throws Exception 178 */ 179 @LargeTest 180 public void testTelecomManagerAcceptRingingVideoCallAsAudio() throws Exception { 181 IdPair ids = startIncomingPhoneCall("650-555-1212", mPhoneAccountA0.getAccountHandle(), 182 VideoProfile.STATE_BIDIRECTIONAL, mConnectionServiceFixtureA); 183 184 assertEquals(Call.STATE_RINGING, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 185 assertEquals(Call.STATE_RINGING, mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 186 187 // Use TelecomManager API to answer the ringing call. 188 TelecomManager telecomManager = (TelecomManager) mComponentContextFixture.getTestDouble() 189 .getApplicationContext().getSystemService(Context.TELECOM_SERVICE); 190 telecomManager.acceptRingingCall(VideoProfile.STATE_AUDIO_ONLY); 191 192 // The generic answer method on the ConnectionService is used to answer audio-only calls. 193 verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT)) 194 .answer(eq(ids.mConnectionId), any()); 195 mConnectionServiceFixtureA.sendSetActive(ids.mConnectionId); 196 197 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId); 198 } 199 200 /** 201 * Tests the {@link TelecomManager#acceptRingingCall()} API. Tests simple case of an incoming 202 * video call, where an attempt is made to answer with an invalid video state. 203 * 204 * @throws Exception 205 */ 206 @LargeTest 207 public void testTelecomManagerAcceptRingingInvalidVideoState() throws Exception { 208 IdPair ids = startIncomingPhoneCall("650-555-1212", mPhoneAccountA0.getAccountHandle(), 209 VideoProfile.STATE_BIDIRECTIONAL, mConnectionServiceFixtureA); 210 211 assertEquals(Call.STATE_RINGING, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 212 assertEquals(Call.STATE_RINGING, mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 213 214 // Use TelecomManager API to answer the ringing call; the default expected behavior is to 215 // answer using whatever video state the ringing call requests. 216 TelecomManager telecomManager = (TelecomManager) mComponentContextFixture.getTestDouble() 217 .getApplicationContext().getSystemService(Context.TELECOM_SERVICE); 218 telecomManager.acceptRingingCall(999 /* invalid videostate */); 219 220 // Answer video API should be called 221 verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT)) 222 .answerVideo(eq(ids.mConnectionId), eq(VideoProfile.STATE_BIDIRECTIONAL), any()); 223 mConnectionServiceFixtureA.sendSetActive(ids.mConnectionId); 224 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId); 225 } 226 227 @LargeTest 228 public void testSingleIncomingCallLocalDisconnect() throws Exception { 229 IdPair ids = startAndMakeActiveIncomingCall("650-555-1212", 230 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 231 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId); 232 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 233 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 234 235 when(mClockProxy.currentTimeMillis()).thenReturn(TEST_DISCONNECT_TIME); 236 when(mClockProxy.elapsedRealtime()).thenReturn(TEST_DISCONNECT_ELAPSED_TIME); 237 mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL); 238 assertEquals(Call.STATE_DISCONNECTED, 239 mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 240 assertEquals(Call.STATE_DISCONNECTED, 241 mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 242 } 243 244 @LargeTest 245 public void testSingleIncomingCallRemoteDisconnect() throws Exception { 246 IdPair ids = startAndMakeActiveIncomingCall("650-555-1212", 247 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 248 249 when(mClockProxy.currentTimeMillis()).thenReturn(TEST_DISCONNECT_TIME); 250 when(mClockProxy.elapsedRealtime()).thenReturn(TEST_DISCONNECT_ELAPSED_TIME); 251 mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL); 252 assertEquals(Call.STATE_DISCONNECTED, 253 mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 254 assertEquals(Call.STATE_DISCONNECTED, 255 mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 256 } 257 258 @LargeTest 259 public void testIncomingEmergencyCallback() throws Exception { 260 // Make an outgoing emergency call 261 String phoneNumber = "650-555-1212"; 262 IdPair ids = startAndMakeDialingEmergencyCall(phoneNumber, 263 mPhoneAccountE0.getAccountHandle(), mConnectionServiceFixtureA); 264 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId); 265 mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL); 266 267 // Incoming call should be marked as a potential emergency callback 268 Bundle extras = new Bundle(); 269 extras.putParcelable( 270 TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, 271 Uri.fromParts(PhoneAccount.SCHEME_TEL, phoneNumber, null)); 272 mTelecomSystem.getTelecomServiceImpl().getBinder() 273 .addNewIncomingCall(mPhoneAccountA0.getAccountHandle(), extras); 274 275 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT); 276 ArgumentCaptor<ConnectionRequest> connectionRequestCaptor 277 = ArgumentCaptor.forClass(ConnectionRequest.class); 278 verify(mConnectionServiceFixtureA.getTestDouble()) 279 .createConnection(any(PhoneAccountHandle.class), anyString(), 280 connectionRequestCaptor.capture(), eq(true), eq(false), any()); 281 282 assert(connectionRequestCaptor.getValue().getExtras().containsKey( 283 android.telecom.Call.EXTRA_LAST_EMERGENCY_CALLBACK_TIME_MILLIS)); 284 assertTrue(connectionRequestCaptor.getValue().getExtras().getLong( 285 android.telecom.Call.EXTRA_LAST_EMERGENCY_CALLBACK_TIME_MILLIS, 0) > 0); 286 assert(connectionRequestCaptor.getValue().getExtras().containsKey( 287 TelecomManager.EXTRA_INCOMING_CALL_ADDRESS)); 288 } 289 290 @LargeTest 291 public void testOutgoingCallAndSelectPhoneAccount() throws Exception { 292 // Remove default PhoneAccount so that the Call moves into the correct 293 // SELECT_PHONE_ACCOUNT state. 294 mTelecomSystem.getPhoneAccountRegistrar().setUserSelectedOutgoingPhoneAccount( 295 null, Process.myUserHandle()); 296 int startingNumConnections = mConnectionServiceFixtureA.mConnectionById.size(); 297 int startingNumCalls = mInCallServiceFixtureX.mCallById.size(); 298 String callId = startOutgoingPhoneCallWithNoPhoneAccount("650-555-1212", 299 mConnectionServiceFixtureA); 300 assertEquals(Call.STATE_SELECT_PHONE_ACCOUNT, 301 mInCallServiceFixtureX.getCall(callId).getState()); 302 assertEquals(Call.STATE_SELECT_PHONE_ACCOUNT, 303 mInCallServiceFixtureY.getCall(callId).getState()); 304 mInCallServiceFixtureX.mInCallAdapter.phoneAccountSelected(callId, 305 mPhoneAccountA0.getAccountHandle(), false); 306 307 IdPair ids = outgoingCallPhoneAccountSelected(mPhoneAccountA0.getAccountHandle(), 308 startingNumConnections, startingNumCalls, mConnectionServiceFixtureA); 309 310 when(mClockProxy.currentTimeMillis()).thenReturn(TEST_DISCONNECT_TIME); 311 when(mClockProxy.elapsedRealtime()).thenReturn(TEST_DISCONNECT_ELAPSED_TIME); 312 mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL); 313 assertEquals(Call.STATE_DISCONNECTED, 314 mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 315 assertEquals(Call.STATE_DISCONNECTED, 316 mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 317 } 318 319 @LargeTest 320 public void testIncomingCallFromContactWithSendToVoicemailIsRejected() throws Exception { 321 Bundle extras = new Bundle(); 322 extras.putParcelable( 323 TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, 324 Uri.fromParts(PhoneAccount.SCHEME_TEL, "650-555-1212", null)); 325 mTelecomSystem.getTelecomServiceImpl().getBinder() 326 .addNewIncomingCall(mPhoneAccountA0.getAccountHandle(), extras); 327 328 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT); 329 verify(mConnectionServiceFixtureA.getTestDouble()) 330 .createConnection(any(PhoneAccountHandle.class), anyString(), 331 any(ConnectionRequest.class), eq(true), eq(false), any()); 332 333 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT); 334 assertEquals(1, mCallerInfoAsyncQueryFactoryFixture.mRequests.size()); 335 for (CallerInfoAsyncQueryFactoryFixture.Request request : 336 mCallerInfoAsyncQueryFactoryFixture.mRequests) { 337 CallerInfo sendToVoicemailCallerInfo = new CallerInfo(); 338 sendToVoicemailCallerInfo.shouldSendToVoicemail = true; 339 request.replyWithCallerInfo(sendToVoicemailCallerInfo); 340 } 341 342 assertTrueWithTimeout(new Predicate<Void>() { 343 @Override 344 public boolean apply(Void aVoid) { 345 return mConnectionServiceFixtureA.mConnectionService.rejectedCallIds.size() == 1; 346 } 347 }); 348 assertTrueWithTimeout(new Predicate<Void>() { 349 @Override 350 public boolean apply(Void aVoid) { 351 return mMissedCallNotifier.missedCallsNotified.size() == 1; 352 } 353 }); 354 355 verify(mInCallServiceFixtureX.getTestDouble(), never()) 356 .setInCallAdapter(any(IInCallAdapter.class)); 357 verify(mInCallServiceFixtureY.getTestDouble(), never()) 358 .setInCallAdapter(any(IInCallAdapter.class)); 359 } 360 361 @LargeTest 362 public void testIncomingCallCallerInfoLookupTimesOutIsAllowed() throws Exception { 363 when(mClockProxy.currentTimeMillis()).thenReturn(TEST_CREATE_TIME); 364 when(mClockProxy.elapsedRealtime()).thenReturn(TEST_CREATE_ELAPSED_TIME); 365 Bundle extras = new Bundle(); 366 extras.putParcelable( 367 TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, 368 Uri.fromParts(PhoneAccount.SCHEME_TEL, "650-555-1212", null)); 369 mTelecomSystem.getTelecomServiceImpl().getBinder() 370 .addNewIncomingCall(mPhoneAccountA0.getAccountHandle(), extras); 371 372 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT); 373 verify(mConnectionServiceFixtureA.getTestDouble()) 374 .createConnection(any(PhoneAccountHandle.class), anyString(), 375 any(ConnectionRequest.class), eq(true), eq(false), any()); 376 377 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT); 378 // Never reply to the caller info lookup. 379 assertEquals(1, mCallerInfoAsyncQueryFactoryFixture.mRequests.size()); 380 381 verify(mInCallServiceFixtureX.getTestDouble(), timeout(TEST_TIMEOUT)) 382 .setInCallAdapter(any(IInCallAdapter.class)); 383 verify(mInCallServiceFixtureY.getTestDouble(), timeout(TEST_TIMEOUT)) 384 .setInCallAdapter(any(IInCallAdapter.class)); 385 386 assertEquals(0, mConnectionServiceFixtureA.mConnectionService.rejectedCallIds.size()); 387 assertEquals(0, mMissedCallNotifier.missedCallsNotified.size()); 388 389 assertTrueWithTimeout(new Predicate<Void>() { 390 @Override 391 public boolean apply(Void v) { 392 return mInCallServiceFixtureX.mInCallAdapter != null; 393 } 394 }); 395 396 verify(mInCallServiceFixtureX.getTestDouble(), timeout(TEST_TIMEOUT)) 397 .addCall(any(ParcelableCall.class)); 398 verify(mInCallServiceFixtureY.getTestDouble(), timeout(TEST_TIMEOUT)) 399 .addCall(any(ParcelableCall.class)); 400 401 when(mClockProxy.currentTimeMillis()).thenReturn(TEST_CONNECT_TIME); 402 when(mClockProxy.elapsedRealtime()).thenReturn(TEST_CONNECT_ELAPSED_TIME); 403 disconnectCall(mInCallServiceFixtureX.mLatestCallId, 404 mConnectionServiceFixtureA.mLatestConnectionId); 405 } 406 407 @LargeTest 408 public void testIncomingCallFromBlockedNumberIsRejected() throws Exception { 409 String phoneNumber = "650-555-1212"; 410 blockNumber(phoneNumber); 411 412 Bundle extras = new Bundle(); 413 extras.putParcelable( 414 TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, 415 Uri.fromParts(PhoneAccount.SCHEME_TEL, phoneNumber, null)); 416 mTelecomSystem.getTelecomServiceImpl().getBinder() 417 .addNewIncomingCall(mPhoneAccountA0.getAccountHandle(), extras); 418 419 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT); 420 verify(mConnectionServiceFixtureA.getTestDouble()) 421 .createConnection(any(PhoneAccountHandle.class), anyString(), 422 any(ConnectionRequest.class), eq(true), eq(false), any()); 423 424 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT); 425 assertEquals(1, mCallerInfoAsyncQueryFactoryFixture.mRequests.size()); 426 for (CallerInfoAsyncQueryFactoryFixture.Request request : 427 mCallerInfoAsyncQueryFactoryFixture.mRequests) { 428 request.reply(); 429 } 430 431 assertTrueWithTimeout(new Predicate<Void>() { 432 @Override 433 public boolean apply(Void aVoid) { 434 return mConnectionServiceFixtureA.mConnectionService.rejectedCallIds.size() == 1; 435 } 436 }); 437 assertEquals(0, mMissedCallNotifier.missedCallsNotified.size()); 438 439 verify(mInCallServiceFixtureX.getTestDouble(), never()) 440 .setInCallAdapter(any(IInCallAdapter.class)); 441 verify(mInCallServiceFixtureY.getTestDouble(), never()) 442 .setInCallAdapter(any(IInCallAdapter.class)); 443 } 444 445 @LargeTest 446 public void testIncomingCallBlockCheckTimesoutIsAllowed() throws Exception { 447 final CountDownLatch latch = new CountDownLatch(1); 448 String phoneNumber = "650-555-1212"; 449 blockNumberWithAnswer(phoneNumber, new Answer<Bundle>() { 450 @Override 451 public Bundle answer(InvocationOnMock invocation) throws Throwable { 452 latch.await(TEST_TIMEOUT * 2, TimeUnit.MILLISECONDS); 453 Bundle bundle = new Bundle(); 454 bundle.putBoolean(BlockedNumberContract.RES_NUMBER_IS_BLOCKED, true); 455 return bundle; 456 } 457 }); 458 459 IdPair ids = startAndMakeActiveIncomingCall( 460 phoneNumber, mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 461 latch.countDown(); 462 463 assertEquals(0, mConnectionServiceFixtureA.mConnectionService.rejectedCallIds.size()); 464 assertEquals(0, mMissedCallNotifier.missedCallsNotified.size()); 465 disconnectCall(ids.mCallId, ids.mConnectionId); 466 } 467 468 public void do_testDeadlockOnOutgoingCall() throws Exception { 469 final IdPair ids = startOutgoingPhoneCall("650-555-1212", 470 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA, 471 Process.myUserHandle()); 472 rapidFire( 473 new Runnable() { 474 @Override 475 public void run() { 476 while (mCallerInfoAsyncQueryFactoryFixture.mRequests.size() > 0) { 477 mCallerInfoAsyncQueryFactoryFixture.mRequests.remove(0).reply(); 478 } 479 } 480 }, 481 new Runnable() { 482 @Override 483 public void run() { 484 try { 485 mConnectionServiceFixtureA.sendSetActive(ids.mConnectionId); 486 } catch (Exception e) { 487 Log.e(this, e, ""); 488 } 489 } 490 }); 491 } 492 493 @MediumTest 494 public void testDeadlockOnOutgoingCall() throws Exception { 495 for (int i = 0; i < 100; i++) { 496 BasicCallTests test = new BasicCallTests(); 497 test.setContext(getContext()); 498 test.setTestContext(getTestContext()); 499 test.setName(getName()); 500 test.setUp(); 501 test.do_testDeadlockOnOutgoingCall(); 502 test.tearDown(); 503 } 504 } 505 506 @LargeTest 507 public void testIncomingThenOutgoingCalls() throws Exception { 508 // TODO: We have to use the same PhoneAccount for both; see http://b/18461539 509 IdPair incoming = startAndMakeActiveIncomingCall("650-555-2323", 510 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 511 IdPair outgoing = startAndMakeActiveOutgoingCall("650-555-1212", 512 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 513 514 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(incoming.mCallId); 515 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(outgoing.mCallId); 516 } 517 518 @LargeTest 519 public void testOutgoingThenIncomingCalls() throws Exception { 520 // TODO: We have to use the same PhoneAccount for both; see http://b/18461539 521 IdPair outgoing = startAndMakeActiveOutgoingCall("650-555-1212", 522 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 523 IdPair incoming = startAndMakeActiveIncomingCall("650-555-2323", 524 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 525 verify(mConnectionServiceFixtureA.getTestDouble()) 526 .hold(eq(outgoing.mConnectionId), any()); 527 mConnectionServiceFixtureA.mConnectionById.get(outgoing.mConnectionId).state = 528 Connection.STATE_HOLDING; 529 mConnectionServiceFixtureA.sendSetOnHold(outgoing.mConnectionId); 530 assertEquals(Call.STATE_HOLDING, 531 mInCallServiceFixtureX.getCall(outgoing.mCallId).getState()); 532 assertEquals(Call.STATE_HOLDING, 533 mInCallServiceFixtureY.getCall(outgoing.mCallId).getState()); 534 535 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(incoming.mCallId); 536 mInCallServiceFixtureX.mInCallAdapter.disconnectCall(outgoing.mCallId); 537 } 538 539 @LargeTest 540 public void testAudioManagerOperations() throws Exception { 541 AudioManager audioManager = (AudioManager) mComponentContextFixture.getTestDouble() 542 .getApplicationContext().getSystemService(Context.AUDIO_SERVICE); 543 544 IdPair outgoing = startAndMakeActiveOutgoingCall("650-555-1212", 545 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 546 547 verify(audioManager, timeout(TEST_TIMEOUT)).requestAudioFocusForCall(anyInt(), anyInt()); 548 verify(audioManager, timeout(TEST_TIMEOUT).atLeastOnce()) 549 .setMode(AudioManager.MODE_IN_CALL); 550 551 mInCallServiceFixtureX.mInCallAdapter.mute(true); 552 verify(mAudioService, timeout(TEST_TIMEOUT)) 553 .setMicrophoneMute(eq(true), any(String.class), any(Integer.class)); 554 mInCallServiceFixtureX.mInCallAdapter.mute(false); 555 verify(mAudioService, timeout(TEST_TIMEOUT)) 556 .setMicrophoneMute(eq(false), any(String.class), any(Integer.class)); 557 558 mInCallServiceFixtureX.mInCallAdapter.setAudioRoute(CallAudioState.ROUTE_SPEAKER); 559 verify(audioManager, timeout(TEST_TIMEOUT)) 560 .setSpeakerphoneOn(true); 561 mInCallServiceFixtureX.mInCallAdapter.setAudioRoute(CallAudioState.ROUTE_EARPIECE); 562 verify(audioManager, timeout(TEST_TIMEOUT)) 563 .setSpeakerphoneOn(false); 564 565 mConnectionServiceFixtureA. 566 sendSetDisconnected(outgoing.mConnectionId, DisconnectCause.REMOTE); 567 568 verify(audioManager, timeout(TEST_TIMEOUT)) 569 .abandonAudioFocusForCall(); 570 verify(audioManager, timeout(TEST_TIMEOUT).atLeastOnce()) 571 .setMode(AudioManager.MODE_NORMAL); 572 } 573 574 private void rapidFire(Runnable... tasks) { 575 final CyclicBarrier barrier = new CyclicBarrier(tasks.length); 576 final CountDownLatch latch = new CountDownLatch(tasks.length); 577 for (int i = 0; i < tasks.length; i++) { 578 final Runnable task = tasks[i]; 579 new Thread(new Runnable() { 580 @Override 581 public void run() { 582 try { 583 barrier.await(); 584 task.run(); 585 } catch (InterruptedException | BrokenBarrierException e){ 586 Log.e(BasicCallTests.this, e, "Unexpectedly interrupted"); 587 } finally { 588 latch.countDown(); 589 } 590 } 591 }).start(); 592 } 593 try { 594 latch.await(); 595 } catch (InterruptedException e) { 596 Log.e(BasicCallTests.this, e, "Unexpectedly interrupted"); 597 } 598 } 599 600 @MediumTest 601 public void testBasicConferenceCall() throws Exception { 602 makeConferenceCall(); 603 } 604 605 @MediumTest 606 public void testAddCallToConference1() throws Exception { 607 ParcelableCall conferenceCall = makeConferenceCall(); 608 IdPair callId3 = startAndMakeActiveOutgoingCall("650-555-1214", 609 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 610 // testAddCallToConference{1,2} differ in the order of arguments to InCallAdapter#conference 611 mInCallServiceFixtureX.getInCallAdapter().conference( 612 conferenceCall.getId(), callId3.mCallId); 613 Thread.sleep(200); 614 615 ParcelableCall call3 = mInCallServiceFixtureX.getCall(callId3.mCallId); 616 ParcelableCall updatedConference = mInCallServiceFixtureX.getCall(conferenceCall.getId()); 617 assertEquals(conferenceCall.getId(), call3.getParentCallId()); 618 assertEquals(3, updatedConference.getChildCallIds().size()); 619 assertTrue(updatedConference.getChildCallIds().contains(callId3.mCallId)); 620 } 621 622 @MediumTest 623 public void testAddCallToConference2() throws Exception { 624 ParcelableCall conferenceCall = makeConferenceCall(); 625 IdPair callId3 = startAndMakeActiveOutgoingCall("650-555-1214", 626 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 627 mInCallServiceFixtureX.getInCallAdapter() 628 .conference(callId3.mCallId, conferenceCall.getId()); 629 Thread.sleep(200); 630 631 ParcelableCall call3 = mInCallServiceFixtureX.getCall(callId3.mCallId); 632 ParcelableCall updatedConference = mInCallServiceFixtureX.getCall(conferenceCall.getId()); 633 assertEquals(conferenceCall.getId(), call3.getParentCallId()); 634 assertEquals(3, updatedConference.getChildCallIds().size()); 635 assertTrue(updatedConference.getChildCallIds().contains(callId3.mCallId)); 636 } 637 638 /** 639 * Tests the {@link Call#pullExternalCall()} API. Verifies that if a call is not an external 640 * call, no pull call request is made to the connection service. 641 * 642 * @throws Exception 643 */ 644 @MediumTest 645 public void testPullNonExternalCall() throws Exception { 646 // TODO: Revisit this unit test once telecom support for filtering external calls from 647 // InCall services is implemented. 648 IdPair ids = startAndMakeActiveIncomingCall("650-555-1212", 649 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 650 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 651 652 // Attempt to pull the call and verify the API call makes it through 653 mInCallServiceFixtureX.mInCallAdapter.pullExternalCall(ids.mCallId); 654 Thread.sleep(TEST_TIMEOUT); 655 verify(mConnectionServiceFixtureA.getTestDouble(), never()) 656 .pullExternalCall(eq(ids.mCallId), any()); 657 } 658 659 /** 660 * Tests the {@link Connection#sendConnectionEvent(String, Bundle)} API. 661 * 662 * @throws Exception 663 */ 664 @MediumTest 665 public void testSendConnectionEventNull() throws Exception { 666 IdPair ids = startAndMakeActiveIncomingCall("650-555-1212", 667 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 668 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 669 mConnectionServiceFixtureA.sendConnectionEvent(ids.mConnectionId, TEST_EVENT, null); 670 verify(mInCallServiceFixtureX.getTestDouble(), timeout(TEST_TIMEOUT)) 671 .onConnectionEvent(ids.mCallId, TEST_EVENT, null); 672 } 673 674 /** 675 * Tests the {@link Connection#sendConnectionEvent(String, Bundle)} API. 676 * 677 * @throws Exception 678 */ 679 @MediumTest 680 public void testSendConnectionEventNotNull() throws Exception { 681 IdPair ids = startAndMakeActiveIncomingCall("650-555-1212", 682 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 683 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 684 685 Bundle testBundle = new Bundle(); 686 testBundle.putString(TEST_BUNDLE_KEY, "TEST"); 687 688 ArgumentCaptor<Bundle> bundleArgumentCaptor = ArgumentCaptor.forClass(Bundle.class); 689 mConnectionServiceFixtureA.sendConnectionEvent(ids.mConnectionId, TEST_EVENT, testBundle); 690 verify(mInCallServiceFixtureX.getTestDouble(), timeout(TEST_TIMEOUT)) 691 .onConnectionEvent(eq(ids.mCallId), eq(TEST_EVENT), bundleArgumentCaptor.capture()); 692 assert (bundleArgumentCaptor.getValue().containsKey(TEST_BUNDLE_KEY)); 693 } 694 695 /** 696 * Tests the {@link Call#sendCallEvent(String, Bundle)} API. 697 * 698 * @throws Exception 699 */ 700 @MediumTest 701 public void testSendCallEventNull() throws Exception { 702 IdPair ids = startAndMakeActiveIncomingCall("650-555-1212", 703 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 704 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 705 706 mInCallServiceFixtureX.mInCallAdapter.sendCallEvent(ids.mCallId, TEST_EVENT, null); 707 verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT)) 708 .sendCallEvent(eq(ids.mConnectionId), eq(TEST_EVENT), isNull(Bundle.class), any()); 709 } 710 711 /** 712 * Tests the {@link Call#sendCallEvent(String, Bundle)} API. 713 * 714 * @throws Exception 715 */ 716 @MediumTest 717 public void testSendCallEventNonNull() throws Exception { 718 IdPair ids = startAndMakeActiveIncomingCall("650-555-1212", 719 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 720 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 721 722 Bundle testBundle = new Bundle(); 723 testBundle.putString(TEST_BUNDLE_KEY, "TEST"); 724 725 ArgumentCaptor<Bundle> bundleArgumentCaptor = ArgumentCaptor.forClass(Bundle.class); 726 mInCallServiceFixtureX.mInCallAdapter.sendCallEvent(ids.mCallId, TEST_EVENT, 727 testBundle); 728 verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT)) 729 .sendCallEvent(eq(ids.mConnectionId), eq(TEST_EVENT), 730 bundleArgumentCaptor.capture(), any()); 731 assert (bundleArgumentCaptor.getValue().containsKey(TEST_BUNDLE_KEY)); 732 } 733 734 private void blockNumber(String phoneNumber) throws Exception { 735 blockNumberWithAnswer(phoneNumber, new Answer<Bundle>() { 736 @Override 737 public Bundle answer(InvocationOnMock invocation) throws Throwable { 738 Bundle bundle = new Bundle(); 739 bundle.putBoolean(BlockedNumberContract.RES_NUMBER_IS_BLOCKED, true); 740 return bundle; 741 } 742 }); 743 } 744 745 private void blockNumberWithAnswer(String phoneNumber, Answer answer) throws Exception { 746 when(getBlockedNumberProvider().call( 747 anyString(), 748 eq(BlockedNumberContract.SystemContract.METHOD_SHOULD_SYSTEM_BLOCK_NUMBER), 749 eq(phoneNumber), 750 isNull(Bundle.class))).thenAnswer(answer); 751 } 752 753 private void verifyNoBlockChecks() { 754 verifyZeroInteractions(getBlockedNumberProvider()); 755 } 756 757 private IContentProvider getBlockedNumberProvider() { 758 return mSpyContext.getContentResolver().acquireProvider(BlockedNumberContract.AUTHORITY); 759 } 760 761 private void disconnectCall(String callId, String connectionId) throws Exception { 762 when(mClockProxy.currentTimeMillis()).thenReturn(TEST_DISCONNECT_TIME); 763 when(mClockProxy.elapsedRealtime()).thenReturn(TEST_DISCONNECT_ELAPSED_TIME); 764 mConnectionServiceFixtureA.sendSetDisconnected(connectionId, DisconnectCause.LOCAL); 765 assertEquals(Call.STATE_DISCONNECTED, mInCallServiceFixtureX.getCall(callId).getState()); 766 assertEquals(Call.STATE_DISCONNECTED, mInCallServiceFixtureY.getCall(callId).getState()); 767 assertEquals(TEST_CREATE_TIME, 768 mInCallServiceFixtureX.getCall(callId).getCreationTimeMillis()); 769 assertEquals(TEST_CREATE_TIME, 770 mInCallServiceFixtureY.getCall(callId).getCreationTimeMillis()); 771 } 772 773 /** 774 * Tests to make sure that the Call.Details.PROPERTY_HAS_CDMA_VOICE_PRIVACY property is set on a 775 * Call that is based on a Connection with the Connection.PROPERTY_HAS_CDMA_VOICE_PRIVACY 776 * property set. 777 */ 778 @MediumTest 779 public void testCdmaEnhancedPrivacyVoiceCall() throws Exception { 780 mConnectionServiceFixtureA.mConnectionServiceDelegate.mProperties = 781 Connection.PROPERTY_HAS_CDMA_VOICE_PRIVACY; 782 783 IdPair ids = startAndMakeActiveOutgoingCall("650-555-1212", 784 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 785 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 786 787 assertTrue(Call.Details.hasProperty( 788 mInCallServiceFixtureX.getCall(ids.mCallId).getProperties(), 789 Call.Details.PROPERTY_HAS_CDMA_VOICE_PRIVACY)); 790 } 791 792 /** 793 * Tests to make sure that Call.Details.PROPERTY_HAS_CDMA_VOICE_PRIVACY is dropped 794 * when the Connection.PROPERTY_HAS_CDMA_VOICE_PRIVACY property is removed from the Connection. 795 */ 796 @MediumTest 797 public void testDropCdmaEnhancedPrivacyVoiceCall() throws Exception { 798 mConnectionServiceFixtureA.mConnectionServiceDelegate.mProperties = 799 Connection.PROPERTY_HAS_CDMA_VOICE_PRIVACY; 800 801 IdPair ids = startAndMakeActiveOutgoingCall("650-555-1212", 802 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 803 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 804 mConnectionServiceFixtureA.mLatestConnection.setConnectionProperties(0); 805 806 assertFalse(Call.Details.hasProperty( 807 mInCallServiceFixtureX.getCall(ids.mCallId).getProperties(), 808 Call.Details.PROPERTY_HAS_CDMA_VOICE_PRIVACY)); 809 } 810 811 /** 812 * Tests the {@link Call#pullExternalCall()} API. Ensures that an external call which is 813 * pullable can be pulled. 814 * 815 * @throws Exception 816 */ 817 @LargeTest 818 public void testPullExternalCall() throws Exception { 819 // TODO: Revisit this unit test once telecom support for filtering external calls from 820 // InCall services is implemented. 821 mConnectionServiceFixtureA.mConnectionServiceDelegate.mCapabilities = 822 Connection.CAPABILITY_CAN_PULL_CALL; 823 mConnectionServiceFixtureA.mConnectionServiceDelegate.mProperties = 824 Connection.PROPERTY_IS_EXTERNAL_CALL; 825 826 IdPair ids = startAndMakeActiveIncomingCall("650-555-1212", 827 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 828 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 829 830 // Attempt to pull the call and verify the API call makes it through 831 mInCallServiceFixtureX.mInCallAdapter.pullExternalCall(ids.mCallId); 832 verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT)) 833 .pullExternalCall(eq(ids.mConnectionId), any()); 834 } 835 836 /** 837 * Tests the {@link Call#pullExternalCall()} API. Verifies that if an external call is not 838 * marked as pullable that the connection service does not get an API call to pull the external 839 * call. 840 * 841 * @throws Exception 842 */ 843 @LargeTest 844 public void testPullNonPullableExternalCall() throws Exception { 845 // TODO: Revisit this unit test once telecom support for filtering external calls from 846 // InCall services is implemented. 847 mConnectionServiceFixtureA.mConnectionServiceDelegate.mProperties = 848 Connection.PROPERTY_IS_EXTERNAL_CALL; 849 850 IdPair ids = startAndMakeActiveIncomingCall("650-555-1212", 851 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA); 852 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 853 854 // Attempt to pull the call and verify the API call makes it through 855 mInCallServiceFixtureX.mInCallAdapter.pullExternalCall(ids.mCallId); 856 Thread.sleep(TEST_TIMEOUT); 857 verify(mConnectionServiceFixtureA.getTestDouble(), never()) 858 .pullExternalCall(eq(ids.mConnectionId), any()); 859 } 860 861 @LargeTest 862 public void testEmergencyCallFailMoveToSecondSim() throws Exception { 863 IdPair ids = startAndMakeDialingEmergencyCall("650-555-1212", 864 mPhoneAccountE0.getAccountHandle(), mConnectionServiceFixtureA); 865 assertEquals(Call.STATE_DIALING, mInCallServiceFixtureX.getCall(ids.mCallId).getState()); 866 assertEquals(Call.STATE_DIALING, mInCallServiceFixtureY.getCall(ids.mCallId).getState()); 867 868 // The Emergency Call has failed on the default SIM with an ERROR Disconnect Cause. Retry 869 // with the other SIM PhoneAccount 870 IdPair newIds = triggerEmergencyRedial(mPhoneAccountE1.getAccountHandle(), 871 mConnectionServiceFixtureA, ids); 872 873 // Call should be active on the E1 PhoneAccount 874 mConnectionServiceFixtureA.sendSetActive(newIds.mConnectionId); 875 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(newIds.mCallId).getState()); 876 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(newIds.mCallId).getState()); 877 assertEquals(mInCallServiceFixtureX.getCall(ids.mCallId).getAccountHandle(), 878 mPhoneAccountE1.getAccountHandle()); 879 } 880 881 /** 882 * Test scenario where the user starts an outgoing video call with no selected PhoneAccount, and 883 * then subsequently selects a PhoneAccount which supports video calling. 884 * @throws Exception 885 */ 886 @LargeTest 887 public void testOutgoingCallSelectPhoneAccountVideo() throws Exception { 888 startOutgoingPhoneCallPendingCreateConnection("650-555-1212", 889 null, mConnectionServiceFixtureA, 890 Process.myUserHandle(), VideoProfile.STATE_BIDIRECTIONAL); 891 com.android.server.telecom.Call call = mTelecomSystem.getCallsManager().getCalls() 892 .iterator().next(); 893 assert(call.isVideoCallingSupported()); 894 assertEquals(VideoProfile.STATE_BIDIRECTIONAL, call.getVideoState()); 895 896 // Change the phone account to one which supports video calling. 897 call.setTargetPhoneAccount(mPhoneAccountA1.getAccountHandle()); 898 assert(call.isVideoCallingSupported()); 899 assertEquals(VideoProfile.STATE_BIDIRECTIONAL, call.getVideoState()); 900 } 901 902 /** 903 * Test scenario where the user starts an outgoing video call with no selected PhoneAccount, and 904 * then subsequently selects a PhoneAccount which does not support video calling. 905 * @throws Exception 906 */ 907 @FlakyTest 908 @LargeTest 909 public void testOutgoingCallSelectPhoneAccountNoVideo() throws Exception { 910 startOutgoingPhoneCallPendingCreateConnection("650-555-1212", 911 null, mConnectionServiceFixtureA, 912 Process.myUserHandle(), VideoProfile.STATE_BIDIRECTIONAL); 913 com.android.server.telecom.Call call = mTelecomSystem.getCallsManager().getCalls() 914 .iterator().next(); 915 assert(call.isVideoCallingSupported()); 916 assertEquals(VideoProfile.STATE_BIDIRECTIONAL, call.getVideoState()); 917 918 // Change the phone account to one which does not support video calling. 919 call.setTargetPhoneAccount(mPhoneAccountA2.getAccountHandle()); 920 assert(!call.isVideoCallingSupported()); 921 assertEquals(VideoProfile.STATE_AUDIO_ONLY, call.getVideoState()); 922 } 923} 924