blob: cf17b5c198cdb1a5bfca052bc9c4c191c4714b37 [file] [log] [blame]
Ihab Awadaa383cc2015-03-22 22:12:28 -07001/*
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
Brad Ebinger2c93c502015-10-28 00:23:54 +000017package com.android.server.telecom.tests;
Ihab Awadaa383cc2015-03-22 22:12:28 -070018
Ihab Awad32dd7c32015-05-28 10:52:20 -070019
Santos Cordon92694512015-04-23 14:47:28 -070020import static org.mockito.Matchers.any;
21import static org.mockito.Matchers.anyBoolean;
22import static org.mockito.Matchers.anyInt;
23import static org.mockito.Matchers.anyString;
24import static org.mockito.Matchers.eq;
Abhijith Shastryc6e42ef2016-02-19 18:26:44 -080025import static org.mockito.Matchers.isNull;
Hall Liu8fb1fb72015-10-22 15:24:40 -070026import static org.mockito.Mockito.doAnswer;
27import static org.mockito.Mockito.doReturn;
Santos Cordon92694512015-04-23 14:47:28 -070028import static org.mockito.Mockito.mock;
Ihab Awad1b5490a2015-05-12 13:13:48 -070029import static org.mockito.Mockito.reset;
Tyler Gunnae694b12015-11-11 17:46:03 -080030import static org.mockito.Mockito.spy;
Santos Cordon92694512015-04-23 14:47:28 -070031import static org.mockito.Mockito.timeout;
Hall Liuf7783fb2015-11-23 18:45:48 -080032import static org.mockito.Mockito.times;
Santos Cordon92694512015-04-23 14:47:28 -070033import static org.mockito.Mockito.verify;
Hall Liu6d4b66d2016-04-01 16:31:13 -070034import static org.mockito.Mockito.when;
Santos Cordon92694512015-04-23 14:47:28 -070035
Tyler Gunneaaf0742016-09-15 15:36:38 -070036import android.app.NotificationManager;
Santos Cordon92694512015-04-23 14:47:28 -070037import android.content.BroadcastReceiver;
38import android.content.ComponentName;
Hall Liu6d4b66d2016-04-01 16:31:13 -070039import android.content.ContentResolver;
Santos Cordon92694512015-04-23 14:47:28 -070040import android.content.Context;
Abhijith Shastryc6e42ef2016-02-19 18:26:44 -080041import android.content.IContentProvider;
Santos Cordon92694512015-04-23 14:47:28 -070042import android.content.Intent;
Ihab Awadb60f0062015-05-26 16:20:32 -070043import android.media.AudioManager;
Hall Liu8fb1fb72015-10-22 15:24:40 -070044import android.media.IAudioService;
Santos Cordon92694512015-04-23 14:47:28 -070045import android.net.Uri;
46import android.os.Bundle;
47import android.os.Handler;
Brad Ebinger84771f82016-05-18 16:57:30 -070048import android.os.Looper;
Tony Mak578a4e62015-11-23 11:18:51 +000049import android.os.Process;
Santos Cordon92694512015-04-23 14:47:28 -070050import android.os.UserHandle;
Abhijith Shastryc6e42ef2016-02-19 18:26:44 -080051import android.provider.BlockedNumberContract;
Ihab Awad0a4b95f2015-05-18 10:15:38 -070052import android.telecom.Call;
Santos Cordon92694512015-04-23 14:47:28 -070053import android.telecom.ConnectionRequest;
Brad Ebinger6e8f3d72016-06-20 11:35:42 -070054import android.telecom.DisconnectCause;
Santos Cordon92694512015-04-23 14:47:28 -070055import android.telecom.ParcelableCall;
56import android.telecom.PhoneAccount;
57import android.telecom.PhoneAccountHandle;
58import android.telecom.TelecomManager;
Ihab Awad32dd7c32015-05-28 10:52:20 -070059import android.telecom.VideoProfile;
Santos Cordon92694512015-04-23 14:47:28 -070060
Ihab Awadaa383cc2015-03-22 22:12:28 -070061import com.android.internal.telecom.IInCallAdapter;
Brad Ebinger7ade5e22016-04-05 18:43:50 -070062import com.android.server.telecom.AsyncRingtonePlayer;
Hall Liub3979ee2015-11-11 16:21:25 -080063import com.android.server.telecom.BluetoothPhoneServiceImpl;
Abhijith Shastryb7853c02016-02-03 12:56:59 -080064import com.android.server.telecom.CallAudioManager;
Hall Liu609992b2016-08-31 15:48:51 -070065import com.android.server.telecom.CallAudioRouteStateMachine;
Tyler Gunnae694b12015-11-11 17:46:03 -080066import com.android.server.telecom.CallerInfoAsyncQueryFactory;
Brad Ebinger2c93c502015-10-28 00:23:54 +000067import com.android.server.telecom.CallsManager;
Tyler Gunnae694b12015-11-11 17:46:03 -080068import com.android.server.telecom.CallsManagerListenerBase;
69import com.android.server.telecom.ContactsAsyncHelper;
Brad Ebinger2c93c502015-10-28 00:23:54 +000070import com.android.server.telecom.HeadsetMediaButton;
71import com.android.server.telecom.HeadsetMediaButtonFactory;
72import com.android.server.telecom.InCallWakeLockController;
73import com.android.server.telecom.InCallWakeLockControllerFactory;
Tyler Gunneaaf0742016-09-15 15:36:38 -070074import com.android.server.telecom.InterruptionFilterProxy;
Brad Ebinger2c93c502015-10-28 00:23:54 +000075import com.android.server.telecom.MissedCallNotifier;
Hall Liub3979ee2015-11-11 16:21:25 -080076import com.android.server.telecom.PhoneAccountRegistrar;
Brad Ebinger6e8f3d72016-06-20 11:35:42 -070077import com.android.server.telecom.PhoneNumberUtilsAdapter;
78import com.android.server.telecom.PhoneNumberUtilsAdapterImpl;
Brad Ebinger2c93c502015-10-28 00:23:54 +000079import com.android.server.telecom.ProximitySensorManager;
80import com.android.server.telecom.ProximitySensorManagerFactory;
Hall Liu609992b2016-08-31 15:48:51 -070081import com.android.server.telecom.Runnable;
Brad Ebinger2c93c502015-10-28 00:23:54 +000082import com.android.server.telecom.TelecomSystem;
Hall Liu6d4b66d2016-04-01 16:31:13 -070083import com.android.server.telecom.Timeouts;
Hall Liu609992b2016-08-31 15:48:51 -070084import com.android.server.telecom.callfiltering.AsyncBlockCheckFilter;
Tony Mak578a4e62015-11-23 11:18:51 +000085import com.android.server.telecom.components.UserCallIntentProcessor;
Tony Maka9930942016-01-15 10:57:14 +000086import com.android.server.telecom.ui.MissedCallNotifierImpl.MissedCallNotifierImplFactory;
Ihab Awadaa383cc2015-03-22 22:12:28 -070087
Hall Liu8fb1fb72015-10-22 15:24:40 -070088import com.google.common.base.Predicate;
89
Anju Mathapatibddd51b2015-10-10 02:28:16 -070090import com.android.server.telecom.ViceNotifier;
91import com.android.server.telecom.ui.ViceNotificationImpl;
Ihab Awadaa383cc2015-03-22 22:12:28 -070092import org.mockito.ArgumentCaptor;
93import org.mockito.Mock;
Hall Liu8fb1fb72015-10-22 15:24:40 -070094import org.mockito.invocation.InvocationOnMock;
95import org.mockito.stubbing.Answer;
Ihab Awadaa383cc2015-03-22 22:12:28 -070096
Abhijith Shastryc6e42ef2016-02-19 18:26:44 -080097import java.util.ArrayList;
98import java.util.List;
Hall Liu609992b2016-08-31 15:48:51 -070099import java.util.concurrent.CountDownLatch;
100import java.util.concurrent.TimeUnit;
Abhijith Shastryc6e42ef2016-02-19 18:26:44 -0800101
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800102/**
103 * Implements mocks and functionality required to implement telecom system tests.
104 */
Ihab Awadaa383cc2015-03-22 22:12:28 -0700105public class TelecomSystemTest extends TelecomTestCase {
106
Ihab Awad32dd7c32015-05-28 10:52:20 -0700107 static final int TEST_POLL_INTERVAL = 10; // milliseconds
Ihab Awadaa383cc2015-03-22 22:12:28 -0700108 static final int TEST_TIMEOUT = 1000; // milliseconds
109
Tyler Gunnae694b12015-11-11 17:46:03 -0800110 public class HeadsetMediaButtonFactoryF implements HeadsetMediaButtonFactory {
111 @Override
112 public HeadsetMediaButton create(Context context, CallsManager callsManager,
113 TelecomSystem.SyncRoot lock) {
114 return mHeadsetMediaButton;
115 }
116 }
117
118 public class ProximitySensorManagerFactoryF implements ProximitySensorManagerFactory {
119 @Override
120 public ProximitySensorManager create(Context context, CallsManager callsManager) {
121 return mProximitySensorManager;
122 }
123 }
124
125 public class InCallWakeLockControllerFactoryF implements InCallWakeLockControllerFactory {
126 @Override
127 public InCallWakeLockController create(Context context, CallsManager callsManager) {
128 return mInCallWakeLockController;
129 }
130 }
131
132 public static class MissedCallNotifierFakeImpl extends CallsManagerListenerBase
133 implements MissedCallNotifier {
Abhijith Shastryc6e42ef2016-02-19 18:26:44 -0800134 List<com.android.server.telecom.Call> missedCallsNotified = new ArrayList<>();
135
Tyler Gunnae694b12015-11-11 17:46:03 -0800136 @Override
Tony Maka9930942016-01-15 10:57:14 +0000137 public void clearMissedCalls(UserHandle userHandle) {
Tyler Gunnae694b12015-11-11 17:46:03 -0800138
139 }
140
141 @Override
142 public void showMissedCallNotification(com.android.server.telecom.Call call) {
Abhijith Shastryc6e42ef2016-02-19 18:26:44 -0800143 missedCallsNotified.add(call);
Tyler Gunnae694b12015-11-11 17:46:03 -0800144 }
145
146 @Override
Tony Maka9930942016-01-15 10:57:14 +0000147 public void reloadFromDatabase(TelecomSystem.SyncRoot lock, CallsManager callsManager,
Tyler Gunnae694b12015-11-11 17:46:03 -0800148 ContactsAsyncHelper contactsAsyncHelper,
Tony Maka9930942016-01-15 10:57:14 +0000149 CallerInfoAsyncQueryFactory callerInfoAsyncQueryFactory, UserHandle userHandle) {
150
151 }
152
153 @Override
154 public void setCurrentUserHandle(UserHandle userHandle) {
Tyler Gunnae694b12015-11-11 17:46:03 -0800155
156 }
157 }
158
Abhijith Shastryc6e42ef2016-02-19 18:26:44 -0800159 MissedCallNotifierFakeImpl mMissedCallNotifier = new MissedCallNotifierFakeImpl();
Brad Ebinger6e8f3d72016-06-20 11:35:42 -0700160 private class EmergencyNumberUtilsAdapter extends PhoneNumberUtilsAdapterImpl {
161
162 @Override
163 public boolean isLocalEmergencyNumber(Context context, String number) {
164 return mIsEmergencyCall;
165 }
166
167 @Override
168 public boolean isPotentialLocalEmergencyNumber(Context context, String number) {
169 return mIsEmergencyCall;
170 }
171 }
172 PhoneNumberUtilsAdapter mPhoneNumberUtilsAdapter = new EmergencyNumberUtilsAdapter();
Tyler Gunneaaf0742016-09-15 15:36:38 -0700173
174 public static class MockInterruptionFilterProxy implements InterruptionFilterProxy {
175 private int mInterruptionFilter = NotificationManager.INTERRUPTION_FILTER_ALL;
176 @Override
177 public void setInterruptionFilter(int interruptionFilter) {
178 mInterruptionFilter = interruptionFilter;
179 }
180
181 @Override
182 public int getCurrentInterruptionFilter() {
183 return mInterruptionFilter;
184 }
Tyler Gunn49056662017-01-10 16:18:46 -0800185
186 @Override
187 public String getInterruptionModeInitiator() {
188 return "com.android.server.telecom";
189 }
Tyler Gunneaaf0742016-09-15 15:36:38 -0700190 }
191
Ihab Awadaa383cc2015-03-22 22:12:28 -0700192 @Mock HeadsetMediaButton mHeadsetMediaButton;
193 @Mock ProximitySensorManager mProximitySensorManager;
194 @Mock InCallWakeLockController mInCallWakeLockController;
Hall Liub3979ee2015-11-11 16:21:25 -0800195 @Mock BluetoothPhoneServiceImpl mBluetoothPhoneServiceImpl;
Brad Ebinger7ade5e22016-04-05 18:43:50 -0700196 @Mock AsyncRingtonePlayer mAsyncRingtonePlayer;
Anju Mathapatibddd51b2015-10-10 02:28:16 -0700197 @Mock ViceNotifier mViceNotifier;
Tyler Gunneaaf0742016-09-15 15:36:38 -0700198 @Mock InterruptionFilterProxy mInterruptionFilterProxy;
Ihab Awadaa383cc2015-03-22 22:12:28 -0700199
200 final ComponentName mInCallServiceComponentNameX =
201 new ComponentName(
202 "incall-service-package-X",
203 "incall-service-class-X");
204 final ComponentName mInCallServiceComponentNameY =
205 new ComponentName(
206 "incall-service-package-Y",
207 "incall-service-class-Y");
208
209 InCallServiceFixture mInCallServiceFixtureX;
210 InCallServiceFixture mInCallServiceFixtureY;
211
212 final ComponentName mConnectionServiceComponentNameA =
213 new ComponentName(
214 "connection-service-package-A",
215 "connection-service-class-A");
216 final ComponentName mConnectionServiceComponentNameB =
217 new ComponentName(
218 "connection-service-package-B",
219 "connection-service-class-B");
220
221 final PhoneAccount mPhoneAccountA0 =
222 PhoneAccount.builder(
223 new PhoneAccountHandle(
224 mConnectionServiceComponentNameA,
225 "id A 0"),
226 "Phone account service A ID 0")
227 .addSupportedUriScheme("tel")
228 .setCapabilities(
229 PhoneAccount.CAPABILITY_CALL_PROVIDER |
Hall Liu609992b2016-08-31 15:48:51 -0700230 PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION |
231 PhoneAccount.CAPABILITY_VIDEO_CALLING)
Ihab Awadaa383cc2015-03-22 22:12:28 -0700232 .build();
233 final PhoneAccount mPhoneAccountA1 =
234 PhoneAccount.builder(
235 new PhoneAccountHandle(
236 mConnectionServiceComponentNameA,
237 "id A 1"),
238 "Phone account service A ID 1")
239 .addSupportedUriScheme("tel")
240 .setCapabilities(
241 PhoneAccount.CAPABILITY_CALL_PROVIDER |
Tyler Gunneaaf0742016-09-15 15:36:38 -0700242 PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION |
243 PhoneAccount.CAPABILITY_VIDEO_CALLING)
Ihab Awadaa383cc2015-03-22 22:12:28 -0700244 .build();
245 final PhoneAccount mPhoneAccountB0 =
246 PhoneAccount.builder(
247 new PhoneAccountHandle(
Ihab Awad1b5490a2015-05-12 13:13:48 -0700248 mConnectionServiceComponentNameB,
Ihab Awadaa383cc2015-03-22 22:12:28 -0700249 "id B 0"),
250 "Phone account service B ID 0")
251 .addSupportedUriScheme("tel")
252 .setCapabilities(
253 PhoneAccount.CAPABILITY_CALL_PROVIDER |
Tyler Gunneaaf0742016-09-15 15:36:38 -0700254 PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION |
255 PhoneAccount.CAPABILITY_VIDEO_CALLING)
Ihab Awadaa383cc2015-03-22 22:12:28 -0700256 .build();
Brad Ebinger6e8f3d72016-06-20 11:35:42 -0700257 final PhoneAccount mPhoneAccountE0 =
258 PhoneAccount.builder(
259 new PhoneAccountHandle(
260 mConnectionServiceComponentNameA,
261 "id E 0"),
262 "Phone account service E ID 0")
263 .addSupportedUriScheme("tel")
264 .setCapabilities(
265 PhoneAccount.CAPABILITY_CALL_PROVIDER |
266 PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION |
Tyler Gunneaaf0742016-09-15 15:36:38 -0700267 PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS |
268 PhoneAccount.CAPABILITY_VIDEO_CALLING)
Brad Ebinger6e8f3d72016-06-20 11:35:42 -0700269 .build();
270
271 final PhoneAccount mPhoneAccountE1 =
272 PhoneAccount.builder(
273 new PhoneAccountHandle(
274 mConnectionServiceComponentNameA,
275 "id E 1"),
276 "Phone account service E ID 1")
277 .addSupportedUriScheme("tel")
278 .setCapabilities(
279 PhoneAccount.CAPABILITY_CALL_PROVIDER |
280 PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION |
Tyler Gunneaaf0742016-09-15 15:36:38 -0700281 PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS |
282 PhoneAccount.CAPABILITY_VIDEO_CALLING)
Ihab Awadaa383cc2015-03-22 22:12:28 -0700283 .build();
284
285 ConnectionServiceFixture mConnectionServiceFixtureA;
286 ConnectionServiceFixture mConnectionServiceFixtureB;
Hall Liu6d4b66d2016-04-01 16:31:13 -0700287 Timeouts.Adapter mTimeoutsAdapter;
Ihab Awadaa383cc2015-03-22 22:12:28 -0700288
Ihab Awadabcbce42015-04-07 14:04:01 -0700289 CallerInfoAsyncQueryFactoryFixture mCallerInfoAsyncQueryFactoryFixture;
290
Hall Liu8fb1fb72015-10-22 15:24:40 -0700291 IAudioService mAudioService;
292
Ihab Awadaa383cc2015-03-22 22:12:28 -0700293 TelecomSystem mTelecomSystem;
294
Hall Liuecda5542015-12-04 11:31:31 -0800295 Context mSpyContext;
296
Hall Liuf7783fb2015-11-23 18:45:48 -0800297 private int mNumOutgoingCallsMade;
298
Brad Ebinger6e8f3d72016-06-20 11:35:42 -0700299 private boolean mIsEmergencyCall;
300
Ihab Awad1b5490a2015-05-12 13:13:48 -0700301 class IdPair {
302 final String mConnectionId;
303 final String mCallId;
304
305 public IdPair(String connectionId, String callId) {
306 this.mConnectionId = connectionId;
307 this.mCallId = callId;
308 }
309 }
310
Ihab Awadaa383cc2015-03-22 22:12:28 -0700311 @Override
312 public void setUp() throws Exception {
313 super.setUp();
Hall Liuecda5542015-12-04 11:31:31 -0800314 mSpyContext = mComponentContextFixture.getTestDouble().getApplicationContext();
315 doReturn(mSpyContext).when(mSpyContext).getApplicationContext();
316
Hall Liuf7783fb2015-11-23 18:45:48 -0800317 mNumOutgoingCallsMade = 0;
Ihab Awadaa383cc2015-03-22 22:12:28 -0700318
Brad Ebinger6e8f3d72016-06-20 11:35:42 -0700319 mIsEmergencyCall = false;
320
Ihab Awadaa383cc2015-03-22 22:12:28 -0700321 // First set up information about the In-Call services in the mock Context, since
322 // Telecom will search for these as soon as it is instantiated
323 setupInCallServices();
324
325 // Next, create the TelecomSystem, our system under test
326 setupTelecomSystem();
327
328 // Finally, register the ConnectionServices with the PhoneAccountRegistrar of the
329 // now-running TelecomSystem
330 setupConnectionServices();
331 }
332
333 @Override
334 public void tearDown() throws Exception {
335 mTelecomSystem = null;
336 super.tearDown();
337 }
338
Tyler Gunn961694a2016-03-21 16:01:40 -0700339 protected ParcelableCall makeConferenceCall() throws Exception {
340 IdPair callId1 = startAndMakeActiveOutgoingCall("650-555-1212",
341 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
342
343 IdPair callId2 = startAndMakeActiveOutgoingCall("650-555-1213",
344 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
345
346 IInCallAdapter inCallAdapter = mInCallServiceFixtureX.getInCallAdapter();
347 inCallAdapter.conference(callId1.mCallId, callId2.mCallId);
348 // Wait for wacky non-deterministic behavior
349 Thread.sleep(200);
350 ParcelableCall call1 = mInCallServiceFixtureX.getCall(callId1.mCallId);
351 ParcelableCall call2 = mInCallServiceFixtureX.getCall(callId2.mCallId);
352 // Check that the two calls end up with a parent in the end
353 assertNotNull(call1.getParentCallId());
354 assertNotNull(call2.getParentCallId());
355 assertEquals(call1.getParentCallId(), call2.getParentCallId());
356
357 // Check to make sure that the parent call made it to the in-call service
358 String parentCallId = call1.getParentCallId();
359 ParcelableCall conferenceCall = mInCallServiceFixtureX.getCall(parentCallId);
360 assertEquals(2, conferenceCall.getChildCallIds().size());
361 assertTrue(conferenceCall.getChildCallIds().contains(callId1.mCallId));
362 assertTrue(conferenceCall.getChildCallIds().contains(callId2.mCallId));
363 return conferenceCall;
364 }
365
Ihab Awadaa383cc2015-03-22 22:12:28 -0700366 private void setupTelecomSystem() throws Exception {
Tyler Gunnae694b12015-11-11 17:46:03 -0800367 // Use actual implementations instead of mocking the interface out.
Ihab Awadaa383cc2015-03-22 22:12:28 -0700368 HeadsetMediaButtonFactory headsetMediaButtonFactory =
Tyler Gunnae694b12015-11-11 17:46:03 -0800369 spy(new HeadsetMediaButtonFactoryF());
Ihab Awadaa383cc2015-03-22 22:12:28 -0700370 ProximitySensorManagerFactory proximitySensorManagerFactory =
Tyler Gunnae694b12015-11-11 17:46:03 -0800371 spy(new ProximitySensorManagerFactoryF());
Ihab Awadaa383cc2015-03-22 22:12:28 -0700372 InCallWakeLockControllerFactory inCallWakeLockControllerFactory =
Tyler Gunnae694b12015-11-11 17:46:03 -0800373 spy(new InCallWakeLockControllerFactoryF());
Hall Liu8fb1fb72015-10-22 15:24:40 -0700374 mAudioService = setupAudioService();
Ihab Awadaa383cc2015-03-22 22:12:28 -0700375
Ihab Awadabcbce42015-04-07 14:04:01 -0700376 mCallerInfoAsyncQueryFactoryFixture = new CallerInfoAsyncQueryFactoryFixture();
377
Hall Liu6d4b66d2016-04-01 16:31:13 -0700378 mTimeoutsAdapter = mock(Timeouts.Adapter.class);
379 when(mTimeoutsAdapter.getCallScreeningTimeoutMillis(any(ContentResolver.class)))
Hall Liu609992b2016-08-31 15:48:51 -0700380 .thenReturn(TEST_TIMEOUT / 5L);
Hall Liu6d4b66d2016-04-01 16:31:13 -0700381
Ihab Awadaa383cc2015-03-22 22:12:28 -0700382 mTelecomSystem = new TelecomSystem(
383 mComponentContextFixture.getTestDouble(),
Tony Maka9930942016-01-15 10:57:14 +0000384 new MissedCallNotifierImplFactory() {
385 @Override
386 public MissedCallNotifier makeMissedCallNotifierImpl(Context context,
Brad Ebinger6ab66c32016-07-15 19:27:51 -0700387 PhoneAccountRegistrar phoneAccountRegistrar,
388 PhoneNumberUtilsAdapter phoneNumberUtilsAdapter) {
Tony Maka9930942016-01-15 10:57:14 +0000389 return mMissedCallNotifier;
390 }
391 },
Ihab Awadabcbce42015-04-07 14:04:01 -0700392 mCallerInfoAsyncQueryFactoryFixture.getTestDouble(),
Ihab Awadaa383cc2015-03-22 22:12:28 -0700393 headsetMediaButtonFactory,
394 proximitySensorManagerFactory,
Hall Liu8fb1fb72015-10-22 15:24:40 -0700395 inCallWakeLockControllerFactory,
396 new CallAudioManager.AudioServiceFactory() {
397 @Override
398 public IAudioService getAudioService() {
399 return mAudioService;
400 }
Hall Liub3979ee2015-11-11 16:21:25 -0800401 },
402 new BluetoothPhoneServiceImpl.BluetoothPhoneServiceImplFactory() {
403 @Override
404 public BluetoothPhoneServiceImpl makeBluetoothPhoneServiceImpl(Context context,
405 TelecomSystem.SyncRoot lock, CallsManager callsManager,
406 PhoneAccountRegistrar phoneAccountRegistrar) {
407 return mBluetoothPhoneServiceImpl;
408 }
Brad Ebinger7ade5e22016-04-05 18:43:50 -0700409 },
Hall Liu6d4b66d2016-04-01 16:31:13 -0700410 mTimeoutsAdapter,
Anju Mathapatibddd51b2015-10-10 02:28:16 -0700411 mAsyncRingtonePlayer,
Lalit Kansara1d77ec92016-12-07 01:42:37 +0530412 mViceNotifier,
Tyler Gunneaaf0742016-09-15 15:36:38 -0700413 mPhoneNumberUtilsAdapter,
414 mInterruptionFilterProxy);
Ihab Awadaa383cc2015-03-22 22:12:28 -0700415
Hall Liu1d903dd2015-10-09 15:56:44 -0700416 mComponentContextFixture.setTelecomManager(new TelecomManager(
417 mComponentContextFixture.getTestDouble(),
418 mTelecomSystem.getTelecomServiceImpl().getBinder()));
419
Ihab Awadaa383cc2015-03-22 22:12:28 -0700420 verify(headsetMediaButtonFactory).create(
421 eq(mComponentContextFixture.getTestDouble().getApplicationContext()),
Ihab Awad731369c2015-05-19 09:23:21 -0700422 any(CallsManager.class),
423 any(TelecomSystem.SyncRoot.class));
Ihab Awadaa383cc2015-03-22 22:12:28 -0700424 verify(proximitySensorManagerFactory).create(
425 eq(mComponentContextFixture.getTestDouble().getApplicationContext()),
426 any(CallsManager.class));
427 verify(inCallWakeLockControllerFactory).create(
428 eq(mComponentContextFixture.getTestDouble().getApplicationContext()),
429 any(CallsManager.class));
430 }
431
432 private void setupConnectionServices() throws Exception {
433 mConnectionServiceFixtureA = new ConnectionServiceFixture();
434 mConnectionServiceFixtureB = new ConnectionServiceFixture();
435
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800436 mComponentContextFixture.addConnectionService(mConnectionServiceComponentNameA,
Ihab Awadaa383cc2015-03-22 22:12:28 -0700437 mConnectionServiceFixtureA.getTestDouble());
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800438 mComponentContextFixture.addConnectionService(mConnectionServiceComponentNameB,
Ihab Awadaa383cc2015-03-22 22:12:28 -0700439 mConnectionServiceFixtureB.getTestDouble());
440
441 mTelecomSystem.getPhoneAccountRegistrar().registerPhoneAccount(mPhoneAccountA0);
442 mTelecomSystem.getPhoneAccountRegistrar().registerPhoneAccount(mPhoneAccountA1);
443 mTelecomSystem.getPhoneAccountRegistrar().registerPhoneAccount(mPhoneAccountB0);
Brad Ebinger6e8f3d72016-06-20 11:35:42 -0700444 mTelecomSystem.getPhoneAccountRegistrar().registerPhoneAccount(mPhoneAccountE0);
445 mTelecomSystem.getPhoneAccountRegistrar().registerPhoneAccount(mPhoneAccountE1);
Ihab Awad0a4b95f2015-05-18 10:15:38 -0700446
447 mTelecomSystem.getPhoneAccountRegistrar().setUserSelectedOutgoingPhoneAccount(
Tony Mak4a3e2fd2015-12-04 11:58:38 +0000448 mPhoneAccountA0.getAccountHandle(), Process.myUserHandle());
Ihab Awadaa383cc2015-03-22 22:12:28 -0700449 }
450
451 private void setupInCallServices() throws Exception {
452 mComponentContextFixture.putResource(
453 com.android.server.telecom.R.string.ui_default_package,
454 mInCallServiceComponentNameX.getPackageName());
455 mComponentContextFixture.putResource(
456 com.android.server.telecom.R.string.incall_default_class,
457 mInCallServiceComponentNameX.getClassName());
Brad Ebingerf4745b62015-12-08 17:57:59 -0800458 mComponentContextFixture.putBooleanResource(
459 com.android.internal.R.bool.config_voice_capable, true);
Ihab Awadaa383cc2015-03-22 22:12:28 -0700460
461 mInCallServiceFixtureX = new InCallServiceFixture();
462 mInCallServiceFixtureY = new InCallServiceFixture();
463
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800464 mComponentContextFixture.addInCallService(mInCallServiceComponentNameX,
Ihab Awadaa383cc2015-03-22 22:12:28 -0700465 mInCallServiceFixtureX.getTestDouble());
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800466 mComponentContextFixture.addInCallService(mInCallServiceComponentNameY,
Ihab Awadaa383cc2015-03-22 22:12:28 -0700467 mInCallServiceFixtureY.getTestDouble());
468 }
469
Hall Liu8fb1fb72015-10-22 15:24:40 -0700470 /**
471 * Helper method for setting up the fake audio service.
472 * Calls to the fake audio service need to toggle the return
473 * value of AudioManager#isMicrophoneMute.
474 * @return mock of IAudioService
475 */
476 private IAudioService setupAudioService() {
477 IAudioService audioService = mock(IAudioService.class);
Tyler Gunnae694b12015-11-11 17:46:03 -0800478
Hall Liu8fb1fb72015-10-22 15:24:40 -0700479 final AudioManager fakeAudioManager =
480 (AudioManager) mComponentContextFixture.getTestDouble()
481 .getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
482
483 try {
484 doAnswer(new Answer() {
485 @Override
486 public Object answer(InvocationOnMock i) {
487 Object[] args = i.getArguments();
488 doReturn(args[0]).when(fakeAudioManager).isMicrophoneMute();
489 return null;
490 }
491 }).when(audioService)
492 .setMicrophoneMute(any(Boolean.class), any(String.class), any(Integer.class));
493
494 } catch (android.os.RemoteException e) {
495 // Do nothing, leave the faked microphone state as-is
496 }
497 return audioService;
498 }
499
Brad Ebingerc301b512016-03-16 18:27:57 -0700500 protected String startOutgoingPhoneCallWithNoPhoneAccount(String number,
501 ConnectionServiceFixture connectionServiceFixture)
502 throws Exception {
503
504 return startOutgoingPhoneCallPendingCreateConnection(number, null,
505 connectionServiceFixture, Process.myUserHandle(), VideoProfile.STATE_AUDIO_ONLY);
506 }
507
508 protected IdPair outgoingCallPhoneAccountSelected(PhoneAccountHandle phoneAccountHandle,
509 int startingNumConnections, int startingNumCalls,
510 ConnectionServiceFixture connectionServiceFixture) throws Exception {
511
512 IdPair ids = outgoingCallCreateConnectionComplete(startingNumConnections, startingNumCalls,
513 phoneAccountHandle, connectionServiceFixture);
514
515 connectionServiceFixture.sendSetDialing(ids.mConnectionId);
516 assertEquals(Call.STATE_DIALING, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
517 assertEquals(Call.STATE_DIALING, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
518
519 connectionServiceFixture.sendSetVideoState(ids.mConnectionId);
520
521 connectionServiceFixture.sendSetActive(ids.mConnectionId);
522 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
523 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
524
525 return ids;
526 }
527
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800528 protected IdPair startOutgoingPhoneCall(String number, PhoneAccountHandle phoneAccountHandle,
529 ConnectionServiceFixture connectionServiceFixture, UserHandle initiatingUser)
530 throws Exception {
Brad Ebingerc301b512016-03-16 18:27:57 -0700531
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800532 return startOutgoingPhoneCall(number, phoneAccountHandle, connectionServiceFixture,
533 initiatingUser, VideoProfile.STATE_AUDIO_ONLY);
534 }
535
536 protected IdPair startOutgoingPhoneCall(String number, PhoneAccountHandle phoneAccountHandle,
537 ConnectionServiceFixture connectionServiceFixture, UserHandle initiatingUser,
538 int videoState) throws Exception {
Brad Ebingerc301b512016-03-16 18:27:57 -0700539 int startingNumConnections = connectionServiceFixture.mConnectionById.size();
540 int startingNumCalls = mInCallServiceFixtureX.mCallById.size();
541
542 startOutgoingPhoneCallPendingCreateConnection(number, phoneAccountHandle,
543 connectionServiceFixture, initiatingUser, videoState);
544
545 return outgoingCallCreateConnectionComplete(startingNumConnections, startingNumCalls,
546 phoneAccountHandle, connectionServiceFixture);
547 }
548
Brad Ebinger6e8f3d72016-06-20 11:35:42 -0700549 protected IdPair triggerEmergencyRedial(PhoneAccountHandle phoneAccountHandle,
550 ConnectionServiceFixture connectionServiceFixture, IdPair emergencyIds)
551 throws Exception {
552 int startingNumConnections = connectionServiceFixture.mConnectionById.size();
553 int startingNumCalls = mInCallServiceFixtureX.mCallById.size();
554
555 // Send the message to disconnect the Emergency call due to an error.
556 // CreateConnectionProcessor should now try the second SIM account
557 connectionServiceFixture.sendSetDisconnected(emergencyIds.mConnectionId,
558 DisconnectCause.ERROR);
559 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
560 assertEquals(Call.STATE_DIALING, mInCallServiceFixtureX.getCall(
561 emergencyIds.mCallId).getState());
562 assertEquals(Call.STATE_DIALING, mInCallServiceFixtureY.getCall(
563 emergencyIds.mCallId).getState());
564
565 return redialingCallCreateConnectionComplete(startingNumConnections, startingNumCalls,
566 phoneAccountHandle, connectionServiceFixture);
567 }
568
569 protected IdPair startOutgoingEmergencyCall(String number,
Brad Ebingerc301b512016-03-16 18:27:57 -0700570 PhoneAccountHandle phoneAccountHandle,
571 ConnectionServiceFixture connectionServiceFixture, UserHandle initiatingUser,
572 int videoState) throws Exception {
Brad Ebinger6e8f3d72016-06-20 11:35:42 -0700573 int startingNumConnections = connectionServiceFixture.mConnectionById.size();
574 int startingNumCalls = mInCallServiceFixtureX.mCallById.size();
575
576 mIsEmergencyCall = true;
577 // Call will not use the ordered broadcaster, since it is an Emergency Call
578 startOutgoingPhoneCallWaitForBroadcaster(number, phoneAccountHandle,
579 connectionServiceFixture, initiatingUser, videoState, true /*isEmergency*/);
580
581 return outgoingCallCreateConnectionComplete(startingNumConnections, startingNumCalls,
582 phoneAccountHandle, connectionServiceFixture);
583 }
584
585 protected void startOutgoingPhoneCallWaitForBroadcaster(String number,
586 PhoneAccountHandle phoneAccountHandle,
587 ConnectionServiceFixture connectionServiceFixture, UserHandle initiatingUser,
588 int videoState, boolean isEmergency) throws Exception {
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800589 reset(connectionServiceFixture.getTestDouble(), mInCallServiceFixtureX.getTestDouble(),
Ihab Awad1b5490a2015-05-12 13:13:48 -0700590 mInCallServiceFixtureY.getTestDouble());
591
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800592 assertEquals(mInCallServiceFixtureX.mCallById.size(),
Ihab Awad1b5490a2015-05-12 13:13:48 -0700593 mInCallServiceFixtureY.mCallById.size());
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800594 assertEquals((mInCallServiceFixtureX.mInCallAdapter != null),
Ihab Awad1b5490a2015-05-12 13:13:48 -0700595 (mInCallServiceFixtureY.mInCallAdapter != null));
596
Hall Liuf7783fb2015-11-23 18:45:48 -0800597 mNumOutgoingCallsMade++;
Brad Ebingerc301b512016-03-16 18:27:57 -0700598
Ihab Awad1b5490a2015-05-12 13:13:48 -0700599 boolean hasInCallAdapter = mInCallServiceFixtureX.mInCallAdapter != null;
600
Ihab Awadaa383cc2015-03-22 22:12:28 -0700601 Intent actionCallIntent = new Intent();
602 actionCallIntent.setData(Uri.parse("tel:" + number));
603 actionCallIntent.putExtra(Intent.EXTRA_PHONE_NUMBER, number);
Brad Ebinger6e8f3d72016-06-20 11:35:42 -0700604 if(isEmergency) {
605 actionCallIntent.setAction(Intent.ACTION_CALL_EMERGENCY);
606 } else {
607 actionCallIntent.setAction(Intent.ACTION_CALL);
608 }
Ihab Awadaa383cc2015-03-22 22:12:28 -0700609 if (phoneAccountHandle != null) {
610 actionCallIntent.putExtra(
611 TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
612 phoneAccountHandle);
613 }
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800614 if (videoState != VideoProfile.STATE_AUDIO_ONLY) {
615 actionCallIntent.putExtra(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, videoState);
616 }
Ihab Awadaa383cc2015-03-22 22:12:28 -0700617
Tony Mak578a4e62015-11-23 11:18:51 +0000618 final UserHandle userHandle = initiatingUser;
Brad Ebingerf4745b62015-12-08 17:57:59 -0800619 Context localAppContext = mComponentContextFixture.getTestDouble().getApplicationContext();
620 new UserCallIntentProcessor(localAppContext, userHandle).processIntent(
621 actionCallIntent, null, true /* hasCallAppOp*/);
622 // UserCallIntentProcessor's mContext.sendBroadcastAsUser(...) will call to an empty method
623 // as to not actually try to send an intent to PrimaryCallReceiver. We verify that it was
624 // called correctly in order to continue.
625 verify(localAppContext).sendBroadcastAsUser(actionCallIntent, UserHandle.SYSTEM);
Ihab Awadaa383cc2015-03-22 22:12:28 -0700626 mTelecomSystem.getCallIntentProcessor().processIntent(actionCallIntent);
627
Ihab Awad1b5490a2015-05-12 13:13:48 -0700628 if (!hasInCallAdapter) {
629 verify(mInCallServiceFixtureX.getTestDouble())
630 .setInCallAdapter(
631 any(IInCallAdapter.class));
632 verify(mInCallServiceFixtureY.getTestDouble())
633 .setInCallAdapter(
634 any(IInCallAdapter.class));
635 }
Brad Ebinger6e8f3d72016-06-20 11:35:42 -0700636 }
637
638 protected String startOutgoingPhoneCallPendingCreateConnection(String number,
639 PhoneAccountHandle phoneAccountHandle,
640 ConnectionServiceFixture connectionServiceFixture, UserHandle initiatingUser,
641 int videoState) throws Exception {
642 startOutgoingPhoneCallWaitForBroadcaster(number,phoneAccountHandle,
643 connectionServiceFixture, initiatingUser, videoState, false /*isEmergency*/);
Ihab Awad1b5490a2015-05-12 13:13:48 -0700644
Ihab Awadaa383cc2015-03-22 22:12:28 -0700645 ArgumentCaptor<Intent> newOutgoingCallIntent =
646 ArgumentCaptor.forClass(Intent.class);
647 ArgumentCaptor<BroadcastReceiver> newOutgoingCallReceiver =
648 ArgumentCaptor.forClass(BroadcastReceiver.class);
649
Hall Liuf7783fb2015-11-23 18:45:48 -0800650 verify(mComponentContextFixture.getTestDouble().getApplicationContext(),
651 times(mNumOutgoingCallsMade))
Ihab Awadaa383cc2015-03-22 22:12:28 -0700652 .sendOrderedBroadcastAsUser(
653 newOutgoingCallIntent.capture(),
654 any(UserHandle.class),
655 anyString(),
Ihab Awad0a4b95f2015-05-18 10:15:38 -0700656 anyInt(),
Ihab Awadaa383cc2015-03-22 22:12:28 -0700657 newOutgoingCallReceiver.capture(),
658 any(Handler.class),
659 anyInt(),
660 anyString(),
661 any(Bundle.class));
662
Ihab Awadaa383cc2015-03-22 22:12:28 -0700663 // Pass on the new outgoing call Intent
664 // Set a dummy PendingResult so the BroadcastReceiver agrees to accept onReceive()
665 newOutgoingCallReceiver.getValue().setPendingResult(
Rekha Kumard240fe82015-04-01 21:45:57 -0700666 new BroadcastReceiver.PendingResult(0, "", null, 0, true, false, null, 0, 0));
Ihab Awadaa383cc2015-03-22 22:12:28 -0700667 newOutgoingCallReceiver.getValue().setResultData(
668 newOutgoingCallIntent.getValue().getStringExtra(Intent.EXTRA_PHONE_NUMBER));
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800669 newOutgoingCallReceiver.getValue().onReceive(mComponentContextFixture.getTestDouble(),
Ihab Awadaa383cc2015-03-22 22:12:28 -0700670 newOutgoingCallIntent.getValue());
671
Brad Ebingerc301b512016-03-16 18:27:57 -0700672 return mInCallServiceFixtureX.mLatestCallId;
673 }
674
Brad Ebinger6e8f3d72016-06-20 11:35:42 -0700675 // When Telecom is redialing due to an error, we need to make sure the number of connections
676 // increase, but not the number of Calls in the InCallService.
677 protected IdPair redialingCallCreateConnectionComplete(int startingNumConnections,
678 int startingNumCalls, PhoneAccountHandle phoneAccountHandle,
679 ConnectionServiceFixture connectionServiceFixture) throws Exception {
680
681 assertEquals(startingNumConnections + 1, connectionServiceFixture.mConnectionById.size());
682
683 verify(connectionServiceFixture.getTestDouble())
684 .createConnection(eq(phoneAccountHandle), anyString(), any(ConnectionRequest.class),
685 eq(false)/*isIncoming*/, anyBoolean());
686 // Wait for handleCreateConnectionComplete
687 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
688
689 // Make sure the number of registered InCallService Calls stays the same.
690 assertEquals(startingNumCalls, mInCallServiceFixtureX.mCallById.size());
691 assertEquals(startingNumCalls, mInCallServiceFixtureY.mCallById.size());
692
693 assertEquals(mInCallServiceFixtureX.mLatestCallId, mInCallServiceFixtureY.mLatestCallId);
694
695 return new IdPair(connectionServiceFixture.mLatestConnectionId,
696 mInCallServiceFixtureX.mLatestCallId);
697 }
698
Brad Ebingerc301b512016-03-16 18:27:57 -0700699 protected IdPair outgoingCallCreateConnectionComplete(int startingNumConnections,
700 int startingNumCalls, PhoneAccountHandle phoneAccountHandle,
701 ConnectionServiceFixture connectionServiceFixture) throws Exception {
702
Ihab Awad1b5490a2015-05-12 13:13:48 -0700703 assertEquals(startingNumConnections + 1, connectionServiceFixture.mConnectionById.size());
704
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800705 verify(connectionServiceFixture.getTestDouble())
706 .createConnection(eq(phoneAccountHandle), anyString(), any(ConnectionRequest.class),
Brad Ebinger84771f82016-05-18 16:57:30 -0700707 eq(false)/*isIncoming*/, anyBoolean());
708 // Wait for handleCreateConnectionComplete
709 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
Hall Liub3ce5102016-07-14 12:53:08 -0700710 // Wait for the callback in ConnectionService#onAdapterAttached to execute.
711 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
Ihab Awadaa383cc2015-03-22 22:12:28 -0700712
Ihab Awad1b5490a2015-05-12 13:13:48 -0700713 assertEquals(startingNumCalls + 1, mInCallServiceFixtureX.mCallById.size());
714 assertEquals(startingNumCalls + 1, mInCallServiceFixtureY.mCallById.size());
Ihab Awadaa383cc2015-03-22 22:12:28 -0700715
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800716 assertEquals(mInCallServiceFixtureX.mLatestCallId, mInCallServiceFixtureY.mLatestCallId);
Ihab Awad1b5490a2015-05-12 13:13:48 -0700717
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800718 return new IdPair(connectionServiceFixture.mLatestConnectionId,
Ihab Awad1b5490a2015-05-12 13:13:48 -0700719 mInCallServiceFixtureX.mLatestCallId);
Ihab Awadaa383cc2015-03-22 22:12:28 -0700720 }
721
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800722 protected IdPair startIncomingPhoneCall(
Ihab Awadaa383cc2015-03-22 22:12:28 -0700723 String number,
724 PhoneAccountHandle phoneAccountHandle,
Ihab Awad32dd7c32015-05-28 10:52:20 -0700725 final ConnectionServiceFixture connectionServiceFixture) throws Exception {
Tyler Gunn42ef8082015-11-24 15:34:34 -0800726 return startIncomingPhoneCall(number, phoneAccountHandle, VideoProfile.STATE_AUDIO_ONLY,
727 connectionServiceFixture);
728 }
729
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800730 protected IdPair startIncomingPhoneCall(
Tyler Gunn42ef8082015-11-24 15:34:34 -0800731 String number,
732 PhoneAccountHandle phoneAccountHandle,
733 int videoState,
734 final ConnectionServiceFixture connectionServiceFixture) throws Exception {
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800735 reset(connectionServiceFixture.getTestDouble(), mInCallServiceFixtureX.getTestDouble(),
Ihab Awad1b5490a2015-05-12 13:13:48 -0700736 mInCallServiceFixtureY.getTestDouble());
737
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800738 assertEquals(mInCallServiceFixtureX.mCallById.size(),
Ihab Awad1b5490a2015-05-12 13:13:48 -0700739 mInCallServiceFixtureY.mCallById.size());
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800740 assertEquals((mInCallServiceFixtureX.mInCallAdapter != null),
Ihab Awad1b5490a2015-05-12 13:13:48 -0700741 (mInCallServiceFixtureY.mInCallAdapter != null));
Ihab Awad32dd7c32015-05-28 10:52:20 -0700742 final int startingNumConnections = connectionServiceFixture.mConnectionById.size();
743 final int startingNumCalls = mInCallServiceFixtureX.mCallById.size();
Ihab Awad1b5490a2015-05-12 13:13:48 -0700744 boolean hasInCallAdapter = mInCallServiceFixtureX.mInCallAdapter != null;
Abhijith Shastryb7853c02016-02-03 12:56:59 -0800745 connectionServiceFixture.mConnectionServiceDelegate.mVideoState = videoState;
Ihab Awad1b5490a2015-05-12 13:13:48 -0700746
Ihab Awadaa383cc2015-03-22 22:12:28 -0700747 Bundle extras = new Bundle();
748 extras.putParcelable(
Yorke Lee69fa8972015-06-08 11:25:32 -0700749 TelecomManager.EXTRA_INCOMING_CALL_ADDRESS,
Ihab Awadaa383cc2015-03-22 22:12:28 -0700750 Uri.fromParts(PhoneAccount.SCHEME_TEL, number, null));
751 mTelecomSystem.getTelecomServiceImpl().getBinder()
752 .addNewIncomingCall(phoneAccountHandle, extras);
753
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800754 verify(connectionServiceFixture.getTestDouble())
755 .createConnection(any(PhoneAccountHandle.class), anyString(),
756 any(ConnectionRequest.class), eq(true), eq(false));
Ihab Awadaa383cc2015-03-22 22:12:28 -0700757
Abhijith Shastryb7853c02016-02-03 12:56:59 -0800758 for (CallerInfoAsyncQueryFactoryFixture.Request request :
759 mCallerInfoAsyncQueryFactoryFixture.mRequests) {
760 request.reply();
761 }
Ihab Awadaa383cc2015-03-22 22:12:28 -0700762
Abhijith Shastryc6e42ef2016-02-19 18:26:44 -0800763 IContentProvider blockedNumberProvider =
764 mSpyContext.getContentResolver().acquireProvider(BlockedNumberContract.AUTHORITY);
765 verify(blockedNumberProvider, timeout(TEST_TIMEOUT)).call(
766 anyString(),
767 eq(BlockedNumberContract.SystemContract.METHOD_SHOULD_SYSTEM_BLOCK_NUMBER),
768 eq(number),
769 isNull(Bundle.class));
770
Ihab Awadaa383cc2015-03-22 22:12:28 -0700771 // For the case of incoming calls, Telecom connecting the InCall services and adding the
772 // Call is triggered by the async completion of the CallerInfoAsyncQuery. Once the Call
773 // is added, future interactions as triggered by the ConnectionService, through the various
774 // test fixtures, will be synchronous.
775
Ihab Awad1b5490a2015-05-12 13:13:48 -0700776 if (!hasInCallAdapter) {
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800777 verify(mInCallServiceFixtureX.getTestDouble(), timeout(TEST_TIMEOUT))
778 .setInCallAdapter(any(IInCallAdapter.class));
779 verify(mInCallServiceFixtureY.getTestDouble(), timeout(TEST_TIMEOUT))
780 .setInCallAdapter(any(IInCallAdapter.class));
Ihab Awad1b5490a2015-05-12 13:13:48 -0700781 }
782
783 // Give the InCallService time to respond
Ihab Awadaa383cc2015-03-22 22:12:28 -0700784
Ihab Awad32dd7c32015-05-28 10:52:20 -0700785 assertTrueWithTimeout(new Predicate<Void>() {
786 @Override
787 public boolean apply(Void v) {
788 return mInCallServiceFixtureX.mInCallAdapter != null;
789 }
790 });
791
792 assertTrueWithTimeout(new Predicate<Void>() {
793 @Override
794 public boolean apply(Void v) {
795 return mInCallServiceFixtureY.mInCallAdapter != null;
796 }
797 });
Ihab Awadaa383cc2015-03-22 22:12:28 -0700798
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800799 verify(mInCallServiceFixtureX.getTestDouble(), timeout(TEST_TIMEOUT))
800 .addCall(any(ParcelableCall.class));
801 verify(mInCallServiceFixtureY.getTestDouble(), timeout(TEST_TIMEOUT))
802 .addCall(any(ParcelableCall.class));
Ihab Awadaa383cc2015-03-22 22:12:28 -0700803
Ihab Awad1b5490a2015-05-12 13:13:48 -0700804 // Give the InCallService time to respond
Ihab Awad1b5490a2015-05-12 13:13:48 -0700805
Ihab Awad32dd7c32015-05-28 10:52:20 -0700806 assertTrueWithTimeout(new Predicate<Void>() {
807 @Override
808 public boolean apply(Void v) {
809 return startingNumConnections + 1 ==
810 connectionServiceFixture.mConnectionById.size();
811 }
812 });
813 assertTrueWithTimeout(new Predicate<Void>() {
814 @Override
815 public boolean apply(Void v) {
816 return startingNumCalls + 1 == mInCallServiceFixtureX.mCallById.size();
817 }
818 });
819 assertTrueWithTimeout(new Predicate<Void>() {
820 @Override
821 public boolean apply(Void v) {
822 return startingNumCalls + 1 == mInCallServiceFixtureY.mCallById.size();
823 }
824 });
Ihab Awad1b5490a2015-05-12 13:13:48 -0700825
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800826 assertEquals(mInCallServiceFixtureX.mLatestCallId, mInCallServiceFixtureY.mLatestCallId);
Ihab Awad1b5490a2015-05-12 13:13:48 -0700827
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800828 return new IdPair(connectionServiceFixture.mLatestConnectionId,
Ihab Awad1b5490a2015-05-12 13:13:48 -0700829 mInCallServiceFixtureX.mLatestCallId);
Ihab Awadaa383cc2015-03-22 22:12:28 -0700830 }
831
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800832 protected IdPair startAndMakeActiveOutgoingCall(
833 String number,
834 PhoneAccountHandle phoneAccountHandle,
835 ConnectionServiceFixture connectionServiceFixture) throws Exception {
836 return startAndMakeActiveOutgoingCall(number, phoneAccountHandle, connectionServiceFixture,
837 VideoProfile.STATE_AUDIO_ONLY);
Ihab Awadabcbce42015-04-07 14:04:01 -0700838 }
839
Ihab Awadaa383cc2015-03-22 22:12:28 -0700840 // A simple outgoing call, verifying that the appropriate connection service is contacted,
841 // the proper lifecycle is followed, and both In-Call Services are updated correctly.
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800842 protected IdPair startAndMakeActiveOutgoingCall(
Ihab Awad1b5490a2015-05-12 13:13:48 -0700843 String number,
844 PhoneAccountHandle phoneAccountHandle,
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800845 ConnectionServiceFixture connectionServiceFixture, int videoState) throws Exception {
Tony Mak578a4e62015-11-23 11:18:51 +0000846 IdPair ids = startOutgoingPhoneCall(number, phoneAccountHandle, connectionServiceFixture,
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800847 Process.myUserHandle(), videoState);
Ihab Awad1b5490a2015-05-12 13:13:48 -0700848
849 connectionServiceFixture.sendSetDialing(ids.mConnectionId);
Ihab Awad1b5490a2015-05-12 13:13:48 -0700850 assertEquals(Call.STATE_DIALING, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
851 assertEquals(Call.STATE_DIALING, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
852
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800853 connectionServiceFixture.sendSetVideoState(ids.mConnectionId);
854
Ihab Awad1b5490a2015-05-12 13:13:48 -0700855 connectionServiceFixture.sendSetActive(ids.mConnectionId);
856 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
857 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
858
859 return ids;
860 }
861
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800862 protected IdPair startAndMakeActiveIncomingCall(
Ihab Awad1b5490a2015-05-12 13:13:48 -0700863 String number,
864 PhoneAccountHandle phoneAccountHandle,
865 ConnectionServiceFixture connectionServiceFixture) throws Exception {
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800866 return startAndMakeActiveIncomingCall(number, phoneAccountHandle, connectionServiceFixture,
867 VideoProfile.STATE_AUDIO_ONLY);
868 }
869
870 // A simple incoming call, similar in scope to the previous test
871 protected IdPair startAndMakeActiveIncomingCall(
872 String number,
873 PhoneAccountHandle phoneAccountHandle,
874 ConnectionServiceFixture connectionServiceFixture,
875 int videoState) throws Exception {
Ihab Awad1b5490a2015-05-12 13:13:48 -0700876 IdPair ids = startIncomingPhoneCall(number, phoneAccountHandle, connectionServiceFixture);
877
878 assertEquals(Call.STATE_RINGING, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
879 assertEquals(Call.STATE_RINGING, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
880
Ihab Awad32dd7c32015-05-28 10:52:20 -0700881 mInCallServiceFixtureX.mInCallAdapter
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800882 .answerCall(ids.mCallId, videoState);
Ihab Awad32dd7c32015-05-28 10:52:20 -0700883
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800884 if (!VideoProfile.isVideo(videoState)) {
885 verify(connectionServiceFixture.getTestDouble())
886 .answer(ids.mConnectionId);
887 } else {
888 verify(connectionServiceFixture.getTestDouble())
889 .answerVideo(ids.mConnectionId, videoState);
890 }
Ihab Awad32dd7c32015-05-28 10:52:20 -0700891
Ihab Awad1b5490a2015-05-12 13:13:48 -0700892 connectionServiceFixture.sendSetActive(ids.mConnectionId);
893 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
894 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
895
896 return ids;
897 }
898
Brad Ebinger6e8f3d72016-06-20 11:35:42 -0700899 protected IdPair startAndMakeDialingEmergencyCall(
900 String number,
901 PhoneAccountHandle phoneAccountHandle,
902 ConnectionServiceFixture connectionServiceFixture) throws Exception {
903 IdPair ids = startOutgoingEmergencyCall(number, phoneAccountHandle,
904 connectionServiceFixture, Process.myUserHandle(), VideoProfile.STATE_AUDIO_ONLY);
905
906 connectionServiceFixture.sendSetDialing(ids.mConnectionId);
907 assertEquals(Call.STATE_DIALING, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
908 assertEquals(Call.STATE_DIALING, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
909
910 return ids;
911 }
912
Ihab Awad32dd7c32015-05-28 10:52:20 -0700913 protected static void assertTrueWithTimeout(Predicate<Void> predicate) {
914 int elapsed = 0;
915 while (elapsed < TEST_TIMEOUT) {
916 if (predicate.apply(null)) {
917 return;
918 } else {
919 try {
920 Thread.sleep(TEST_POLL_INTERVAL);
921 elapsed += TEST_POLL_INTERVAL;
922 } catch (InterruptedException e) {
923 fail(e.toString());
924 }
925 }
Ihab Awad1b5490a2015-05-12 13:13:48 -0700926 }
Ihab Awad32dd7c32015-05-28 10:52:20 -0700927 fail("Timeout in assertTrueWithTimeout");
Ihab Awad1b5490a2015-05-12 13:13:48 -0700928 }
Ihab Awadaa383cc2015-03-22 22:12:28 -0700929}