blob: f36904980ca89495e4aa00958a3cbd136cf2e55d [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
Hall Liu74bb6352017-12-27 18:23:28 -080020import static org.junit.Assert.assertEquals;
21import static org.junit.Assert.assertNotNull;
22import static org.junit.Assert.assertTrue;
23import static org.junit.Assert.fail;
Brad Ebingerd0fe76e2017-03-20 13:17:15 -070024import static org.mockito.ArgumentMatchers.nullable;
Santos Cordon92694512015-04-23 14:47:28 -070025import static org.mockito.Matchers.any;
26import static org.mockito.Matchers.anyBoolean;
27import static org.mockito.Matchers.anyInt;
28import static org.mockito.Matchers.anyString;
29import static org.mockito.Matchers.eq;
Abhijith Shastryc6e42ef2016-02-19 18:26:44 -080030import static org.mockito.Matchers.isNull;
Hall Liu8fb1fb72015-10-22 15:24:40 -070031import static org.mockito.Mockito.doAnswer;
Tyler Gunn93dc55f2017-04-18 13:23:18 -070032import static org.mockito.Mockito.doNothing;
Hall Liu8fb1fb72015-10-22 15:24:40 -070033import static org.mockito.Mockito.doReturn;
Santos Cordon92694512015-04-23 14:47:28 -070034import static org.mockito.Mockito.mock;
Ihab Awad1b5490a2015-05-12 13:13:48 -070035import static org.mockito.Mockito.reset;
Tyler Gunnae694b12015-11-11 17:46:03 -080036import static org.mockito.Mockito.spy;
Santos Cordon92694512015-04-23 14:47:28 -070037import static org.mockito.Mockito.timeout;
Hall Liuf7783fb2015-11-23 18:45:48 -080038import static org.mockito.Mockito.times;
Santos Cordon92694512015-04-23 14:47:28 -070039import static org.mockito.Mockito.verify;
Hall Liu6d4b66d2016-04-01 16:31:13 -070040import static org.mockito.Mockito.when;
Santos Cordon92694512015-04-23 14:47:28 -070041
42import android.content.BroadcastReceiver;
43import android.content.ComponentName;
Hall Liu6d4b66d2016-04-01 16:31:13 -070044import android.content.ContentResolver;
Santos Cordon92694512015-04-23 14:47:28 -070045import android.content.Context;
Abhijith Shastryc6e42ef2016-02-19 18:26:44 -080046import android.content.IContentProvider;
Santos Cordon92694512015-04-23 14:47:28 -070047import android.content.Intent;
Ihab Awadb60f0062015-05-26 16:20:32 -070048import android.media.AudioManager;
Hall Liu8fb1fb72015-10-22 15:24:40 -070049import android.media.IAudioService;
Brad Ebinger7bba1112017-06-08 13:57:28 -070050import android.media.ToneGenerator;
Santos Cordon92694512015-04-23 14:47:28 -070051import android.net.Uri;
52import android.os.Bundle;
53import android.os.Handler;
Brad Ebinger84771f82016-05-18 16:57:30 -070054import android.os.Looper;
Tony Mak578a4e62015-11-23 11:18:51 +000055import android.os.Process;
Santos Cordon92694512015-04-23 14:47:28 -070056import android.os.UserHandle;
Abhijith Shastryc6e42ef2016-02-19 18:26:44 -080057import android.provider.BlockedNumberContract;
Ihab Awad0a4b95f2015-05-18 10:15:38 -070058import android.telecom.Call;
Santos Cordon92694512015-04-23 14:47:28 -070059import android.telecom.ConnectionRequest;
Brad Ebinger6e8f3d72016-06-20 11:35:42 -070060import android.telecom.DisconnectCause;
Santos Cordon92694512015-04-23 14:47:28 -070061import android.telecom.ParcelableCall;
62import android.telecom.PhoneAccount;
63import android.telecom.PhoneAccountHandle;
64import android.telecom.TelecomManager;
Ihab Awad32dd7c32015-05-28 10:52:20 -070065import android.telecom.VideoProfile;
Santos Cordon92694512015-04-23 14:47:28 -070066
Ihab Awadaa383cc2015-03-22 22:12:28 -070067import com.android.internal.telecom.IInCallAdapter;
Brad Ebinger7ade5e22016-04-05 18:43:50 -070068import com.android.server.telecom.AsyncRingtonePlayer;
Hall Liub3979ee2015-11-11 16:21:25 -080069import com.android.server.telecom.BluetoothPhoneServiceImpl;
Abhijith Shastryb7853c02016-02-03 12:56:59 -080070import com.android.server.telecom.CallAudioManager;
Hall Liu3037ac62016-09-22 14:40:03 -070071import com.android.server.telecom.CallerInfoLookupHelper;
Brad Ebinger2c93c502015-10-28 00:23:54 +000072import com.android.server.telecom.CallsManager;
Tyler Gunnae694b12015-11-11 17:46:03 -080073import com.android.server.telecom.CallsManagerListenerBase;
Tyler Gunn8bb2b012017-08-04 09:28:59 -070074import com.android.server.telecom.ClockProxy;
Hall Liu7c928322016-12-06 18:15:39 -080075import com.android.server.telecom.DefaultDialerCache;
Brad Ebinger2c93c502015-10-28 00:23:54 +000076import com.android.server.telecom.HeadsetMediaButton;
77import com.android.server.telecom.HeadsetMediaButtonFactory;
78import com.android.server.telecom.InCallWakeLockController;
79import com.android.server.telecom.InCallWakeLockControllerFactory;
Brad Ebinger2c93c502015-10-28 00:23:54 +000080import com.android.server.telecom.MissedCallNotifier;
Hall Liub3979ee2015-11-11 16:21:25 -080081import com.android.server.telecom.PhoneAccountRegistrar;
Brad Ebinger6e8f3d72016-06-20 11:35:42 -070082import com.android.server.telecom.PhoneNumberUtilsAdapter;
83import com.android.server.telecom.PhoneNumberUtilsAdapterImpl;
Brad Ebinger2c93c502015-10-28 00:23:54 +000084import com.android.server.telecom.ProximitySensorManager;
85import com.android.server.telecom.ProximitySensorManagerFactory;
86import com.android.server.telecom.TelecomSystem;
Hall Liu6d4b66d2016-04-01 16:31:13 -070087import com.android.server.telecom.Timeouts;
Tony Mak578a4e62015-11-23 11:18:51 +000088import com.android.server.telecom.components.UserCallIntentProcessor;
Tyler Gunn2b17f232017-03-08 08:51:00 -080089import com.android.server.telecom.ui.IncomingCallNotifier;
Tony Maka9930942016-01-15 10:57:14 +000090import com.android.server.telecom.ui.MissedCallNotifierImpl.MissedCallNotifierImplFactory;
Ihab Awadaa383cc2015-03-22 22:12:28 -070091
Hall Liu8fb1fb72015-10-22 15:24:40 -070092import com.google.common.base.Predicate;
93
Ihab Awadaa383cc2015-03-22 22:12:28 -070094import org.mockito.ArgumentCaptor;
95import org.mockito.Mock;
Hall Liu8fb1fb72015-10-22 15:24:40 -070096import org.mockito.invocation.InvocationOnMock;
97import org.mockito.stubbing.Answer;
Ihab Awadaa383cc2015-03-22 22:12:28 -070098
Abhijith Shastryc6e42ef2016-02-19 18:26:44 -080099import java.util.ArrayList;
100import java.util.List;
Hall Liu609992b2016-08-31 15:48:51 -0700101import java.util.concurrent.CountDownLatch;
102import java.util.concurrent.TimeUnit;
Abhijith Shastryc6e42ef2016-02-19 18:26:44 -0800103
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800104/**
105 * Implements mocks and functionality required to implement telecom system tests.
106 */
Ihab Awadaa383cc2015-03-22 22:12:28 -0700107public class TelecomSystemTest extends TelecomTestCase {
108
Ihab Awad32dd7c32015-05-28 10:52:20 -0700109 static final int TEST_POLL_INTERVAL = 10; // milliseconds
Ihab Awadaa383cc2015-03-22 22:12:28 -0700110 static final int TEST_TIMEOUT = 1000; // milliseconds
111
Tyler Gunn8bb2b012017-08-04 09:28:59 -0700112 // Purposely keep the connect time (which is wall clock) and elapsed time (which is time since
113 // boot) different to test that wall clock time operations and elapsed time operations perform
114 // as they individually should.
115 static final long TEST_CREATE_TIME = 100;
116 static final long TEST_CREATE_ELAPSED_TIME = 200;
117 static final long TEST_CONNECT_TIME = 1000;
118 static final long TEST_CONNECT_ELAPSED_TIME = 2000;
119 static final long TEST_DISCONNECT_TIME = 8000;
120 static final long TEST_DISCONNECT_ELAPSED_TIME = 4000;
121
Tyler Gunnae694b12015-11-11 17:46:03 -0800122 public class HeadsetMediaButtonFactoryF implements HeadsetMediaButtonFactory {
123 @Override
124 public HeadsetMediaButton create(Context context, CallsManager callsManager,
125 TelecomSystem.SyncRoot lock) {
126 return mHeadsetMediaButton;
127 }
128 }
129
130 public class ProximitySensorManagerFactoryF implements ProximitySensorManagerFactory {
131 @Override
132 public ProximitySensorManager create(Context context, CallsManager callsManager) {
133 return mProximitySensorManager;
134 }
135 }
136
137 public class InCallWakeLockControllerFactoryF implements InCallWakeLockControllerFactory {
138 @Override
139 public InCallWakeLockController create(Context context, CallsManager callsManager) {
140 return mInCallWakeLockController;
141 }
142 }
143
144 public static class MissedCallNotifierFakeImpl extends CallsManagerListenerBase
145 implements MissedCallNotifier {
Hall Liu3037ac62016-09-22 14:40:03 -0700146 List<CallInfo> missedCallsNotified = new ArrayList<>();
Abhijith Shastryc6e42ef2016-02-19 18:26:44 -0800147
Tyler Gunnae694b12015-11-11 17:46:03 -0800148 @Override
Tony Maka9930942016-01-15 10:57:14 +0000149 public void clearMissedCalls(UserHandle userHandle) {
Tyler Gunnae694b12015-11-11 17:46:03 -0800150
151 }
152
153 @Override
Hall Liu3037ac62016-09-22 14:40:03 -0700154 public void showMissedCallNotification(CallInfo call) {
Abhijith Shastryc6e42ef2016-02-19 18:26:44 -0800155 missedCallsNotified.add(call);
Tyler Gunnae694b12015-11-11 17:46:03 -0800156 }
157
158 @Override
Hall Liu3037ac62016-09-22 14:40:03 -0700159 public void reloadAfterBootComplete(CallerInfoLookupHelper callerInfoLookupHelper,
160 CallInfoFactory callInfoFactory) { }
Tony Maka9930942016-01-15 10:57:14 +0000161
Hall Liu3037ac62016-09-22 14:40:03 -0700162 @Override
163 public void reloadFromDatabase(CallerInfoLookupHelper callerInfoLookupHelper,
164 CallInfoFactory callInfoFactory, UserHandle userHandle) { }
Tony Maka9930942016-01-15 10:57:14 +0000165
166 @Override
167 public void setCurrentUserHandle(UserHandle userHandle) {
Tyler Gunnae694b12015-11-11 17:46:03 -0800168
169 }
170 }
171
Abhijith Shastryc6e42ef2016-02-19 18:26:44 -0800172 MissedCallNotifierFakeImpl mMissedCallNotifier = new MissedCallNotifierFakeImpl();
Brad Ebinger6e8f3d72016-06-20 11:35:42 -0700173 private class EmergencyNumberUtilsAdapter extends PhoneNumberUtilsAdapterImpl {
174
175 @Override
176 public boolean isLocalEmergencyNumber(Context context, String number) {
177 return mIsEmergencyCall;
178 }
179
180 @Override
181 public boolean isPotentialLocalEmergencyNumber(Context context, String number) {
182 return mIsEmergencyCall;
183 }
184 }
Brad Ebinger7bba1112017-06-08 13:57:28 -0700185
186 private class IncomingCallAddedListener extends CallsManagerListenerBase {
187
188 private final CountDownLatch mCountDownLatch;
189
190 public IncomingCallAddedListener(CountDownLatch latch) {
191 mCountDownLatch = latch;
192 }
193
194 @Override
195 public void onCallAdded(com.android.server.telecom.Call call) {
196 mCountDownLatch.countDown();
197 }
198 }
199
Brad Ebinger6e8f3d72016-06-20 11:35:42 -0700200 PhoneNumberUtilsAdapter mPhoneNumberUtilsAdapter = new EmergencyNumberUtilsAdapter();
Tyler Gunneaaf0742016-09-15 15:36:38 -0700201
Ihab Awadaa383cc2015-03-22 22:12:28 -0700202 @Mock HeadsetMediaButton mHeadsetMediaButton;
203 @Mock ProximitySensorManager mProximitySensorManager;
204 @Mock InCallWakeLockController mInCallWakeLockController;
Hall Liub3979ee2015-11-11 16:21:25 -0800205 @Mock BluetoothPhoneServiceImpl mBluetoothPhoneServiceImpl;
Brad Ebinger7ade5e22016-04-05 18:43:50 -0700206 @Mock AsyncRingtonePlayer mAsyncRingtonePlayer;
Tyler Gunn2b17f232017-03-08 08:51:00 -0800207 @Mock IncomingCallNotifier mIncomingCallNotifier;
Tyler Gunn8bb2b012017-08-04 09:28:59 -0700208 @Mock ClockProxy mClockProxy;
Ihab Awadaa383cc2015-03-22 22:12:28 -0700209
210 final ComponentName mInCallServiceComponentNameX =
211 new ComponentName(
212 "incall-service-package-X",
213 "incall-service-class-X");
214 final ComponentName mInCallServiceComponentNameY =
215 new ComponentName(
216 "incall-service-package-Y",
217 "incall-service-class-Y");
218
219 InCallServiceFixture mInCallServiceFixtureX;
220 InCallServiceFixture mInCallServiceFixtureY;
221
222 final ComponentName mConnectionServiceComponentNameA =
223 new ComponentName(
224 "connection-service-package-A",
225 "connection-service-class-A");
226 final ComponentName mConnectionServiceComponentNameB =
227 new ComponentName(
228 "connection-service-package-B",
229 "connection-service-class-B");
230
231 final PhoneAccount mPhoneAccountA0 =
232 PhoneAccount.builder(
233 new PhoneAccountHandle(
234 mConnectionServiceComponentNameA,
235 "id A 0"),
236 "Phone account service A ID 0")
237 .addSupportedUriScheme("tel")
238 .setCapabilities(
239 PhoneAccount.CAPABILITY_CALL_PROVIDER |
Hall Liu609992b2016-08-31 15:48:51 -0700240 PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION |
241 PhoneAccount.CAPABILITY_VIDEO_CALLING)
Ihab Awadaa383cc2015-03-22 22:12:28 -0700242 .build();
243 final PhoneAccount mPhoneAccountA1 =
244 PhoneAccount.builder(
245 new PhoneAccountHandle(
246 mConnectionServiceComponentNameA,
247 "id A 1"),
248 "Phone account service A ID 1")
249 .addSupportedUriScheme("tel")
250 .setCapabilities(
251 PhoneAccount.CAPABILITY_CALL_PROVIDER |
Tyler Gunneaaf0742016-09-15 15:36:38 -0700252 PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION |
253 PhoneAccount.CAPABILITY_VIDEO_CALLING)
Ihab Awadaa383cc2015-03-22 22:12:28 -0700254 .build();
Tyler Gunnddec5892016-09-28 10:26:13 -0700255 final PhoneAccount mPhoneAccountA2 =
256 PhoneAccount.builder(
257 new PhoneAccountHandle(
258 mConnectionServiceComponentNameA,
259 "id A 2"),
260 "Phone account service A ID 2")
261 .addSupportedUriScheme("tel")
262 .setCapabilities(
263 PhoneAccount.CAPABILITY_CALL_PROVIDER |
264 PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)
265 .build();
Tyler Gunn153aafa2017-10-06 10:08:18 -0700266 final PhoneAccount mPhoneAccountSelfManaged =
267 PhoneAccount.builder(
268 new PhoneAccountHandle(
269 mConnectionServiceComponentNameA,
270 "id SM"),
271 "Phone account service A SM")
272 .addSupportedUriScheme("tel")
273 .setCapabilities(
274 PhoneAccount.CAPABILITY_SELF_MANAGED)
275 .build();
Ihab Awadaa383cc2015-03-22 22:12:28 -0700276 final PhoneAccount mPhoneAccountB0 =
277 PhoneAccount.builder(
278 new PhoneAccountHandle(
Ihab Awad1b5490a2015-05-12 13:13:48 -0700279 mConnectionServiceComponentNameB,
Ihab Awadaa383cc2015-03-22 22:12:28 -0700280 "id B 0"),
281 "Phone account service B ID 0")
282 .addSupportedUriScheme("tel")
283 .setCapabilities(
284 PhoneAccount.CAPABILITY_CALL_PROVIDER |
Tyler Gunneaaf0742016-09-15 15:36:38 -0700285 PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION |
286 PhoneAccount.CAPABILITY_VIDEO_CALLING)
Ihab Awadaa383cc2015-03-22 22:12:28 -0700287 .build();
Brad Ebinger6e8f3d72016-06-20 11:35:42 -0700288 final PhoneAccount mPhoneAccountE0 =
289 PhoneAccount.builder(
290 new PhoneAccountHandle(
291 mConnectionServiceComponentNameA,
292 "id E 0"),
293 "Phone account service E ID 0")
294 .addSupportedUriScheme("tel")
295 .setCapabilities(
296 PhoneAccount.CAPABILITY_CALL_PROVIDER |
297 PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION |
Brad Ebingerd1b36692016-06-20 11:35:42 -0700298 PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS)
Brad Ebinger6e8f3d72016-06-20 11:35:42 -0700299 .build();
300
301 final PhoneAccount mPhoneAccountE1 =
302 PhoneAccount.builder(
303 new PhoneAccountHandle(
304 mConnectionServiceComponentNameA,
305 "id E 1"),
306 "Phone account service E ID 1")
307 .addSupportedUriScheme("tel")
308 .setCapabilities(
309 PhoneAccount.CAPABILITY_CALL_PROVIDER |
310 PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION |
Brad Ebingerd1b36692016-06-20 11:35:42 -0700311 PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS)
Brad Ebinger6e8f3d72016-06-20 11:35:42 -0700312 .build();
Ihab Awadaa383cc2015-03-22 22:12:28 -0700313
314 ConnectionServiceFixture mConnectionServiceFixtureA;
315 ConnectionServiceFixture mConnectionServiceFixtureB;
Hall Liu6d4b66d2016-04-01 16:31:13 -0700316 Timeouts.Adapter mTimeoutsAdapter;
Ihab Awadaa383cc2015-03-22 22:12:28 -0700317
Ihab Awadabcbce42015-04-07 14:04:01 -0700318 CallerInfoAsyncQueryFactoryFixture mCallerInfoAsyncQueryFactoryFixture;
319
Hall Liu8fb1fb72015-10-22 15:24:40 -0700320 IAudioService mAudioService;
321
Ihab Awadaa383cc2015-03-22 22:12:28 -0700322 TelecomSystem mTelecomSystem;
323
Hall Liuecda5542015-12-04 11:31:31 -0800324 Context mSpyContext;
325
Hall Liuf7783fb2015-11-23 18:45:48 -0800326 private int mNumOutgoingCallsMade;
327
Brad Ebinger6e8f3d72016-06-20 11:35:42 -0700328 private boolean mIsEmergencyCall;
329
Ihab Awad1b5490a2015-05-12 13:13:48 -0700330 class IdPair {
331 final String mConnectionId;
332 final String mCallId;
333
334 public IdPair(String connectionId, String callId) {
335 this.mConnectionId = connectionId;
336 this.mCallId = callId;
337 }
338 }
339
Ihab Awadaa383cc2015-03-22 22:12:28 -0700340 @Override
341 public void setUp() throws Exception {
342 super.setUp();
Hall Liuecda5542015-12-04 11:31:31 -0800343 mSpyContext = mComponentContextFixture.getTestDouble().getApplicationContext();
344 doReturn(mSpyContext).when(mSpyContext).getApplicationContext();
Tyler Gunn93dc55f2017-04-18 13:23:18 -0700345 doNothing().when(mSpyContext).sendBroadcastAsUser(any(), any(), any());
Hall Liuecda5542015-12-04 11:31:31 -0800346
Hall Liuf7783fb2015-11-23 18:45:48 -0800347 mNumOutgoingCallsMade = 0;
Ihab Awadaa383cc2015-03-22 22:12:28 -0700348
Brad Ebinger6e8f3d72016-06-20 11:35:42 -0700349 mIsEmergencyCall = false;
350
Ihab Awadaa383cc2015-03-22 22:12:28 -0700351 // First set up information about the In-Call services in the mock Context, since
352 // Telecom will search for these as soon as it is instantiated
353 setupInCallServices();
354
355 // Next, create the TelecomSystem, our system under test
356 setupTelecomSystem();
357
358 // Finally, register the ConnectionServices with the PhoneAccountRegistrar of the
359 // now-running TelecomSystem
360 setupConnectionServices();
Brad Ebinger7bba1112017-06-08 13:57:28 -0700361
362 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
Ihab Awadaa383cc2015-03-22 22:12:28 -0700363 }
364
365 @Override
366 public void tearDown() throws Exception {
Hall Liu486cb192016-10-21 18:23:33 -0700367 mTelecomSystem.getCallsManager().getCallAudioManager()
368 .getCallAudioRouteStateMachine().quitNow();
369 mTelecomSystem.getCallsManager().getCallAudioManager()
370 .getCallAudioModeStateMachine().quitNow();
Ihab Awadaa383cc2015-03-22 22:12:28 -0700371 mTelecomSystem = null;
372 super.tearDown();
373 }
374
Tyler Gunn961694a2016-03-21 16:01:40 -0700375 protected ParcelableCall makeConferenceCall() throws Exception {
376 IdPair callId1 = startAndMakeActiveOutgoingCall("650-555-1212",
377 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
378
379 IdPair callId2 = startAndMakeActiveOutgoingCall("650-555-1213",
380 mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
381
382 IInCallAdapter inCallAdapter = mInCallServiceFixtureX.getInCallAdapter();
383 inCallAdapter.conference(callId1.mCallId, callId2.mCallId);
384 // Wait for wacky non-deterministic behavior
385 Thread.sleep(200);
386 ParcelableCall call1 = mInCallServiceFixtureX.getCall(callId1.mCallId);
387 ParcelableCall call2 = mInCallServiceFixtureX.getCall(callId2.mCallId);
388 // Check that the two calls end up with a parent in the end
389 assertNotNull(call1.getParentCallId());
390 assertNotNull(call2.getParentCallId());
391 assertEquals(call1.getParentCallId(), call2.getParentCallId());
392
393 // Check to make sure that the parent call made it to the in-call service
394 String parentCallId = call1.getParentCallId();
395 ParcelableCall conferenceCall = mInCallServiceFixtureX.getCall(parentCallId);
396 assertEquals(2, conferenceCall.getChildCallIds().size());
397 assertTrue(conferenceCall.getChildCallIds().contains(callId1.mCallId));
398 assertTrue(conferenceCall.getChildCallIds().contains(callId2.mCallId));
399 return conferenceCall;
400 }
401
Ihab Awadaa383cc2015-03-22 22:12:28 -0700402 private void setupTelecomSystem() throws Exception {
Tyler Gunnae694b12015-11-11 17:46:03 -0800403 // Use actual implementations instead of mocking the interface out.
Ihab Awadaa383cc2015-03-22 22:12:28 -0700404 HeadsetMediaButtonFactory headsetMediaButtonFactory =
Tyler Gunnae694b12015-11-11 17:46:03 -0800405 spy(new HeadsetMediaButtonFactoryF());
Ihab Awadaa383cc2015-03-22 22:12:28 -0700406 ProximitySensorManagerFactory proximitySensorManagerFactory =
Tyler Gunnae694b12015-11-11 17:46:03 -0800407 spy(new ProximitySensorManagerFactoryF());
Ihab Awadaa383cc2015-03-22 22:12:28 -0700408 InCallWakeLockControllerFactory inCallWakeLockControllerFactory =
Tyler Gunnae694b12015-11-11 17:46:03 -0800409 spy(new InCallWakeLockControllerFactoryF());
Hall Liu8fb1fb72015-10-22 15:24:40 -0700410 mAudioService = setupAudioService();
Ihab Awadaa383cc2015-03-22 22:12:28 -0700411
Ihab Awadabcbce42015-04-07 14:04:01 -0700412 mCallerInfoAsyncQueryFactoryFixture = new CallerInfoAsyncQueryFactoryFixture();
413
Hall Liu6d4b66d2016-04-01 16:31:13 -0700414 mTimeoutsAdapter = mock(Timeouts.Adapter.class);
415 when(mTimeoutsAdapter.getCallScreeningTimeoutMillis(any(ContentResolver.class)))
Hall Liu609992b2016-08-31 15:48:51 -0700416 .thenReturn(TEST_TIMEOUT / 5L);
Tyler Gunn2b17f232017-03-08 08:51:00 -0800417 mIncomingCallNotifier = mock(IncomingCallNotifier.class);
Tyler Gunn8bb2b012017-08-04 09:28:59 -0700418 mClockProxy = mock(ClockProxy.class);
419 when(mClockProxy.currentTimeMillis()).thenReturn(TEST_CREATE_TIME);
420 when(mClockProxy.elapsedRealtime()).thenReturn(TEST_CREATE_ELAPSED_TIME);
Ihab Awadaa383cc2015-03-22 22:12:28 -0700421 mTelecomSystem = new TelecomSystem(
422 mComponentContextFixture.getTestDouble(),
Tony Maka9930942016-01-15 10:57:14 +0000423 new MissedCallNotifierImplFactory() {
424 @Override
425 public MissedCallNotifier makeMissedCallNotifierImpl(Context context,
Hall Liu7c928322016-12-06 18:15:39 -0800426 PhoneAccountRegistrar phoneAccountRegistrar,
427 DefaultDialerCache defaultDialerCache) {
Tony Maka9930942016-01-15 10:57:14 +0000428 return mMissedCallNotifier;
429 }
430 },
Ihab Awadabcbce42015-04-07 14:04:01 -0700431 mCallerInfoAsyncQueryFactoryFixture.getTestDouble(),
Ihab Awadaa383cc2015-03-22 22:12:28 -0700432 headsetMediaButtonFactory,
433 proximitySensorManagerFactory,
Hall Liu8fb1fb72015-10-22 15:24:40 -0700434 inCallWakeLockControllerFactory,
435 new CallAudioManager.AudioServiceFactory() {
436 @Override
437 public IAudioService getAudioService() {
438 return mAudioService;
439 }
Hall Liub3979ee2015-11-11 16:21:25 -0800440 },
441 new BluetoothPhoneServiceImpl.BluetoothPhoneServiceImplFactory() {
442 @Override
443 public BluetoothPhoneServiceImpl makeBluetoothPhoneServiceImpl(Context context,
444 TelecomSystem.SyncRoot lock, CallsManager callsManager,
445 PhoneAccountRegistrar phoneAccountRegistrar) {
446 return mBluetoothPhoneServiceImpl;
447 }
Brad Ebinger7ade5e22016-04-05 18:43:50 -0700448 },
Hall Liu6d4b66d2016-04-01 16:31:13 -0700449 mTimeoutsAdapter,
Brad Ebinger6e8f3d72016-06-20 11:35:42 -0700450 mAsyncRingtonePlayer,
Tyler Gunneaaf0742016-09-15 15:36:38 -0700451 mPhoneNumberUtilsAdapter,
Brad Ebinger7bba1112017-06-08 13:57:28 -0700452 mIncomingCallNotifier,
Tyler Gunn02e00dd2017-08-24 15:44:02 -0700453 (streamType, volume) -> mock(ToneGenerator.class),
Tyler Gunn8bb2b012017-08-04 09:28:59 -0700454 mClockProxy);
Ihab Awadaa383cc2015-03-22 22:12:28 -0700455
Hall Liu1d903dd2015-10-09 15:56:44 -0700456 mComponentContextFixture.setTelecomManager(new TelecomManager(
457 mComponentContextFixture.getTestDouble(),
458 mTelecomSystem.getTelecomServiceImpl().getBinder()));
459
Ihab Awadaa383cc2015-03-22 22:12:28 -0700460 verify(headsetMediaButtonFactory).create(
461 eq(mComponentContextFixture.getTestDouble().getApplicationContext()),
Ihab Awad731369c2015-05-19 09:23:21 -0700462 any(CallsManager.class),
463 any(TelecomSystem.SyncRoot.class));
Ihab Awadaa383cc2015-03-22 22:12:28 -0700464 verify(proximitySensorManagerFactory).create(
465 eq(mComponentContextFixture.getTestDouble().getApplicationContext()),
466 any(CallsManager.class));
467 verify(inCallWakeLockControllerFactory).create(
468 eq(mComponentContextFixture.getTestDouble().getApplicationContext()),
469 any(CallsManager.class));
470 }
471
472 private void setupConnectionServices() throws Exception {
Hall Liu74bb6352017-12-27 18:23:28 -0800473 mConnectionServiceFixtureA = new ConnectionServiceFixture(mContext);
474 mConnectionServiceFixtureB = new ConnectionServiceFixture(mContext);
Ihab Awadaa383cc2015-03-22 22:12:28 -0700475
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800476 mComponentContextFixture.addConnectionService(mConnectionServiceComponentNameA,
Ihab Awadaa383cc2015-03-22 22:12:28 -0700477 mConnectionServiceFixtureA.getTestDouble());
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800478 mComponentContextFixture.addConnectionService(mConnectionServiceComponentNameB,
Ihab Awadaa383cc2015-03-22 22:12:28 -0700479 mConnectionServiceFixtureB.getTestDouble());
480
481 mTelecomSystem.getPhoneAccountRegistrar().registerPhoneAccount(mPhoneAccountA0);
482 mTelecomSystem.getPhoneAccountRegistrar().registerPhoneAccount(mPhoneAccountA1);
Tyler Gunnddec5892016-09-28 10:26:13 -0700483 mTelecomSystem.getPhoneAccountRegistrar().registerPhoneAccount(mPhoneAccountA2);
Tyler Gunn153aafa2017-10-06 10:08:18 -0700484 mTelecomSystem.getPhoneAccountRegistrar().registerPhoneAccount(mPhoneAccountSelfManaged);
Ihab Awadaa383cc2015-03-22 22:12:28 -0700485 mTelecomSystem.getPhoneAccountRegistrar().registerPhoneAccount(mPhoneAccountB0);
Brad Ebinger6e8f3d72016-06-20 11:35:42 -0700486 mTelecomSystem.getPhoneAccountRegistrar().registerPhoneAccount(mPhoneAccountE0);
487 mTelecomSystem.getPhoneAccountRegistrar().registerPhoneAccount(mPhoneAccountE1);
Ihab Awad0a4b95f2015-05-18 10:15:38 -0700488
489 mTelecomSystem.getPhoneAccountRegistrar().setUserSelectedOutgoingPhoneAccount(
Tony Mak4a3e2fd2015-12-04 11:58:38 +0000490 mPhoneAccountA0.getAccountHandle(), Process.myUserHandle());
Ihab Awadaa383cc2015-03-22 22:12:28 -0700491 }
492
493 private void setupInCallServices() throws Exception {
494 mComponentContextFixture.putResource(
495 com.android.server.telecom.R.string.ui_default_package,
496 mInCallServiceComponentNameX.getPackageName());
497 mComponentContextFixture.putResource(
498 com.android.server.telecom.R.string.incall_default_class,
499 mInCallServiceComponentNameX.getClassName());
Brad Ebingerf4745b62015-12-08 17:57:59 -0800500 mComponentContextFixture.putBooleanResource(
501 com.android.internal.R.bool.config_voice_capable, true);
Ihab Awadaa383cc2015-03-22 22:12:28 -0700502
503 mInCallServiceFixtureX = new InCallServiceFixture();
504 mInCallServiceFixtureY = new InCallServiceFixture();
505
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800506 mComponentContextFixture.addInCallService(mInCallServiceComponentNameX,
Ihab Awadaa383cc2015-03-22 22:12:28 -0700507 mInCallServiceFixtureX.getTestDouble());
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800508 mComponentContextFixture.addInCallService(mInCallServiceComponentNameY,
Ihab Awadaa383cc2015-03-22 22:12:28 -0700509 mInCallServiceFixtureY.getTestDouble());
510 }
511
Hall Liu8fb1fb72015-10-22 15:24:40 -0700512 /**
513 * Helper method for setting up the fake audio service.
514 * Calls to the fake audio service need to toggle the return
515 * value of AudioManager#isMicrophoneMute.
516 * @return mock of IAudioService
517 */
518 private IAudioService setupAudioService() {
519 IAudioService audioService = mock(IAudioService.class);
Tyler Gunnae694b12015-11-11 17:46:03 -0800520
Hall Liu8fb1fb72015-10-22 15:24:40 -0700521 final AudioManager fakeAudioManager =
522 (AudioManager) mComponentContextFixture.getTestDouble()
523 .getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
524
525 try {
526 doAnswer(new Answer() {
527 @Override
528 public Object answer(InvocationOnMock i) {
529 Object[] args = i.getArguments();
530 doReturn(args[0]).when(fakeAudioManager).isMicrophoneMute();
531 return null;
532 }
533 }).when(audioService)
534 .setMicrophoneMute(any(Boolean.class), any(String.class), any(Integer.class));
535
536 } catch (android.os.RemoteException e) {
537 // Do nothing, leave the faked microphone state as-is
538 }
539 return audioService;
540 }
541
Brad Ebingerc301b512016-03-16 18:27:57 -0700542 protected String startOutgoingPhoneCallWithNoPhoneAccount(String number,
543 ConnectionServiceFixture connectionServiceFixture)
544 throws Exception {
545
546 return startOutgoingPhoneCallPendingCreateConnection(number, null,
547 connectionServiceFixture, Process.myUserHandle(), VideoProfile.STATE_AUDIO_ONLY);
548 }
549
550 protected IdPair outgoingCallPhoneAccountSelected(PhoneAccountHandle phoneAccountHandle,
551 int startingNumConnections, int startingNumCalls,
552 ConnectionServiceFixture connectionServiceFixture) throws Exception {
553
554 IdPair ids = outgoingCallCreateConnectionComplete(startingNumConnections, startingNumCalls,
555 phoneAccountHandle, connectionServiceFixture);
556
557 connectionServiceFixture.sendSetDialing(ids.mConnectionId);
558 assertEquals(Call.STATE_DIALING, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
559 assertEquals(Call.STATE_DIALING, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
560
561 connectionServiceFixture.sendSetVideoState(ids.mConnectionId);
562
563 connectionServiceFixture.sendSetActive(ids.mConnectionId);
564 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
565 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
566
567 return ids;
568 }
569
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800570 protected IdPair startOutgoingPhoneCall(String number, PhoneAccountHandle phoneAccountHandle,
571 ConnectionServiceFixture connectionServiceFixture, UserHandle initiatingUser)
572 throws Exception {
Brad Ebingerc301b512016-03-16 18:27:57 -0700573
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800574 return startOutgoingPhoneCall(number, phoneAccountHandle, connectionServiceFixture,
575 initiatingUser, VideoProfile.STATE_AUDIO_ONLY);
576 }
577
578 protected IdPair startOutgoingPhoneCall(String number, PhoneAccountHandle phoneAccountHandle,
579 ConnectionServiceFixture connectionServiceFixture, UserHandle initiatingUser,
580 int videoState) throws Exception {
Brad Ebingerc301b512016-03-16 18:27:57 -0700581 int startingNumConnections = connectionServiceFixture.mConnectionById.size();
582 int startingNumCalls = mInCallServiceFixtureX.mCallById.size();
583
Hall Liu130209c2017-11-17 17:17:57 -0800584 startOutgoingPhoneCallPendingCreateConnection(number, phoneAccountHandle,
Brad Ebingerc301b512016-03-16 18:27:57 -0700585 connectionServiceFixture, initiatingUser, videoState);
586
587 return outgoingCallCreateConnectionComplete(startingNumConnections, startingNumCalls,
588 phoneAccountHandle, connectionServiceFixture);
589 }
590
Brad Ebinger6e8f3d72016-06-20 11:35:42 -0700591 protected IdPair triggerEmergencyRedial(PhoneAccountHandle phoneAccountHandle,
592 ConnectionServiceFixture connectionServiceFixture, IdPair emergencyIds)
593 throws Exception {
594 int startingNumConnections = connectionServiceFixture.mConnectionById.size();
595 int startingNumCalls = mInCallServiceFixtureX.mCallById.size();
596
597 // Send the message to disconnect the Emergency call due to an error.
598 // CreateConnectionProcessor should now try the second SIM account
599 connectionServiceFixture.sendSetDisconnected(emergencyIds.mConnectionId,
600 DisconnectCause.ERROR);
601 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
602 assertEquals(Call.STATE_DIALING, mInCallServiceFixtureX.getCall(
603 emergencyIds.mCallId).getState());
604 assertEquals(Call.STATE_DIALING, mInCallServiceFixtureY.getCall(
605 emergencyIds.mCallId).getState());
606
607 return redialingCallCreateConnectionComplete(startingNumConnections, startingNumCalls,
608 phoneAccountHandle, connectionServiceFixture);
609 }
610
611 protected IdPair startOutgoingEmergencyCall(String number,
Brad Ebingerc301b512016-03-16 18:27:57 -0700612 PhoneAccountHandle phoneAccountHandle,
613 ConnectionServiceFixture connectionServiceFixture, UserHandle initiatingUser,
614 int videoState) throws Exception {
Brad Ebinger6e8f3d72016-06-20 11:35:42 -0700615 int startingNumConnections = connectionServiceFixture.mConnectionById.size();
616 int startingNumCalls = mInCallServiceFixtureX.mCallById.size();
617
618 mIsEmergencyCall = true;
619 // Call will not use the ordered broadcaster, since it is an Emergency Call
620 startOutgoingPhoneCallWaitForBroadcaster(number, phoneAccountHandle,
621 connectionServiceFixture, initiatingUser, videoState, true /*isEmergency*/);
622
623 return outgoingCallCreateConnectionComplete(startingNumConnections, startingNumCalls,
624 phoneAccountHandle, connectionServiceFixture);
625 }
626
627 protected void startOutgoingPhoneCallWaitForBroadcaster(String number,
628 PhoneAccountHandle phoneAccountHandle,
629 ConnectionServiceFixture connectionServiceFixture, UserHandle initiatingUser,
630 int videoState, boolean isEmergency) throws Exception {
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800631 reset(connectionServiceFixture.getTestDouble(), mInCallServiceFixtureX.getTestDouble(),
Ihab Awad1b5490a2015-05-12 13:13:48 -0700632 mInCallServiceFixtureY.getTestDouble());
633
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800634 assertEquals(mInCallServiceFixtureX.mCallById.size(),
Ihab Awad1b5490a2015-05-12 13:13:48 -0700635 mInCallServiceFixtureY.mCallById.size());
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800636 assertEquals((mInCallServiceFixtureX.mInCallAdapter != null),
Ihab Awad1b5490a2015-05-12 13:13:48 -0700637 (mInCallServiceFixtureY.mInCallAdapter != null));
638
Hall Liuf7783fb2015-11-23 18:45:48 -0800639 mNumOutgoingCallsMade++;
Brad Ebingerc301b512016-03-16 18:27:57 -0700640
Ihab Awad1b5490a2015-05-12 13:13:48 -0700641 boolean hasInCallAdapter = mInCallServiceFixtureX.mInCallAdapter != null;
642
Ihab Awadaa383cc2015-03-22 22:12:28 -0700643 Intent actionCallIntent = new Intent();
644 actionCallIntent.setData(Uri.parse("tel:" + number));
645 actionCallIntent.putExtra(Intent.EXTRA_PHONE_NUMBER, number);
Brad Ebinger6e8f3d72016-06-20 11:35:42 -0700646 if(isEmergency) {
647 actionCallIntent.setAction(Intent.ACTION_CALL_EMERGENCY);
648 } else {
649 actionCallIntent.setAction(Intent.ACTION_CALL);
650 }
Ihab Awadaa383cc2015-03-22 22:12:28 -0700651 if (phoneAccountHandle != null) {
652 actionCallIntent.putExtra(
653 TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
654 phoneAccountHandle);
655 }
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800656 if (videoState != VideoProfile.STATE_AUDIO_ONLY) {
657 actionCallIntent.putExtra(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, videoState);
658 }
Ihab Awadaa383cc2015-03-22 22:12:28 -0700659
Tony Mak578a4e62015-11-23 11:18:51 +0000660 final UserHandle userHandle = initiatingUser;
Brad Ebingerf4745b62015-12-08 17:57:59 -0800661 Context localAppContext = mComponentContextFixture.getTestDouble().getApplicationContext();
662 new UserCallIntentProcessor(localAppContext, userHandle).processIntent(
663 actionCallIntent, null, true /* hasCallAppOp*/);
664 // UserCallIntentProcessor's mContext.sendBroadcastAsUser(...) will call to an empty method
665 // as to not actually try to send an intent to PrimaryCallReceiver. We verify that it was
666 // called correctly in order to continue.
667 verify(localAppContext).sendBroadcastAsUser(actionCallIntent, UserHandle.SYSTEM);
Ihab Awadaa383cc2015-03-22 22:12:28 -0700668 mTelecomSystem.getCallIntentProcessor().processIntent(actionCallIntent);
Brad Ebingerc37ddf12016-10-18 13:43:23 -0700669 // Wait for handler to start CallerInfo lookup.
670 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
671 // Send the CallerInfo lookup reply.
672 mCallerInfoAsyncQueryFactoryFixture.mRequests.forEach(
673 CallerInfoAsyncQueryFactoryFixture.Request::reply);
Ihab Awadaa383cc2015-03-22 22:12:28 -0700674
Tyler Gunn153aafa2017-10-06 10:08:18 -0700675 boolean isSelfManaged = phoneAccountHandle == mPhoneAccountSelfManaged.getAccountHandle();
676 if (!hasInCallAdapter && !isSelfManaged) {
Ihab Awad1b5490a2015-05-12 13:13:48 -0700677 verify(mInCallServiceFixtureX.getTestDouble())
678 .setInCallAdapter(
679 any(IInCallAdapter.class));
680 verify(mInCallServiceFixtureY.getTestDouble())
681 .setInCallAdapter(
682 any(IInCallAdapter.class));
683 }
Brad Ebinger6e8f3d72016-06-20 11:35:42 -0700684 }
685
686 protected String startOutgoingPhoneCallPendingCreateConnection(String number,
687 PhoneAccountHandle phoneAccountHandle,
688 ConnectionServiceFixture connectionServiceFixture, UserHandle initiatingUser,
689 int videoState) throws Exception {
690 startOutgoingPhoneCallWaitForBroadcaster(number,phoneAccountHandle,
691 connectionServiceFixture, initiatingUser, videoState, false /*isEmergency*/);
Ihab Awad1b5490a2015-05-12 13:13:48 -0700692
Ihab Awadaa383cc2015-03-22 22:12:28 -0700693 ArgumentCaptor<Intent> newOutgoingCallIntent =
694 ArgumentCaptor.forClass(Intent.class);
695 ArgumentCaptor<BroadcastReceiver> newOutgoingCallReceiver =
696 ArgumentCaptor.forClass(BroadcastReceiver.class);
697
Tyler Gunn153aafa2017-10-06 10:08:18 -0700698 if (phoneAccountHandle != mPhoneAccountSelfManaged.getAccountHandle()) {
699 verify(mComponentContextFixture.getTestDouble().getApplicationContext(),
700 times(mNumOutgoingCallsMade))
701 .sendOrderedBroadcastAsUser(
702 newOutgoingCallIntent.capture(),
703 any(UserHandle.class),
704 anyString(),
705 anyInt(),
706 newOutgoingCallReceiver.capture(),
707 nullable(Handler.class),
708 anyInt(),
709 anyString(),
710 nullable(Bundle.class));
711 // Pass on the new outgoing call Intent
712 // Set a dummy PendingResult so the BroadcastReceiver agrees to accept onReceive()
713 newOutgoingCallReceiver.getValue().setPendingResult(
714 new BroadcastReceiver.PendingResult(0, "", null, 0, true, false, null, 0, 0));
715 newOutgoingCallReceiver.getValue().setResultData(
716 newOutgoingCallIntent.getValue().getStringExtra(Intent.EXTRA_PHONE_NUMBER));
717 newOutgoingCallReceiver.getValue().onReceive(mComponentContextFixture.getTestDouble(),
718 newOutgoingCallIntent.getValue());
719 }
Ihab Awadaa383cc2015-03-22 22:12:28 -0700720
Brad Ebingerc301b512016-03-16 18:27:57 -0700721 return mInCallServiceFixtureX.mLatestCallId;
722 }
723
Brad Ebinger6e8f3d72016-06-20 11:35:42 -0700724 // When Telecom is redialing due to an error, we need to make sure the number of connections
725 // increase, but not the number of Calls in the InCallService.
726 protected IdPair redialingCallCreateConnectionComplete(int startingNumConnections,
727 int startingNumCalls, PhoneAccountHandle phoneAccountHandle,
728 ConnectionServiceFixture connectionServiceFixture) throws Exception {
729
730 assertEquals(startingNumConnections + 1, connectionServiceFixture.mConnectionById.size());
731
732 verify(connectionServiceFixture.getTestDouble())
733 .createConnection(eq(phoneAccountHandle), anyString(), any(ConnectionRequest.class),
Brad Ebingerb78b0232016-10-24 16:40:33 -0700734 eq(false)/*isIncoming*/, anyBoolean(), any());
Brad Ebinger6e8f3d72016-06-20 11:35:42 -0700735 // Wait for handleCreateConnectionComplete
736 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
737
738 // Make sure the number of registered InCallService Calls stays the same.
739 assertEquals(startingNumCalls, mInCallServiceFixtureX.mCallById.size());
740 assertEquals(startingNumCalls, mInCallServiceFixtureY.mCallById.size());
741
742 assertEquals(mInCallServiceFixtureX.mLatestCallId, mInCallServiceFixtureY.mLatestCallId);
743
744 return new IdPair(connectionServiceFixture.mLatestConnectionId,
745 mInCallServiceFixtureX.mLatestCallId);
746 }
747
Brad Ebingerc301b512016-03-16 18:27:57 -0700748 protected IdPair outgoingCallCreateConnectionComplete(int startingNumConnections,
749 int startingNumCalls, PhoneAccountHandle phoneAccountHandle,
750 ConnectionServiceFixture connectionServiceFixture) throws Exception {
751
Ihab Awad1b5490a2015-05-12 13:13:48 -0700752 assertEquals(startingNumConnections + 1, connectionServiceFixture.mConnectionById.size());
753
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800754 verify(connectionServiceFixture.getTestDouble())
755 .createConnection(eq(phoneAccountHandle), anyString(), any(ConnectionRequest.class),
Brad Ebingerb78b0232016-10-24 16:40:33 -0700756 eq(false)/*isIncoming*/, anyBoolean(), any());
Brad Ebinger84771f82016-05-18 16:57:30 -0700757 // Wait for handleCreateConnectionComplete
758 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
Hall Liub3ce5102016-07-14 12:53:08 -0700759 // Wait for the callback in ConnectionService#onAdapterAttached to execute.
760 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
Ihab Awadaa383cc2015-03-22 22:12:28 -0700761
Tyler Gunnddb03e12017-05-12 11:54:41 -0700762 // Ensure callback to CS on successful creation happened.
763 verify(connectionServiceFixture.getTestDouble(), timeout(TEST_TIMEOUT))
764 .createConnectionComplete(anyString(), any());
765
Tyler Gunn153aafa2017-10-06 10:08:18 -0700766 if (phoneAccountHandle == mPhoneAccountSelfManaged.getAccountHandle()) {
767 assertEquals(startingNumCalls, mInCallServiceFixtureX.mCallById.size());
768 assertEquals(startingNumCalls, mInCallServiceFixtureY.mCallById.size());
769 } else {
770 assertEquals(startingNumCalls + 1, mInCallServiceFixtureX.mCallById.size());
771 assertEquals(startingNumCalls + 1, mInCallServiceFixtureY.mCallById.size());
772 }
Ihab Awadaa383cc2015-03-22 22:12:28 -0700773
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800774 assertEquals(mInCallServiceFixtureX.mLatestCallId, mInCallServiceFixtureY.mLatestCallId);
Ihab Awad1b5490a2015-05-12 13:13:48 -0700775
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800776 return new IdPair(connectionServiceFixture.mLatestConnectionId,
Ihab Awad1b5490a2015-05-12 13:13:48 -0700777 mInCallServiceFixtureX.mLatestCallId);
Ihab Awadaa383cc2015-03-22 22:12:28 -0700778 }
779
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800780 protected IdPair startIncomingPhoneCall(
Ihab Awadaa383cc2015-03-22 22:12:28 -0700781 String number,
782 PhoneAccountHandle phoneAccountHandle,
Ihab Awad32dd7c32015-05-28 10:52:20 -0700783 final ConnectionServiceFixture connectionServiceFixture) throws Exception {
Tyler Gunn42ef8082015-11-24 15:34:34 -0800784 return startIncomingPhoneCall(number, phoneAccountHandle, VideoProfile.STATE_AUDIO_ONLY,
785 connectionServiceFixture);
786 }
787
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800788 protected IdPair startIncomingPhoneCall(
Tyler Gunn42ef8082015-11-24 15:34:34 -0800789 String number,
790 PhoneAccountHandle phoneAccountHandle,
791 int videoState,
792 final ConnectionServiceFixture connectionServiceFixture) throws Exception {
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800793 reset(connectionServiceFixture.getTestDouble(), mInCallServiceFixtureX.getTestDouble(),
Ihab Awad1b5490a2015-05-12 13:13:48 -0700794 mInCallServiceFixtureY.getTestDouble());
795
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800796 assertEquals(mInCallServiceFixtureX.mCallById.size(),
Ihab Awad1b5490a2015-05-12 13:13:48 -0700797 mInCallServiceFixtureY.mCallById.size());
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800798 assertEquals((mInCallServiceFixtureX.mInCallAdapter != null),
Ihab Awad1b5490a2015-05-12 13:13:48 -0700799 (mInCallServiceFixtureY.mInCallAdapter != null));
Ihab Awad32dd7c32015-05-28 10:52:20 -0700800 final int startingNumConnections = connectionServiceFixture.mConnectionById.size();
801 final int startingNumCalls = mInCallServiceFixtureX.mCallById.size();
Ihab Awad1b5490a2015-05-12 13:13:48 -0700802 boolean hasInCallAdapter = mInCallServiceFixtureX.mInCallAdapter != null;
Abhijith Shastryb7853c02016-02-03 12:56:59 -0800803 connectionServiceFixture.mConnectionServiceDelegate.mVideoState = videoState;
Brad Ebinger7bba1112017-06-08 13:57:28 -0700804 CountDownLatch incomingCallAddedLatch = new CountDownLatch(1);
805 IncomingCallAddedListener callAddedListener =
806 new IncomingCallAddedListener(incomingCallAddedLatch);
807 mTelecomSystem.getCallsManager().addListener(callAddedListener);
Ihab Awad1b5490a2015-05-12 13:13:48 -0700808
Ihab Awadaa383cc2015-03-22 22:12:28 -0700809 Bundle extras = new Bundle();
810 extras.putParcelable(
Yorke Lee69fa8972015-06-08 11:25:32 -0700811 TelecomManager.EXTRA_INCOMING_CALL_ADDRESS,
Ihab Awadaa383cc2015-03-22 22:12:28 -0700812 Uri.fromParts(PhoneAccount.SCHEME_TEL, number, null));
813 mTelecomSystem.getTelecomServiceImpl().getBinder()
814 .addNewIncomingCall(phoneAccountHandle, extras);
815
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800816 verify(connectionServiceFixture.getTestDouble())
817 .createConnection(any(PhoneAccountHandle.class), anyString(),
Brad Ebingerb78b0232016-10-24 16:40:33 -0700818 any(ConnectionRequest.class), eq(true), eq(false), any());
Ihab Awadaa383cc2015-03-22 22:12:28 -0700819
Brad Ebingerc37ddf12016-10-18 13:43:23 -0700820 // Wait for the handler to start the CallerInfo lookup
821 waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
Tyler Gunnddb03e12017-05-12 11:54:41 -0700822
823 // Ensure callback to CS on successful creation happened.
824 verify(connectionServiceFixture.getTestDouble(), timeout(TEST_TIMEOUT))
825 .createConnectionComplete(anyString(), any());
826
827
Brad Ebingerc37ddf12016-10-18 13:43:23 -0700828 // Process the CallerInfo lookup reply
829 mCallerInfoAsyncQueryFactoryFixture.mRequests.forEach(
830 CallerInfoAsyncQueryFactoryFixture.Request::reply);
Ihab Awadaa383cc2015-03-22 22:12:28 -0700831
Brad Ebinger7bba1112017-06-08 13:57:28 -0700832 //Wait for/Verify call blocking happened asynchronously
833 incomingCallAddedLatch.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS);
834
Abhijith Shastryc6e42ef2016-02-19 18:26:44 -0800835 IContentProvider blockedNumberProvider =
836 mSpyContext.getContentResolver().acquireProvider(BlockedNumberContract.AUTHORITY);
837 verify(blockedNumberProvider, timeout(TEST_TIMEOUT)).call(
838 anyString(),
839 eq(BlockedNumberContract.SystemContract.METHOD_SHOULD_SYSTEM_BLOCK_NUMBER),
840 eq(number),
841 isNull(Bundle.class));
842
Ihab Awadaa383cc2015-03-22 22:12:28 -0700843 // For the case of incoming calls, Telecom connecting the InCall services and adding the
844 // Call is triggered by the async completion of the CallerInfoAsyncQuery. Once the Call
845 // is added, future interactions as triggered by the ConnectionService, through the various
846 // test fixtures, will be synchronous.
847
Hall Liu130209c2017-11-17 17:17:57 -0800848 if (phoneAccountHandle != mPhoneAccountSelfManaged.getAccountHandle()) {
849 if (!hasInCallAdapter) {
850 verify(mInCallServiceFixtureX.getTestDouble(), timeout(TEST_TIMEOUT))
851 .setInCallAdapter(any(IInCallAdapter.class));
852 verify(mInCallServiceFixtureY.getTestDouble(), timeout(TEST_TIMEOUT))
853 .setInCallAdapter(any(IInCallAdapter.class));
Tyler Gunn153aafa2017-10-06 10:08:18 -0700854
Hall Liu130209c2017-11-17 17:17:57 -0800855 // Give the InCallService time to respond
856 assertTrueWithTimeout(new Predicate<Void>() {
857 @Override
858 public boolean apply(Void v) {
859 return mInCallServiceFixtureX.mInCallAdapter != null;
860 }
861 });
Tyler Gunn153aafa2017-10-06 10:08:18 -0700862
Hall Liu130209c2017-11-17 17:17:57 -0800863 assertTrueWithTimeout(new Predicate<Void>() {
864 @Override
865 public boolean apply(Void v) {
866 return mInCallServiceFixtureY.mInCallAdapter != null;
867 }
868 });
Tyler Gunn153aafa2017-10-06 10:08:18 -0700869
Hall Liu130209c2017-11-17 17:17:57 -0800870 verify(mInCallServiceFixtureX.getTestDouble(), timeout(TEST_TIMEOUT))
871 .addCall(any(ParcelableCall.class));
872 verify(mInCallServiceFixtureY.getTestDouble(), timeout(TEST_TIMEOUT))
873 .addCall(any(ParcelableCall.class));
Tyler Gunn153aafa2017-10-06 10:08:18 -0700874
Hall Liu130209c2017-11-17 17:17:57 -0800875 // Give the InCallService time to respond
876 }
Tyler Gunn153aafa2017-10-06 10:08:18 -0700877
878 assertTrueWithTimeout(new Predicate<Void>() {
879 @Override
880 public boolean apply(Void v) {
881 return startingNumConnections + 1 ==
882 connectionServiceFixture.mConnectionById.size();
883 }
884 });
Hall Liu130209c2017-11-17 17:17:57 -0800885
886 mInCallServiceFixtureX.waitUntilNumCalls(startingNumCalls + 1);
887 mInCallServiceFixtureY.waitUntilNumCalls(startingNumCalls + 1);
888 assertEquals(startingNumCalls + 1, mInCallServiceFixtureX.mCallById.size());
889 assertEquals(startingNumCalls + 1, mInCallServiceFixtureY.mCallById.size());
Tyler Gunn153aafa2017-10-06 10:08:18 -0700890
891 assertEquals(mInCallServiceFixtureX.mLatestCallId,
892 mInCallServiceFixtureY.mLatestCallId);
Ihab Awad1b5490a2015-05-12 13:13:48 -0700893 }
894
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800895 return new IdPair(connectionServiceFixture.mLatestConnectionId,
Ihab Awad1b5490a2015-05-12 13:13:48 -0700896 mInCallServiceFixtureX.mLatestCallId);
Ihab Awadaa383cc2015-03-22 22:12:28 -0700897 }
898
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800899 protected IdPair startAndMakeActiveOutgoingCall(
900 String number,
901 PhoneAccountHandle phoneAccountHandle,
902 ConnectionServiceFixture connectionServiceFixture) throws Exception {
903 return startAndMakeActiveOutgoingCall(number, phoneAccountHandle, connectionServiceFixture,
904 VideoProfile.STATE_AUDIO_ONLY);
Ihab Awadabcbce42015-04-07 14:04:01 -0700905 }
906
Ihab Awadaa383cc2015-03-22 22:12:28 -0700907 // A simple outgoing call, verifying that the appropriate connection service is contacted,
908 // the proper lifecycle is followed, and both In-Call Services are updated correctly.
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800909 protected IdPair startAndMakeActiveOutgoingCall(
Ihab Awad1b5490a2015-05-12 13:13:48 -0700910 String number,
911 PhoneAccountHandle phoneAccountHandle,
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800912 ConnectionServiceFixture connectionServiceFixture, int videoState) throws Exception {
Tony Mak578a4e62015-11-23 11:18:51 +0000913 IdPair ids = startOutgoingPhoneCall(number, phoneAccountHandle, connectionServiceFixture,
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800914 Process.myUserHandle(), videoState);
Ihab Awad1b5490a2015-05-12 13:13:48 -0700915
916 connectionServiceFixture.sendSetDialing(ids.mConnectionId);
Tyler Gunn153aafa2017-10-06 10:08:18 -0700917 if (phoneAccountHandle != mPhoneAccountSelfManaged.getAccountHandle()) {
918 assertEquals(Call.STATE_DIALING,
919 mInCallServiceFixtureX.getCall(ids.mCallId).getState());
920 assertEquals(Call.STATE_DIALING,
921 mInCallServiceFixtureY.getCall(ids.mCallId).getState());
922 }
Ihab Awad1b5490a2015-05-12 13:13:48 -0700923
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800924 connectionServiceFixture.sendSetVideoState(ids.mConnectionId);
925
Tyler Gunn8bb2b012017-08-04 09:28:59 -0700926 when(mClockProxy.currentTimeMillis()).thenReturn(TEST_CONNECT_TIME);
927 when(mClockProxy.elapsedRealtime()).thenReturn(TEST_CONNECT_ELAPSED_TIME);
Ihab Awad1b5490a2015-05-12 13:13:48 -0700928 connectionServiceFixture.sendSetActive(ids.mConnectionId);
Tyler Gunn153aafa2017-10-06 10:08:18 -0700929 if (phoneAccountHandle != mPhoneAccountSelfManaged.getAccountHandle()) {
930 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
931 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
932 }
Ihab Awad1b5490a2015-05-12 13:13:48 -0700933 return ids;
934 }
935
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800936 protected IdPair startAndMakeActiveIncomingCall(
Ihab Awad1b5490a2015-05-12 13:13:48 -0700937 String number,
938 PhoneAccountHandle phoneAccountHandle,
939 ConnectionServiceFixture connectionServiceFixture) throws Exception {
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800940 return startAndMakeActiveIncomingCall(number, phoneAccountHandle, connectionServiceFixture,
941 VideoProfile.STATE_AUDIO_ONLY);
942 }
943
944 // A simple incoming call, similar in scope to the previous test
945 protected IdPair startAndMakeActiveIncomingCall(
946 String number,
947 PhoneAccountHandle phoneAccountHandle,
948 ConnectionServiceFixture connectionServiceFixture,
949 int videoState) throws Exception {
Ihab Awad1b5490a2015-05-12 13:13:48 -0700950 IdPair ids = startIncomingPhoneCall(number, phoneAccountHandle, connectionServiceFixture);
951
Tyler Gunn153aafa2017-10-06 10:08:18 -0700952 if (phoneAccountHandle != mPhoneAccountSelfManaged.getAccountHandle()) {
953 assertEquals(Call.STATE_RINGING,
954 mInCallServiceFixtureX.getCall(ids.mCallId).getState());
955 assertEquals(Call.STATE_RINGING,
956 mInCallServiceFixtureY.getCall(ids.mCallId).getState());
Ihab Awad1b5490a2015-05-12 13:13:48 -0700957
Tyler Gunn153aafa2017-10-06 10:08:18 -0700958 mInCallServiceFixtureX.mInCallAdapter
959 .answerCall(ids.mCallId, videoState);
Ihab Awad32dd7c32015-05-28 10:52:20 -0700960
Tyler Gunn153aafa2017-10-06 10:08:18 -0700961 if (!VideoProfile.isVideo(videoState)) {
962 verify(connectionServiceFixture.getTestDouble())
963 .answer(eq(ids.mConnectionId), any());
964 } else {
965 verify(connectionServiceFixture.getTestDouble())
966 .answerVideo(eq(ids.mConnectionId), eq(videoState), any());
967 }
Tyler Gunnb492f4c2015-12-15 08:15:43 -0800968 }
Ihab Awad32dd7c32015-05-28 10:52:20 -0700969
Tyler Gunn8bb2b012017-08-04 09:28:59 -0700970 when(mClockProxy.currentTimeMillis()).thenReturn(TEST_CONNECT_TIME);
971 when(mClockProxy.elapsedRealtime()).thenReturn(TEST_CONNECT_ELAPSED_TIME);
Ihab Awad1b5490a2015-05-12 13:13:48 -0700972 connectionServiceFixture.sendSetActive(ids.mConnectionId);
Ihab Awad1b5490a2015-05-12 13:13:48 -0700973
Tyler Gunn153aafa2017-10-06 10:08:18 -0700974 if (phoneAccountHandle != mPhoneAccountSelfManaged.getAccountHandle()) {
975 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
976 assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
977 }
Ihab Awad1b5490a2015-05-12 13:13:48 -0700978 return ids;
979 }
980
Brad Ebinger6e8f3d72016-06-20 11:35:42 -0700981 protected IdPair startAndMakeDialingEmergencyCall(
982 String number,
983 PhoneAccountHandle phoneAccountHandle,
984 ConnectionServiceFixture connectionServiceFixture) throws Exception {
985 IdPair ids = startOutgoingEmergencyCall(number, phoneAccountHandle,
986 connectionServiceFixture, Process.myUserHandle(), VideoProfile.STATE_AUDIO_ONLY);
987
988 connectionServiceFixture.sendSetDialing(ids.mConnectionId);
989 assertEquals(Call.STATE_DIALING, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
990 assertEquals(Call.STATE_DIALING, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
991
992 return ids;
993 }
994
Ihab Awad32dd7c32015-05-28 10:52:20 -0700995 protected static void assertTrueWithTimeout(Predicate<Void> predicate) {
996 int elapsed = 0;
997 while (elapsed < TEST_TIMEOUT) {
998 if (predicate.apply(null)) {
999 return;
1000 } else {
1001 try {
1002 Thread.sleep(TEST_POLL_INTERVAL);
1003 elapsed += TEST_POLL_INTERVAL;
1004 } catch (InterruptedException e) {
1005 fail(e.toString());
1006 }
1007 }
Ihab Awad1b5490a2015-05-12 13:13:48 -07001008 }
Ihab Awad32dd7c32015-05-28 10:52:20 -07001009 fail("Timeout in assertTrueWithTimeout");
Ihab Awad1b5490a2015-05-12 13:13:48 -07001010 }
Ihab Awadaa383cc2015-03-22 22:12:28 -07001011}