Home | History | Annotate | Download | only in tests
      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 
     17 package com.android.server.telecom.tests;
     18 
     19 import static org.junit.Assert.assertEquals;
     20 import static org.junit.Assert.assertFalse;
     21 import static org.junit.Assert.assertNull;
     22 import static org.junit.Assert.assertTrue;
     23 import static org.mockito.Matchers.any;
     24 import static org.mockito.Matchers.anyInt;
     25 import static org.mockito.Matchers.anyString;
     26 import static org.mockito.Matchers.eq;
     27 import static org.mockito.Matchers.isNull;
     28 import static org.mockito.Mockito.never;
     29 import static org.mockito.Mockito.timeout;
     30 import static org.mockito.Mockito.times;
     31 import static org.mockito.Mockito.verify;
     32 import static org.mockito.Mockito.verifyZeroInteractions;
     33 import static org.mockito.Mockito.when;
     34 
     35 import android.content.Context;
     36 import android.content.IContentProvider;
     37 import android.media.AudioManager;
     38 import android.net.Uri;
     39 import android.os.Bundle;
     40 import android.os.Handler;
     41 import android.os.Looper;
     42 import android.os.Process;
     43 import android.provider.BlockedNumberContract;
     44 import android.telecom.Call;
     45 import android.telecom.CallAudioState;
     46 import android.telecom.Connection;
     47 import android.telecom.ConnectionRequest;
     48 import android.telecom.DisconnectCause;
     49 import android.telecom.Log;
     50 import android.telecom.ParcelableCall;
     51 import android.telecom.PhoneAccount;
     52 import android.telecom.PhoneAccountHandle;
     53 import android.telecom.TelecomManager;
     54 import android.telecom.VideoProfile;
     55 import android.support.test.filters.FlakyTest;
     56 import android.test.suitebuilder.annotation.LargeTest;
     57 import android.test.suitebuilder.annotation.MediumTest;
     58 
     59 import com.android.internal.telecom.IInCallAdapter;
     60 import com.android.internal.telephony.CallerInfo;
     61 
     62 import com.google.common.base.Predicate;
     63 
     64 import org.junit.After;
     65 import org.junit.Before;
     66 import org.junit.Test;
     67 import org.junit.runner.RunWith;
     68 import org.junit.runners.JUnit4;
     69 import org.mockito.invocation.InvocationOnMock;
     70 import org.mockito.stubbing.Answer;
     71 
     72 import java.util.List;
     73 import java.util.concurrent.BrokenBarrierException;
     74 import java.util.concurrent.CountDownLatch;
     75 import java.util.concurrent.CyclicBarrier;
     76 import java.util.concurrent.TimeUnit;
     77 
     78 import org.mockito.ArgumentCaptor;
     79 
     80 /**
     81  * Performs various basic call tests in Telecom.
     82  */
     83 @RunWith(JUnit4.class)
     84 public class BasicCallTests extends TelecomSystemTest {
     85     private static final String TEST_BUNDLE_KEY = "android.telecom.extra.TEST";
     86     private static final String TEST_EVENT = "android.telecom.event.TEST";
     87 
     88     @Override
     89     @Before
     90     public void setUp() throws Exception {
     91         super.setUp();
     92     }
     93 
     94     @Override
     95     @After
     96     public void tearDown() throws Exception {
     97         super.tearDown();
     98     }
     99 
    100     @LargeTest
    101     @Test
    102     public void testSingleOutgoingCallLocalDisconnect() throws Exception {
    103         IdPair ids = startAndMakeActiveOutgoingCall("650-555-1212",
    104                 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
    105 
    106         mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId);
    107         assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
    108         assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
    109 
    110         when(mClockProxy.currentTimeMillis()).thenReturn(TEST_DISCONNECT_TIME);
    111         when(mClockProxy.elapsedRealtime()).thenReturn(TEST_DISCONNECT_ELAPSED_TIME);
    112         mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL);
    113         assertEquals(Call.STATE_DISCONNECTED,
    114                 mInCallServiceFixtureX.getCall(ids.mCallId).getState());
    115         assertEquals(Call.STATE_DISCONNECTED,
    116                 mInCallServiceFixtureY.getCall(ids.mCallId).getState());
    117         assertEquals(TEST_CONNECT_TIME,
    118                 mInCallServiceFixtureX.getCall(ids.mCallId).getConnectTimeMillis());
    119         assertEquals(TEST_CONNECT_TIME,
    120                 mInCallServiceFixtureY.getCall(ids.mCallId).getConnectTimeMillis());
    121         assertEquals(TEST_CREATE_TIME,
    122                 mInCallServiceFixtureX.getCall(ids.mCallId).getCreationTimeMillis());
    123         assertEquals(TEST_CREATE_TIME,
    124                 mInCallServiceFixtureY.getCall(ids.mCallId).getCreationTimeMillis());
    125 
    126         verifyNoBlockChecks();
    127     }
    128 
    129     @LargeTest
    130     @Test
    131     public void testSingleOutgoingCallRemoteDisconnect() throws Exception {
    132         IdPair ids = startAndMakeActiveOutgoingCall("650-555-1212",
    133                 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
    134 
    135         when(mClockProxy.currentTimeMillis()).thenReturn(TEST_DISCONNECT_TIME);
    136         when(mClockProxy.elapsedRealtime()).thenReturn(TEST_DISCONNECT_ELAPSED_TIME);
    137         mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL);
    138         assertEquals(Call.STATE_DISCONNECTED,
    139                 mInCallServiceFixtureX.getCall(ids.mCallId).getState());
    140         assertEquals(Call.STATE_DISCONNECTED,
    141                 mInCallServiceFixtureY.getCall(ids.mCallId).getState());
    142         verifyNoBlockChecks();
    143     }
    144 
    145     /**
    146      * Tests the {@link TelecomManager#acceptRingingCall()} API.  Tests simple case of an incoming
    147      * audio-only call.
    148      *
    149      * @throws Exception
    150      */
    151     @LargeTest
    152     @Test
    153     public void testTelecomManagerAcceptRingingCall() throws Exception {
    154         IdPair ids = startIncomingPhoneCall("650-555-1212", mPhoneAccountA0.getAccountHandle(),
    155                 mConnectionServiceFixtureA);
    156 
    157         assertEquals(Call.STATE_RINGING, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
    158         assertEquals(Call.STATE_RINGING, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
    159 
    160         // Use TelecomManager API to answer the ringing call.
    161         TelecomManager telecomManager = (TelecomManager) mComponentContextFixture.getTestDouble()
    162                 .getApplicationContext().getSystemService(Context.TELECOM_SERVICE);
    163         telecomManager.acceptRingingCall();
    164 
    165         verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT))
    166                 .answer(eq(ids.mConnectionId), any());
    167         mConnectionServiceFixtureA.sendSetActive(ids.mConnectionId);
    168 
    169         mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId);
    170     }
    171 
    172     /**
    173      * Tests the {@link TelecomManager#acceptRingingCall()} API.  Tests simple case of an incoming
    174      * video call, which should be answered as video.
    175      *
    176      * @throws Exception
    177      */
    178     @LargeTest
    179     @Test
    180     public void testTelecomManagerAcceptRingingVideoCall() 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; the default expected behavior is to
    188         // answer using whatever video state the ringing call requests.
    189         TelecomManager telecomManager = (TelecomManager) mComponentContextFixture.getTestDouble()
    190                 .getApplicationContext().getSystemService(Context.TELECOM_SERVICE);
    191         telecomManager.acceptRingingCall();
    192 
    193         // Answer video API should be called
    194         verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT))
    195                 .answerVideo(eq(ids.mConnectionId), eq(VideoProfile.STATE_BIDIRECTIONAL), any());
    196         mConnectionServiceFixtureA.sendSetActive(ids.mConnectionId);
    197 
    198         mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId);
    199     }
    200 
    201     /**
    202      * Tests the {@link TelecomManager#acceptRingingCall(int)} API.  Tests answering a video call
    203      * as an audio call.
    204      *
    205      * @throws Exception
    206      */
    207     @LargeTest
    208     @Test
    209     public void testTelecomManagerAcceptRingingVideoCallAsAudio() throws Exception {
    210         IdPair ids = startIncomingPhoneCall("650-555-1212", mPhoneAccountA0.getAccountHandle(),
    211                 VideoProfile.STATE_BIDIRECTIONAL, mConnectionServiceFixtureA);
    212 
    213         assertEquals(Call.STATE_RINGING, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
    214         assertEquals(Call.STATE_RINGING, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
    215 
    216         // Use TelecomManager API to answer the ringing call.
    217         TelecomManager telecomManager = (TelecomManager) mComponentContextFixture.getTestDouble()
    218                 .getApplicationContext().getSystemService(Context.TELECOM_SERVICE);
    219         telecomManager.acceptRingingCall(VideoProfile.STATE_AUDIO_ONLY);
    220 
    221         // The generic answer method on the ConnectionService is used to answer audio-only calls.
    222         verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT))
    223                 .answer(eq(ids.mConnectionId), any());
    224         mConnectionServiceFixtureA.sendSetActive(ids.mConnectionId);
    225 
    226         mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId);
    227     }
    228 
    229     /**
    230      * Tests the {@link TelecomManager#acceptRingingCall()} API.  Tests simple case of an incoming
    231      * video call, where an attempt is made to answer with an invalid video state.
    232      *
    233      * @throws Exception
    234      */
    235     @LargeTest
    236     @Test
    237     public void testTelecomManagerAcceptRingingInvalidVideoState() throws Exception {
    238         IdPair ids = startIncomingPhoneCall("650-555-1212", mPhoneAccountA0.getAccountHandle(),
    239                 VideoProfile.STATE_BIDIRECTIONAL, mConnectionServiceFixtureA);
    240 
    241         assertEquals(Call.STATE_RINGING, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
    242         assertEquals(Call.STATE_RINGING, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
    243 
    244         // Use TelecomManager API to answer the ringing call; the default expected behavior is to
    245         // answer using whatever video state the ringing call requests.
    246         TelecomManager telecomManager = (TelecomManager) mComponentContextFixture.getTestDouble()
    247                 .getApplicationContext().getSystemService(Context.TELECOM_SERVICE);
    248         telecomManager.acceptRingingCall(999 /* invalid videostate */);
    249 
    250         // Answer video API should be called
    251         verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT))
    252                 .answerVideo(eq(ids.mConnectionId), eq(VideoProfile.STATE_BIDIRECTIONAL), any());
    253         mConnectionServiceFixtureA.sendSetActive(ids.mConnectionId);
    254         mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId);
    255     }
    256 
    257     @LargeTest
    258     @Test
    259     public void testSingleIncomingCallLocalDisconnect() throws Exception {
    260         IdPair ids = startAndMakeActiveIncomingCall("650-555-1212",
    261                 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
    262         mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId);
    263         assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
    264         assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
    265 
    266         when(mClockProxy.currentTimeMillis()).thenReturn(TEST_DISCONNECT_TIME);
    267         when(mClockProxy.elapsedRealtime()).thenReturn(TEST_DISCONNECT_ELAPSED_TIME);
    268         mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL);
    269         assertEquals(Call.STATE_DISCONNECTED,
    270                 mInCallServiceFixtureX.getCall(ids.mCallId).getState());
    271         assertEquals(Call.STATE_DISCONNECTED,
    272                 mInCallServiceFixtureY.getCall(ids.mCallId).getState());
    273     }
    274 
    275     @LargeTest
    276     @Test
    277     public void testSingleIncomingCallRemoteDisconnect() throws Exception {
    278         IdPair ids = startAndMakeActiveIncomingCall("650-555-1212",
    279                 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
    280 
    281         when(mClockProxy.currentTimeMillis()).thenReturn(TEST_DISCONNECT_TIME);
    282         when(mClockProxy.elapsedRealtime()).thenReturn(TEST_DISCONNECT_ELAPSED_TIME);
    283         mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL);
    284         assertEquals(Call.STATE_DISCONNECTED,
    285                 mInCallServiceFixtureX.getCall(ids.mCallId).getState());
    286         assertEquals(Call.STATE_DISCONNECTED,
    287                 mInCallServiceFixtureY.getCall(ids.mCallId).getState());
    288     }
    289 
    290     @LargeTest
    291     @Test
    292     public void testIncomingEmergencyCallback() throws Exception {
    293         // Make an outgoing emergency call
    294         String phoneNumber = "650-555-1212";
    295         IdPair ids = startAndMakeDialingEmergencyCall(phoneNumber,
    296                 mPhoneAccountE0.getAccountHandle(), mConnectionServiceFixtureA);
    297         mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId);
    298         mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL);
    299 
    300         // Incoming call should be marked as a potential emergency callback
    301         Bundle extras = new Bundle();
    302         extras.putParcelable(
    303                 TelecomManager.EXTRA_INCOMING_CALL_ADDRESS,
    304                 Uri.fromParts(PhoneAccount.SCHEME_TEL, phoneNumber, null));
    305         mTelecomSystem.getTelecomServiceImpl().getBinder()
    306                 .addNewIncomingCall(mPhoneAccountA0.getAccountHandle(), extras);
    307 
    308         waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
    309         ArgumentCaptor<ConnectionRequest> connectionRequestCaptor
    310             = ArgumentCaptor.forClass(ConnectionRequest.class);
    311         verify(mConnectionServiceFixtureA.getTestDouble())
    312                 .createConnection(any(PhoneAccountHandle.class), anyString(),
    313                         connectionRequestCaptor.capture(), eq(true), eq(false), any());
    314 
    315         assertTrue(connectionRequestCaptor.getValue().getExtras().containsKey(
    316             android.telecom.Call.EXTRA_LAST_EMERGENCY_CALLBACK_TIME_MILLIS));
    317         assertTrue(connectionRequestCaptor.getValue().getExtras().getLong(
    318             android.telecom.Call.EXTRA_LAST_EMERGENCY_CALLBACK_TIME_MILLIS, 0) > 0);
    319         assertTrue(connectionRequestCaptor.getValue().getExtras().containsKey(
    320             TelecomManager.EXTRA_INCOMING_CALL_ADDRESS));
    321     }
    322 
    323     @LargeTest
    324     @Test
    325     public void testOutgoingCallAndSelectPhoneAccount() throws Exception {
    326         // Remove default PhoneAccount so that the Call moves into the correct
    327         // SELECT_PHONE_ACCOUNT state.
    328         mTelecomSystem.getPhoneAccountRegistrar().setUserSelectedOutgoingPhoneAccount(
    329                 null, Process.myUserHandle());
    330         int startingNumConnections = mConnectionServiceFixtureA.mConnectionById.size();
    331         int startingNumCalls = mInCallServiceFixtureX.mCallById.size();
    332         String callId = startOutgoingPhoneCallWithNoPhoneAccount("650-555-1212",
    333                 mConnectionServiceFixtureA);
    334         assertEquals(Call.STATE_SELECT_PHONE_ACCOUNT,
    335                 mInCallServiceFixtureX.getCall(callId).getState());
    336         assertEquals(Call.STATE_SELECT_PHONE_ACCOUNT,
    337                 mInCallServiceFixtureY.getCall(callId).getState());
    338         mInCallServiceFixtureX.mInCallAdapter.phoneAccountSelected(callId,
    339                 mPhoneAccountA0.getAccountHandle(), false);
    340 
    341         IdPair ids = outgoingCallPhoneAccountSelected(mPhoneAccountA0.getAccountHandle(),
    342                 startingNumConnections, startingNumCalls, mConnectionServiceFixtureA);
    343 
    344         when(mClockProxy.currentTimeMillis()).thenReturn(TEST_DISCONNECT_TIME);
    345         when(mClockProxy.elapsedRealtime()).thenReturn(TEST_DISCONNECT_ELAPSED_TIME);
    346         mConnectionServiceFixtureA.sendSetDisconnected(ids.mConnectionId, DisconnectCause.LOCAL);
    347         assertEquals(Call.STATE_DISCONNECTED,
    348                 mInCallServiceFixtureX.getCall(ids.mCallId).getState());
    349         assertEquals(Call.STATE_DISCONNECTED,
    350                 mInCallServiceFixtureY.getCall(ids.mCallId).getState());
    351     }
    352 
    353     @LargeTest
    354     @Test
    355     public void testIncomingCallFromContactWithSendToVoicemailIsRejected() throws Exception {
    356         Bundle extras = new Bundle();
    357         extras.putParcelable(
    358                 TelecomManager.EXTRA_INCOMING_CALL_ADDRESS,
    359                 Uri.fromParts(PhoneAccount.SCHEME_TEL, "650-555-1212", null));
    360         mTelecomSystem.getTelecomServiceImpl().getBinder()
    361                 .addNewIncomingCall(mPhoneAccountA0.getAccountHandle(), extras);
    362 
    363         waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
    364         verify(mConnectionServiceFixtureA.getTestDouble())
    365                 .createConnection(any(PhoneAccountHandle.class), anyString(),
    366                         any(ConnectionRequest.class), eq(true), eq(false), any());
    367 
    368         waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
    369         assertEquals(1, mCallerInfoAsyncQueryFactoryFixture.mRequests.size());
    370         for (CallerInfoAsyncQueryFactoryFixture.Request request :
    371                 mCallerInfoAsyncQueryFactoryFixture.mRequests) {
    372             CallerInfo sendToVoicemailCallerInfo = new CallerInfo();
    373             sendToVoicemailCallerInfo.shouldSendToVoicemail = true;
    374             request.replyWithCallerInfo(sendToVoicemailCallerInfo);
    375         }
    376 
    377         assertTrueWithTimeout(new Predicate<Void>() {
    378             @Override
    379             public boolean apply(Void aVoid) {
    380                 return mConnectionServiceFixtureA.mConnectionService.rejectedCallIds.size() == 1;
    381             }
    382         });
    383         assertTrueWithTimeout(new Predicate<Void>() {
    384             @Override
    385             public boolean apply(Void aVoid) {
    386                 return mMissedCallNotifier.missedCallsNotified.size() == 1;
    387             }
    388         });
    389 
    390         verify(mInCallServiceFixtureX.getTestDouble(), never())
    391                 .setInCallAdapter(any(IInCallAdapter.class));
    392         verify(mInCallServiceFixtureY.getTestDouble(), never())
    393                 .setInCallAdapter(any(IInCallAdapter.class));
    394     }
    395 
    396     @LargeTest
    397     @Test
    398     public void testIncomingCallCallerInfoLookupTimesOutIsAllowed() throws Exception {
    399         when(mClockProxy.currentTimeMillis()).thenReturn(TEST_CREATE_TIME);
    400         when(mClockProxy.elapsedRealtime()).thenReturn(TEST_CREATE_ELAPSED_TIME);
    401         Bundle extras = new Bundle();
    402         extras.putParcelable(
    403                 TelecomManager.EXTRA_INCOMING_CALL_ADDRESS,
    404                 Uri.fromParts(PhoneAccount.SCHEME_TEL, "650-555-1212", null));
    405         mTelecomSystem.getTelecomServiceImpl().getBinder()
    406                 .addNewIncomingCall(mPhoneAccountA0.getAccountHandle(), extras);
    407 
    408         waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
    409         verify(mConnectionServiceFixtureA.getTestDouble())
    410                 .createConnection(any(PhoneAccountHandle.class), anyString(),
    411                         any(ConnectionRequest.class), eq(true), eq(false), any());
    412 
    413         waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
    414         // Never reply to the caller info lookup.
    415         assertEquals(1, mCallerInfoAsyncQueryFactoryFixture.mRequests.size());
    416 
    417         verify(mInCallServiceFixtureX.getTestDouble(), timeout(TEST_TIMEOUT))
    418                 .setInCallAdapter(any(IInCallAdapter.class));
    419         verify(mInCallServiceFixtureY.getTestDouble(), timeout(TEST_TIMEOUT))
    420                 .setInCallAdapter(any(IInCallAdapter.class));
    421 
    422         assertEquals(0, mConnectionServiceFixtureA.mConnectionService.rejectedCallIds.size());
    423         assertEquals(0, mMissedCallNotifier.missedCallsNotified.size());
    424 
    425         assertTrueWithTimeout(new Predicate<Void>() {
    426             @Override
    427             public boolean apply(Void v) {
    428                 return mInCallServiceFixtureX.mInCallAdapter != null;
    429             }
    430         });
    431 
    432         verify(mInCallServiceFixtureX.getTestDouble(), timeout(TEST_TIMEOUT))
    433                 .addCall(any(ParcelableCall.class));
    434         verify(mInCallServiceFixtureY.getTestDouble(), timeout(TEST_TIMEOUT))
    435                 .addCall(any(ParcelableCall.class));
    436 
    437         when(mClockProxy.currentTimeMillis()).thenReturn(TEST_CONNECT_TIME);
    438         when(mClockProxy.elapsedRealtime()).thenReturn(TEST_CONNECT_ELAPSED_TIME);
    439         disconnectCall(mInCallServiceFixtureX.mLatestCallId,
    440                 mConnectionServiceFixtureA.mLatestConnectionId);
    441     }
    442 
    443     @LargeTest
    444     @Test
    445     @FlakyTest
    446     public void testIncomingCallFromBlockedNumberIsRejected() throws Exception {
    447         String phoneNumber = "650-555-1212";
    448         blockNumber(phoneNumber);
    449 
    450         Bundle extras = new Bundle();
    451         extras.putParcelable(
    452                 TelecomManager.EXTRA_INCOMING_CALL_ADDRESS,
    453                 Uri.fromParts(PhoneAccount.SCHEME_TEL, phoneNumber, null));
    454         mTelecomSystem.getTelecomServiceImpl().getBinder()
    455                 .addNewIncomingCall(mPhoneAccountA0.getAccountHandle(), extras);
    456 
    457         waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
    458         verify(mConnectionServiceFixtureA.getTestDouble())
    459                 .createConnection(any(PhoneAccountHandle.class), anyString(),
    460                         any(ConnectionRequest.class), eq(true), eq(false), any());
    461 
    462         waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
    463         assertEquals(1, mCallerInfoAsyncQueryFactoryFixture.mRequests.size());
    464         for (CallerInfoAsyncQueryFactoryFixture.Request request :
    465                 mCallerInfoAsyncQueryFactoryFixture.mRequests) {
    466             request.reply();
    467         }
    468 
    469         assertTrueWithTimeout(new Predicate<Void>() {
    470             @Override
    471             public boolean apply(Void aVoid) {
    472                 return mConnectionServiceFixtureA.mConnectionService.rejectedCallIds.size() == 1;
    473             }
    474         });
    475         assertEquals(0, mMissedCallNotifier.missedCallsNotified.size());
    476 
    477         verify(mInCallServiceFixtureX.getTestDouble(), never())
    478                 .setInCallAdapter(any(IInCallAdapter.class));
    479         verify(mInCallServiceFixtureY.getTestDouble(), never())
    480                 .setInCallAdapter(any(IInCallAdapter.class));
    481     }
    482 
    483     @LargeTest
    484     @Test
    485     public void testIncomingCallBlockCheckTimesoutIsAllowed() throws Exception {
    486         final CountDownLatch latch = new CountDownLatch(1);
    487         String phoneNumber = "650-555-1212";
    488         blockNumberWithAnswer(phoneNumber, new Answer<Bundle>() {
    489             @Override
    490             public Bundle answer(InvocationOnMock invocation) throws Throwable {
    491                 latch.await(TEST_TIMEOUT * 2, TimeUnit.MILLISECONDS);
    492                 Bundle bundle = new Bundle();
    493                 bundle.putBoolean(BlockedNumberContract.RES_NUMBER_IS_BLOCKED, true);
    494                 return bundle;
    495             }
    496         });
    497 
    498         IdPair ids = startAndMakeActiveIncomingCall(
    499                 phoneNumber, mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
    500         latch.countDown();
    501 
    502         assertEquals(0, mConnectionServiceFixtureA.mConnectionService.rejectedCallIds.size());
    503         assertEquals(0, mMissedCallNotifier.missedCallsNotified.size());
    504         disconnectCall(ids.mCallId, ids.mConnectionId);
    505     }
    506 
    507     public void do_testDeadlockOnOutgoingCall() throws Exception {
    508         final IdPair ids = startOutgoingPhoneCall("650-555-1212",
    509                 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA,
    510                 Process.myUserHandle());
    511         rapidFire(
    512                 new Runnable() {
    513                     @Override
    514                     public void run() {
    515                         while (mCallerInfoAsyncQueryFactoryFixture.mRequests.size() > 0) {
    516                             mCallerInfoAsyncQueryFactoryFixture.mRequests.remove(0).reply();
    517                         }
    518                     }
    519                 },
    520                 new Runnable() {
    521                     @Override
    522                     public void run() {
    523                         try {
    524                             mConnectionServiceFixtureA.sendSetActive(ids.mConnectionId);
    525                         } catch (Exception e) {
    526                             Log.e(this, e, "");
    527                         }
    528                     }
    529                 });
    530     }
    531 
    532     @LargeTest
    533     @Test
    534     public void testIncomingThenOutgoingCalls() throws Exception {
    535         // TODO: We have to use the same PhoneAccount for both; see http://b/18461539
    536         IdPair incoming = startAndMakeActiveIncomingCall("650-555-2323",
    537                 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
    538         IdPair outgoing = startAndMakeActiveOutgoingCall("650-555-1212",
    539                 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
    540 
    541         mInCallServiceFixtureX.mInCallAdapter.disconnectCall(incoming.mCallId);
    542         mInCallServiceFixtureX.mInCallAdapter.disconnectCall(outgoing.mCallId);
    543     }
    544 
    545     @LargeTest
    546     @Test
    547     public void testOutgoingThenIncomingCalls() throws Exception {
    548         // TODO: We have to use the same PhoneAccount for both; see http://b/18461539
    549         IdPair outgoing = startAndMakeActiveOutgoingCall("650-555-1212",
    550                 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
    551         IdPair incoming = startAndMakeActiveIncomingCall("650-555-2323",
    552                 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
    553         verify(mConnectionServiceFixtureA.getTestDouble())
    554                 .hold(eq(outgoing.mConnectionId), any());
    555         mConnectionServiceFixtureA.mConnectionById.get(outgoing.mConnectionId).state =
    556                 Connection.STATE_HOLDING;
    557         mConnectionServiceFixtureA.sendSetOnHold(outgoing.mConnectionId);
    558         assertEquals(Call.STATE_HOLDING,
    559                 mInCallServiceFixtureX.getCall(outgoing.mCallId).getState());
    560         assertEquals(Call.STATE_HOLDING,
    561                 mInCallServiceFixtureY.getCall(outgoing.mCallId).getState());
    562 
    563         mInCallServiceFixtureX.mInCallAdapter.disconnectCall(incoming.mCallId);
    564         mInCallServiceFixtureX.mInCallAdapter.disconnectCall(outgoing.mCallId);
    565     }
    566 
    567     @LargeTest
    568     @Test
    569     public void testAudioManagerOperations() throws Exception {
    570         AudioManager audioManager = (AudioManager) mComponentContextFixture.getTestDouble()
    571                 .getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
    572 
    573         IdPair outgoing = startAndMakeActiveOutgoingCall("650-555-1212",
    574                 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
    575 
    576         verify(audioManager, timeout(TEST_TIMEOUT)).requestAudioFocusForCall(anyInt(), anyInt());
    577         verify(audioManager, timeout(TEST_TIMEOUT).atLeastOnce())
    578                 .setMode(AudioManager.MODE_IN_CALL);
    579 
    580         mInCallServiceFixtureX.mInCallAdapter.mute(true);
    581         verify(mAudioService, timeout(TEST_TIMEOUT))
    582                 .setMicrophoneMute(eq(true), any(String.class), any(Integer.class));
    583         mInCallServiceFixtureX.mInCallAdapter.mute(false);
    584         verify(mAudioService, timeout(TEST_TIMEOUT))
    585                 .setMicrophoneMute(eq(false), any(String.class), any(Integer.class));
    586 
    587         mInCallServiceFixtureX.mInCallAdapter.setAudioRoute(CallAudioState.ROUTE_SPEAKER, null);
    588         verify(audioManager, timeout(TEST_TIMEOUT))
    589                 .setSpeakerphoneOn(true);
    590         mInCallServiceFixtureX.mInCallAdapter.setAudioRoute(CallAudioState.ROUTE_EARPIECE, null);
    591         verify(audioManager, timeout(TEST_TIMEOUT))
    592                 .setSpeakerphoneOn(false);
    593 
    594         mConnectionServiceFixtureA.
    595                 sendSetDisconnected(outgoing.mConnectionId, DisconnectCause.REMOTE);
    596 
    597         verify(audioManager, timeout(TEST_TIMEOUT))
    598                 .abandonAudioFocusForCall();
    599         verify(audioManager, timeout(TEST_TIMEOUT).atLeastOnce())
    600                 .setMode(AudioManager.MODE_NORMAL);
    601     }
    602 
    603     private void rapidFire(Runnable... tasks) {
    604         final CyclicBarrier barrier = new CyclicBarrier(tasks.length);
    605         final CountDownLatch latch = new CountDownLatch(tasks.length);
    606         for (int i = 0; i < tasks.length; i++) {
    607             final Runnable task = tasks[i];
    608             new Thread(new Runnable() {
    609                 @Override
    610                 public void run() {
    611                     try {
    612                         barrier.await();
    613                         task.run();
    614                     } catch (InterruptedException | BrokenBarrierException e){
    615                         Log.e(BasicCallTests.this, e, "Unexpectedly interrupted");
    616                     } finally {
    617                         latch.countDown();
    618                     }
    619                 }
    620             }).start();
    621         }
    622         try {
    623             latch.await();
    624         } catch (InterruptedException e) {
    625             Log.e(BasicCallTests.this, e, "Unexpectedly interrupted");
    626         }
    627     }
    628 
    629     @MediumTest
    630     @Test
    631     public void testBasicConferenceCall() throws Exception {
    632         makeConferenceCall();
    633     }
    634 
    635     @MediumTest
    636     @Test
    637     public void testAddCallToConference1() throws Exception {
    638         ParcelableCall conferenceCall = makeConferenceCall();
    639         IdPair callId3 = startAndMakeActiveOutgoingCall("650-555-1214",
    640                 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
    641         // testAddCallToConference{1,2} differ in the order of arguments to InCallAdapter#conference
    642         mInCallServiceFixtureX.getInCallAdapter().conference(
    643                 conferenceCall.getId(), callId3.mCallId);
    644         Thread.sleep(200);
    645 
    646         ParcelableCall call3 = mInCallServiceFixtureX.getCall(callId3.mCallId);
    647         ParcelableCall updatedConference = mInCallServiceFixtureX.getCall(conferenceCall.getId());
    648         assertEquals(conferenceCall.getId(), call3.getParentCallId());
    649         assertEquals(3, updatedConference.getChildCallIds().size());
    650         assertTrue(updatedConference.getChildCallIds().contains(callId3.mCallId));
    651     }
    652 
    653     @MediumTest
    654     @Test
    655     public void testAddCallToConference2() throws Exception {
    656         ParcelableCall conferenceCall = makeConferenceCall();
    657         IdPair callId3 = startAndMakeActiveOutgoingCall("650-555-1214",
    658                 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
    659         mInCallServiceFixtureX.getInCallAdapter()
    660                 .conference(callId3.mCallId, conferenceCall.getId());
    661         Thread.sleep(200);
    662 
    663         ParcelableCall call3 = mInCallServiceFixtureX.getCall(callId3.mCallId);
    664         ParcelableCall updatedConference = mInCallServiceFixtureX.getCall(conferenceCall.getId());
    665         assertEquals(conferenceCall.getId(), call3.getParentCallId());
    666         assertEquals(3, updatedConference.getChildCallIds().size());
    667         assertTrue(updatedConference.getChildCallIds().contains(callId3.mCallId));
    668     }
    669 
    670     /**
    671      * Tests the {@link Call#pullExternalCall()} API.  Verifies that if a call is not an external
    672      * call, no pull call request is made to the connection service.
    673      *
    674      * @throws Exception
    675      */
    676     @MediumTest
    677     @Test
    678     public void testPullNonExternalCall() throws Exception {
    679         // TODO: Revisit this unit test once telecom support for filtering external calls from
    680         // InCall services is implemented.
    681         IdPair ids = startAndMakeActiveIncomingCall("650-555-1212",
    682                 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
    683         assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
    684 
    685         // Attempt to pull the call and verify the API call makes it through
    686         mInCallServiceFixtureX.mInCallAdapter.pullExternalCall(ids.mCallId);
    687         Thread.sleep(TEST_TIMEOUT);
    688         verify(mConnectionServiceFixtureA.getTestDouble(), never())
    689                 .pullExternalCall(eq(ids.mCallId), any());
    690     }
    691 
    692     /**
    693      * Tests the {@link Connection#sendConnectionEvent(String, Bundle)} API.
    694      *
    695      * @throws Exception
    696      */
    697     @MediumTest
    698     @Test
    699     public void testSendConnectionEventNull() throws Exception {
    700         IdPair ids = startAndMakeActiveIncomingCall("650-555-1212",
    701                 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
    702         assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
    703         mConnectionServiceFixtureA.sendConnectionEvent(ids.mConnectionId, TEST_EVENT, null);
    704         verify(mInCallServiceFixtureX.getTestDouble(), timeout(TEST_TIMEOUT))
    705                 .onConnectionEvent(ids.mCallId, TEST_EVENT, null);
    706     }
    707 
    708     /**
    709      * Tests the {@link Connection#sendConnectionEvent(String, Bundle)} API.
    710      *
    711      * @throws Exception
    712      */
    713     @MediumTest
    714     @Test
    715     public void testSendConnectionEventNotNull() throws Exception {
    716         IdPair ids = startAndMakeActiveIncomingCall("650-555-1212",
    717                 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
    718         assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
    719 
    720         Bundle testBundle = new Bundle();
    721         testBundle.putString(TEST_BUNDLE_KEY, "TEST");
    722 
    723         ArgumentCaptor<Bundle> bundleArgumentCaptor = ArgumentCaptor.forClass(Bundle.class);
    724         mConnectionServiceFixtureA.sendConnectionEvent(ids.mConnectionId, TEST_EVENT, testBundle);
    725         verify(mInCallServiceFixtureX.getTestDouble(), timeout(TEST_TIMEOUT))
    726                 .onConnectionEvent(eq(ids.mCallId), eq(TEST_EVENT), bundleArgumentCaptor.capture());
    727         assert (bundleArgumentCaptor.getValue().containsKey(TEST_BUNDLE_KEY));
    728     }
    729 
    730     /**
    731      * Tests the {@link Call#sendCallEvent(String, Bundle)} API.
    732      *
    733      * @throws Exception
    734      */
    735     @MediumTest
    736     @Test
    737     public void testSendCallEventNull() throws Exception {
    738         IdPair ids = startAndMakeActiveIncomingCall("650-555-1212",
    739                 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
    740         assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
    741 
    742         mInCallServiceFixtureX.mInCallAdapter.sendCallEvent(ids.mCallId, TEST_EVENT, 26, null);
    743         verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT))
    744                 .sendCallEvent(eq(ids.mConnectionId), eq(TEST_EVENT), isNull(Bundle.class), any());
    745     }
    746 
    747     /**
    748      * Tests the {@link Call#sendCallEvent(String, Bundle)} API.
    749      *
    750      * @throws Exception
    751      */
    752     @MediumTest
    753     @Test
    754     public void testSendCallEventNonNull() throws Exception {
    755         IdPair ids = startAndMakeActiveIncomingCall("650-555-1212",
    756                 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
    757         assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
    758 
    759         Bundle testBundle = new Bundle();
    760         testBundle.putString(TEST_BUNDLE_KEY, "TEST");
    761 
    762         ArgumentCaptor<Bundle> bundleArgumentCaptor = ArgumentCaptor.forClass(Bundle.class);
    763         mInCallServiceFixtureX.mInCallAdapter.sendCallEvent(ids.mCallId, TEST_EVENT, 26,
    764                 testBundle);
    765         verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT))
    766                 .sendCallEvent(eq(ids.mConnectionId), eq(TEST_EVENT),
    767                         bundleArgumentCaptor.capture(), any());
    768         assert (bundleArgumentCaptor.getValue().containsKey(TEST_BUNDLE_KEY));
    769     }
    770 
    771     private void blockNumber(String phoneNumber) throws Exception {
    772         blockNumberWithAnswer(phoneNumber, new Answer<Bundle>() {
    773             @Override
    774             public Bundle answer(InvocationOnMock invocation) throws Throwable {
    775                 Bundle bundle = new Bundle();
    776                 bundle.putBoolean(BlockedNumberContract.RES_NUMBER_IS_BLOCKED, true);
    777                 return bundle;
    778             }
    779         });
    780     }
    781 
    782     private void blockNumberWithAnswer(String phoneNumber, Answer answer) throws Exception {
    783         when(getBlockedNumberProvider().call(
    784                 anyString(),
    785                 eq(BlockedNumberContract.SystemContract.METHOD_SHOULD_SYSTEM_BLOCK_NUMBER),
    786                 eq(phoneNumber),
    787                 isNull(Bundle.class))).thenAnswer(answer);
    788     }
    789 
    790     private void verifyNoBlockChecks() {
    791         verifyZeroInteractions(getBlockedNumberProvider());
    792     }
    793 
    794     private IContentProvider getBlockedNumberProvider() {
    795         return mSpyContext.getContentResolver().acquireProvider(BlockedNumberContract.AUTHORITY);
    796     }
    797 
    798     private void disconnectCall(String callId, String connectionId) throws Exception {
    799         when(mClockProxy.currentTimeMillis()).thenReturn(TEST_DISCONNECT_TIME);
    800         when(mClockProxy.elapsedRealtime()).thenReturn(TEST_DISCONNECT_ELAPSED_TIME);
    801         mConnectionServiceFixtureA.sendSetDisconnected(connectionId, DisconnectCause.LOCAL);
    802         assertEquals(Call.STATE_DISCONNECTED, mInCallServiceFixtureX.getCall(callId).getState());
    803         assertEquals(Call.STATE_DISCONNECTED, mInCallServiceFixtureY.getCall(callId).getState());
    804         assertEquals(TEST_CREATE_TIME,
    805                 mInCallServiceFixtureX.getCall(callId).getCreationTimeMillis());
    806         assertEquals(TEST_CREATE_TIME,
    807                 mInCallServiceFixtureY.getCall(callId).getCreationTimeMillis());
    808     }
    809 
    810     /**
    811      * Tests to make sure that the Call.Details.PROPERTY_HAS_CDMA_VOICE_PRIVACY property is set on a
    812      * Call that is based on a Connection with the Connection.PROPERTY_HAS_CDMA_VOICE_PRIVACY
    813      * property set.
    814      */
    815     @MediumTest
    816     @Test
    817     public void testCdmaEnhancedPrivacyVoiceCall() throws Exception {
    818         mConnectionServiceFixtureA.mConnectionServiceDelegate.mProperties =
    819                 Connection.PROPERTY_HAS_CDMA_VOICE_PRIVACY;
    820 
    821         IdPair ids = startAndMakeActiveOutgoingCall("650-555-1212",
    822                 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
    823         assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
    824 
    825         assertTrue(Call.Details.hasProperty(
    826                 mInCallServiceFixtureX.getCall(ids.mCallId).getProperties(),
    827                 Call.Details.PROPERTY_HAS_CDMA_VOICE_PRIVACY));
    828     }
    829 
    830     /**
    831      * Tests to make sure that Call.Details.PROPERTY_HAS_CDMA_VOICE_PRIVACY is dropped
    832      * when the Connection.PROPERTY_HAS_CDMA_VOICE_PRIVACY property is removed from the Connection.
    833      */
    834     @MediumTest
    835     @Test
    836     public void testDropCdmaEnhancedPrivacyVoiceCall() throws Exception {
    837         mConnectionServiceFixtureA.mConnectionServiceDelegate.mProperties =
    838                 Connection.PROPERTY_HAS_CDMA_VOICE_PRIVACY;
    839 
    840         IdPair ids = startAndMakeActiveOutgoingCall("650-555-1212",
    841                 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
    842         assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
    843         mConnectionServiceFixtureA.mLatestConnection.setConnectionProperties(0);
    844 
    845         assertFalse(Call.Details.hasProperty(
    846                 mInCallServiceFixtureX.getCall(ids.mCallId).getProperties(),
    847                 Call.Details.PROPERTY_HAS_CDMA_VOICE_PRIVACY));
    848     }
    849 
    850     /**
    851      * Tests the {@link Call#pullExternalCall()} API.  Ensures that an external call which is
    852      * pullable can be pulled.
    853      *
    854      * @throws Exception
    855      */
    856     @LargeTest
    857     @Test
    858     public void testPullExternalCall() throws Exception {
    859         // TODO: Revisit this unit test once telecom support for filtering external calls from
    860         // InCall services is implemented.
    861         mConnectionServiceFixtureA.mConnectionServiceDelegate.mCapabilities =
    862                 Connection.CAPABILITY_CAN_PULL_CALL;
    863         mConnectionServiceFixtureA.mConnectionServiceDelegate.mProperties =
    864                 Connection.PROPERTY_IS_EXTERNAL_CALL;
    865 
    866         IdPair ids = startAndMakeActiveIncomingCall("650-555-1212",
    867                 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
    868         assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
    869 
    870         // Attempt to pull the call and verify the API call makes it through
    871         mInCallServiceFixtureX.mInCallAdapter.pullExternalCall(ids.mCallId);
    872         verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT))
    873                 .pullExternalCall(eq(ids.mConnectionId), any());
    874     }
    875 
    876     /**
    877      * Tests the {@link Call#pullExternalCall()} API.  Verifies that if an external call is not
    878      * marked as pullable that the connection service does not get an API call to pull the external
    879      * call.
    880      *
    881      * @throws Exception
    882      */
    883     @LargeTest
    884     @Test
    885     public void testPullNonPullableExternalCall() throws Exception {
    886         // TODO: Revisit this unit test once telecom support for filtering external calls from
    887         // InCall services is implemented.
    888         mConnectionServiceFixtureA.mConnectionServiceDelegate.mProperties =
    889                 Connection.PROPERTY_IS_EXTERNAL_CALL;
    890 
    891         IdPair ids = startAndMakeActiveIncomingCall("650-555-1212",
    892                 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
    893         assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
    894 
    895         // Attempt to pull the call and verify the API call makes it through
    896         mInCallServiceFixtureX.mInCallAdapter.pullExternalCall(ids.mCallId);
    897         Thread.sleep(TEST_TIMEOUT);
    898         verify(mConnectionServiceFixtureA.getTestDouble(), never())
    899                 .pullExternalCall(eq(ids.mConnectionId), any());
    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 supports video calling.
    905      * @throws Exception
    906      */
    907     @LargeTest
    908     @Test
    909     public void testOutgoingCallSelectPhoneAccountVideo() 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 supports video calling.
    919         call.setTargetPhoneAccount(mPhoneAccountA1.getAccountHandle());
    920         assert(call.isVideoCallingSupported());
    921         assertEquals(VideoProfile.STATE_BIDIRECTIONAL, call.getVideoState());
    922     }
    923 
    924     /**
    925      * Test scenario where the user starts an outgoing video call with no selected PhoneAccount, and
    926      * then subsequently selects a PhoneAccount which does not support video calling.
    927      * @throws Exception
    928      */
    929     @FlakyTest
    930     @LargeTest
    931     @Test
    932     public void testOutgoingCallSelectPhoneAccountNoVideo() throws Exception {
    933         startOutgoingPhoneCallPendingCreateConnection("650-555-1212",
    934                 null, mConnectionServiceFixtureA,
    935                 Process.myUserHandle(), VideoProfile.STATE_BIDIRECTIONAL);
    936         com.android.server.telecom.Call call = mTelecomSystem.getCallsManager().getCalls()
    937                 .iterator().next();
    938         assert(call.isVideoCallingSupported());
    939         assertEquals(VideoProfile.STATE_BIDIRECTIONAL, call.getVideoState());
    940 
    941         // Change the phone account to one which does not support video calling.
    942         call.setTargetPhoneAccount(mPhoneAccountA2.getAccountHandle());
    943         assert(!call.isVideoCallingSupported());
    944         assertEquals(VideoProfile.STATE_AUDIO_ONLY, call.getVideoState());
    945     }
    946 
    947     /**
    948      * Basic test to ensure that a self-managed ConnectionService can place a call.
    949      * @throws Exception
    950      */
    951     @LargeTest
    952     @Test
    953     public void testSelfManagedOutgoing() throws Exception {
    954         PhoneAccountHandle phoneAccountHandle = mPhoneAccountSelfManaged.getAccountHandle();
    955         IdPair ids = startAndMakeActiveOutgoingCall("650-555-1212", phoneAccountHandle,
    956                 mConnectionServiceFixtureA);
    957 
    958         // The InCallService should not know about the call since its self-managed.
    959         assertNull(mInCallServiceFixtureX.getCall(ids.mCallId));
    960     }
    961 
    962     /**
    963      * Basic test to ensure that a self-managed ConnectionService can add an incoming call.
    964      * @throws Exception
    965      */
    966     @LargeTest
    967     @Test
    968     public void testSelfManagedIncoming() throws Exception {
    969         PhoneAccountHandle phoneAccountHandle = mPhoneAccountSelfManaged.getAccountHandle();
    970         IdPair ids = startAndMakeActiveIncomingCall("650-555-1212", phoneAccountHandle,
    971                 mConnectionServiceFixtureA);
    972 
    973         // The InCallService should not know about the call since its self-managed.
    974         assertNull(mInCallServiceFixtureX.getCall(ids.mCallId));
    975     }
    976 
    977     /**
    978      * Basic test to ensure that when there are no calls, we permit outgoing calls by a self managed
    979      * CS.
    980      * @throws Exception
    981      */
    982     @LargeTest
    983     @Test
    984     public void testIsOutgoingCallPermitted() throws Exception {
    985         assertTrue(mTelecomSystem.getTelecomServiceImpl().getBinder()
    986                 .isOutgoingCallPermitted(mPhoneAccountSelfManaged.getAccountHandle()));
    987     }
    988 
    989     /**
    990      * Ensure if there is a holdable call ongoing we'll be able to place another call.
    991      * @throws Exception
    992      */
    993     @LargeTest
    994     @Test
    995     public void testIsOutgoingCallPermittedOngoingHoldable() throws Exception {
    996         // Start a regular call; the self-managed CS can make a call now since ongoing call can be
    997         // held
    998         IdPair ids = startAndMakeActiveIncomingCall("650-555-1212",
    999                 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
   1000         assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
   1001 
   1002         assertTrue(mTelecomSystem.getTelecomServiceImpl().getBinder()
   1003                 .isOutgoingCallPermitted(mPhoneAccountSelfManaged.getAccountHandle()));
   1004     }
   1005 
   1006     /**
   1007      * Ensure if there is an unholdable call we can't place another call.
   1008      * @throws Exception
   1009      */
   1010     @LargeTest
   1011     @Test
   1012     public void testIsOutgoingCallPermittedOngoingUnHoldable() throws Exception {
   1013         // Start a regular call; the self-managed CS can't make a call now because the ongoing call
   1014         // can't be held.
   1015         mConnectionServiceFixtureA.mConnectionServiceDelegate.mCapabilities = 0;
   1016         IdPair ids = startAndMakeActiveIncomingCall("650-555-1212",
   1017                 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
   1018         assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
   1019 
   1020         assertTrue(mTelecomSystem.getTelecomServiceImpl().getBinder()
   1021                 .isOutgoingCallPermitted(mPhoneAccountSelfManaged.getAccountHandle()));
   1022     }
   1023 
   1024     /**
   1025      * Basic to verify audio route gets reset to baseline when emergency call placed while a
   1026      * self-managed call is underway.
   1027      * @throws Exception
   1028      */
   1029     @LargeTest
   1030     @Test
   1031     @FlakyTest
   1032     public void testDisconnectSelfManaged() throws Exception {
   1033         // Add a self-managed call.
   1034         PhoneAccountHandle phoneAccountHandle = mPhoneAccountSelfManaged.getAccountHandle();
   1035         startAndMakeActiveIncomingCall("650-555-1212", phoneAccountHandle,
   1036                 mConnectionServiceFixtureA);
   1037         Connection connection = mConnectionServiceFixtureA.mLatestConnection;
   1038 
   1039         // Route self-managed call to speaker.
   1040         connection.setAudioRoute(CallAudioState.ROUTE_SPEAKER);
   1041         waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
   1042 
   1043         // Place an emergency call.
   1044         startAndMakeDialingEmergencyCall("650-555-1212", mPhoneAccountE0.getAccountHandle(),
   1045                 mConnectionServiceFixtureA);
   1046 
   1047         // Should have reverted back to earpiece.
   1048         assertEquals(CallAudioState.ROUTE_EARPIECE,
   1049                 mInCallServiceFixtureX.mCallAudioState.getRoute());
   1050     }
   1051 
   1052     /**
   1053      * Tests the {@link Call#deflect} API.  Verifies that if a call is incoming,
   1054      * and deflect API is called, then request is made to the connection service.
   1055      *
   1056      * @throws Exception
   1057      */
   1058     @LargeTest
   1059     @Test
   1060     public void testDeflectCallWhenIncoming() throws Exception {
   1061         Uri deflectAddress = Uri.parse("tel:650-555-1214");
   1062         IdPair ids = startIncomingPhoneCall("650-555-1212", mPhoneAccountA0.getAccountHandle(),
   1063                 mConnectionServiceFixtureA);
   1064 
   1065         assertEquals(Call.STATE_RINGING, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
   1066         assertEquals(Call.STATE_RINGING, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
   1067         // Attempt to deflect the call and verify the API call makes it through
   1068         mInCallServiceFixtureX.mInCallAdapter.deflectCall(ids.mCallId, deflectAddress);
   1069         verify(mConnectionServiceFixtureA.getTestDouble(), timeout(TEST_TIMEOUT))
   1070                 .deflect(eq(ids.mConnectionId), eq(deflectAddress), any());
   1071         mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId);
   1072     }
   1073 
   1074     /**
   1075      * Tests the {@link Call#deflect} API.  Verifies that if a call is outgoing,
   1076      * and deflect API is called, then request is not made to the connection service.
   1077      * Ideally, deflect option should be displayed only if call is incoming/waiting.
   1078      *
   1079      * @throws Exception
   1080      */
   1081     @LargeTest
   1082     @Test
   1083     public void testDeflectCallWhenOutgoing() throws Exception {
   1084         Uri deflectAddress = Uri.parse("tel:650-555-1214");
   1085         IdPair ids = startOutgoingPhoneCall("650-555-1212", mPhoneAccountA0.getAccountHandle(),
   1086                 mConnectionServiceFixtureA, Process.myUserHandle());
   1087         // Attempt to deflect the call and verify the API call does not make it through
   1088         mInCallServiceFixtureX.mInCallAdapter.deflectCall(ids.mCallId, deflectAddress);
   1089         verify(mConnectionServiceFixtureA.getTestDouble(), never())
   1090                 .deflect(eq(ids.mConnectionId), eq(deflectAddress), any());
   1091         mInCallServiceFixtureX.mInCallAdapter.disconnectCall(ids.mCallId);
   1092     }
   1093 
   1094     /**
   1095      * Test to make sure to unmute automatically when making an emergency call and keep unmute
   1096      * during the emergency call.
   1097      * @throws Exception
   1098      */
   1099     @LargeTest
   1100     @Test
   1101     public void testUnmuteDuringEmergencyCall() throws Exception {
   1102         // Make an outgoing call and turn ON mute.
   1103         IdPair outgoingCall = startAndMakeActiveOutgoingCall("650-555-1212",
   1104                 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
   1105         assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(outgoingCall.mCallId)
   1106                 .getState());
   1107         mInCallServiceFixtureX.mInCallAdapter.mute(true);
   1108         waitForHandlerAction(mTelecomSystem.getCallsManager().getCallAudioManager()
   1109                 .getCallAudioRouteStateMachine().getHandler(), TEST_TIMEOUT);
   1110         assertTrue(mTelecomSystem.getCallsManager().getAudioState().isMuted());
   1111 
   1112         // Make an emergency call.
   1113         IdPair emergencyCall = startAndMakeDialingEmergencyCall("650-555-1213",
   1114                 mPhoneAccountE0.getAccountHandle(), mConnectionServiceFixtureA);
   1115         assertEquals(Call.STATE_DIALING, mInCallServiceFixtureX.getCall(emergencyCall.mCallId)
   1116                 .getState());
   1117         waitForHandlerAction(mTelecomSystem.getCallsManager().getCallAudioManager()
   1118                 .getCallAudioRouteStateMachine().getHandler(), TEST_TIMEOUT);
   1119         // Should be unmute automatically.
   1120         assertFalse(mTelecomSystem.getCallsManager().getAudioState().isMuted());
   1121 
   1122         // Toggle mute during an emergency call.
   1123         mTelecomSystem.getCallsManager().getCallAudioManager().toggleMute();
   1124         waitForHandlerAction(mTelecomSystem.getCallsManager().getCallAudioManager()
   1125                 .getCallAudioRouteStateMachine().getHandler(), TEST_TIMEOUT);
   1126         // Should keep unmute.
   1127         assertFalse(mTelecomSystem.getCallsManager().getAudioState().isMuted());
   1128 
   1129         ArgumentCaptor<Boolean> muteValueCaptor = ArgumentCaptor.forClass(Boolean.class);
   1130         verify(mAudioService, times(2)).setMicrophoneMute(muteValueCaptor.capture(),
   1131                 any(String.class), any(Integer.class));
   1132         List<Boolean> muteValues = muteValueCaptor.getAllValues();
   1133         // Check mute status was changed twice with true and false.
   1134         assertTrue(muteValues.get(0));
   1135         assertFalse(muteValues.get(1));
   1136     }
   1137 }
   1138