1aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad/*
2aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad * Copyright (C) 2015 The Android Open Source Project
3aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad *
4aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad * Licensed under the Apache License, Version 2.0 (the "License");
5aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad * you may not use this file except in compliance with the License.
6aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad * You may obtain a copy of the License at
7aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad *
8aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad *      http://www.apache.org/licenses/LICENSE-2.0
9aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad *
10aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad * Unless required by applicable law or agreed to in writing, software
11aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad * distributed under the License is distributed on an "AS IS" BASIS,
12aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad * See the License for the specific language governing permissions and
14aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad * limitations under the License.
15aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad */
16aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
172c93c50e5be7d85b78c4af15aaa10e44f0bcdf3eBrad Ebingerpackage com.android.server.telecom.tests;
18aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
1932dd7c331c5b4dc475d96b113a052286973f78fcIhab Awad
20d0fe76e8e74ac515cacc492fa2c783cf2247ac05Brad Ebingerimport static org.mockito.ArgumentMatchers.nullable;
2192694519535c54f542b4ef3973e9c1934f2feeffSantos Cordonimport static org.mockito.Matchers.any;
2292694519535c54f542b4ef3973e9c1934f2feeffSantos Cordonimport static org.mockito.Matchers.anyBoolean;
2392694519535c54f542b4ef3973e9c1934f2feeffSantos Cordonimport static org.mockito.Matchers.anyInt;
2492694519535c54f542b4ef3973e9c1934f2feeffSantos Cordonimport static org.mockito.Matchers.anyString;
2592694519535c54f542b4ef3973e9c1934f2feeffSantos Cordonimport static org.mockito.Matchers.eq;
26c6e42ef0465fe01b35bb3aa94fbcbc081e3b45edAbhijith Shastryimport static org.mockito.Matchers.isNull;
278fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liuimport static org.mockito.Mockito.doAnswer;
2893dc55f22d5bab2b552f9e28c14fb0cd49814d52Tyler Gunnimport static org.mockito.Mockito.doNothing;
298fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liuimport static org.mockito.Mockito.doReturn;
3092694519535c54f542b4ef3973e9c1934f2feeffSantos Cordonimport static org.mockito.Mockito.mock;
311b5490ac8643a5969adaba6f68d872acd251d666Ihab Awadimport static org.mockito.Mockito.reset;
32ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunnimport static org.mockito.Mockito.spy;
3392694519535c54f542b4ef3973e9c1934f2feeffSantos Cordonimport static org.mockito.Mockito.timeout;
34f7783fb45c262a36d813cb450062d0076490a530Hall Liuimport static org.mockito.Mockito.times;
3592694519535c54f542b4ef3973e9c1934f2feeffSantos Cordonimport static org.mockito.Mockito.verify;
366d4b66df3d918e3f17263ff40ca3ba0ec5a46719Hall Liuimport static org.mockito.Mockito.when;
3792694519535c54f542b4ef3973e9c1934f2feeffSantos Cordon
38eaaf074d6b8b0b16fb922d8d511d6e8b979bfe0dTyler Gunnimport android.app.NotificationManager;
3992694519535c54f542b4ef3973e9c1934f2feeffSantos Cordonimport android.content.BroadcastReceiver;
4092694519535c54f542b4ef3973e9c1934f2feeffSantos Cordonimport android.content.ComponentName;
416d4b66df3d918e3f17263ff40ca3ba0ec5a46719Hall Liuimport android.content.ContentResolver;
4292694519535c54f542b4ef3973e9c1934f2feeffSantos Cordonimport android.content.Context;
43c6e42ef0465fe01b35bb3aa94fbcbc081e3b45edAbhijith Shastryimport android.content.IContentProvider;
4492694519535c54f542b4ef3973e9c1934f2feeffSantos Cordonimport android.content.Intent;
45b60f00673149da9a96d9369f4e1c4458e9a9cf53Ihab Awadimport android.media.AudioManager;
468fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liuimport android.media.IAudioService;
477bba1112556e122254013562650aac6a6af80ac6Brad Ebingerimport android.media.ToneGenerator;
4892694519535c54f542b4ef3973e9c1934f2feeffSantos Cordonimport android.net.Uri;
4992694519535c54f542b4ef3973e9c1934f2feeffSantos Cordonimport android.os.Bundle;
5092694519535c54f542b4ef3973e9c1934f2feeffSantos Cordonimport android.os.Handler;
5184771f8f87f5f582bf848b621eed8c6cd99d41b0Brad Ebingerimport android.os.Looper;
52578a4e6661fc1be20d164458acb335356d742f72Tony Makimport android.os.Process;
5392694519535c54f542b4ef3973e9c1934f2feeffSantos Cordonimport android.os.UserHandle;
54c6e42ef0465fe01b35bb3aa94fbcbc081e3b45edAbhijith Shastryimport android.provider.BlockedNumberContract;
550a4b95fc7731943fdd1a9b295daae45eb46b28d0Ihab Awadimport android.telecom.Call;
5692694519535c54f542b4ef3973e9c1934f2feeffSantos Cordonimport android.telecom.ConnectionRequest;
576e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebingerimport android.telecom.DisconnectCause;
5892694519535c54f542b4ef3973e9c1934f2feeffSantos Cordonimport android.telecom.ParcelableCall;
5992694519535c54f542b4ef3973e9c1934f2feeffSantos Cordonimport android.telecom.PhoneAccount;
6092694519535c54f542b4ef3973e9c1934f2feeffSantos Cordonimport android.telecom.PhoneAccountHandle;
6192694519535c54f542b4ef3973e9c1934f2feeffSantos Cordonimport android.telecom.TelecomManager;
6232dd7c331c5b4dc475d96b113a052286973f78fcIhab Awadimport android.telecom.VideoProfile;
6392694519535c54f542b4ef3973e9c1934f2feeffSantos Cordon
64aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awadimport com.android.internal.telecom.IInCallAdapter;
657ade5e2c3f7a849e41de3b81051c12a8fcd6ea83Brad Ebingerimport com.android.server.telecom.AsyncRingtonePlayer;
66b3979ee8e636820cc5e68f26562bc02987e5d489Hall Liuimport com.android.server.telecom.BluetoothPhoneServiceImpl;
67b7853c0b716f9cc9ae174d1ca4efaa118ef1740eAbhijith Shastryimport com.android.server.telecom.CallAudioManager;
683037ac6f171b6a3627494bb10042ab7adb34366aHall Liuimport com.android.server.telecom.CallerInfoLookupHelper;
692c93c50e5be7d85b78c4af15aaa10e44f0bcdf3eBrad Ebingerimport com.android.server.telecom.CallsManager;
70ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunnimport com.android.server.telecom.CallsManagerListenerBase;
71bcf23de07aed59ed34d0121a76d29b6ed9a14288Tyler Gunnimport com.android.server.telecom.ClockProxy;
727c9283261ad4fdbc5ebbb74257671388f9c758c7Hall Liuimport com.android.server.telecom.DefaultDialerCache;
732c93c50e5be7d85b78c4af15aaa10e44f0bcdf3eBrad Ebingerimport com.android.server.telecom.HeadsetMediaButton;
742c93c50e5be7d85b78c4af15aaa10e44f0bcdf3eBrad Ebingerimport com.android.server.telecom.HeadsetMediaButtonFactory;
752c93c50e5be7d85b78c4af15aaa10e44f0bcdf3eBrad Ebingerimport com.android.server.telecom.InCallWakeLockController;
762c93c50e5be7d85b78c4af15aaa10e44f0bcdf3eBrad Ebingerimport com.android.server.telecom.InCallWakeLockControllerFactory;
772c93c50e5be7d85b78c4af15aaa10e44f0bcdf3eBrad Ebingerimport com.android.server.telecom.MissedCallNotifier;
78b3979ee8e636820cc5e68f26562bc02987e5d489Hall Liuimport com.android.server.telecom.PhoneAccountRegistrar;
796e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebingerimport com.android.server.telecom.PhoneNumberUtilsAdapter;
806e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebingerimport com.android.server.telecom.PhoneNumberUtilsAdapterImpl;
812c93c50e5be7d85b78c4af15aaa10e44f0bcdf3eBrad Ebingerimport com.android.server.telecom.ProximitySensorManager;
822c93c50e5be7d85b78c4af15aaa10e44f0bcdf3eBrad Ebingerimport com.android.server.telecom.ProximitySensorManagerFactory;
832c93c50e5be7d85b78c4af15aaa10e44f0bcdf3eBrad Ebingerimport com.android.server.telecom.TelecomSystem;
846d4b66df3d918e3f17263ff40ca3ba0ec5a46719Hall Liuimport com.android.server.telecom.Timeouts;
85578a4e6661fc1be20d164458acb335356d742f72Tony Makimport com.android.server.telecom.components.UserCallIntentProcessor;
862b17f23d3257dec66d965ac7b4a59aa2226b43a5Tyler Gunnimport com.android.server.telecom.ui.IncomingCallNotifier;
87a993094840386163e9c2aa65a05e14b49d122318Tony Makimport com.android.server.telecom.ui.MissedCallNotifierImpl.MissedCallNotifierImplFactory;
88aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
898fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liuimport com.google.common.base.Predicate;
908fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu
91aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awadimport org.mockito.ArgumentCaptor;
92aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awadimport org.mockito.Mock;
938fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liuimport org.mockito.invocation.InvocationOnMock;
948fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liuimport org.mockito.stubbing.Answer;
95aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
96c6e42ef0465fe01b35bb3aa94fbcbc081e3b45edAbhijith Shastryimport java.util.ArrayList;
97c6e42ef0465fe01b35bb3aa94fbcbc081e3b45edAbhijith Shastryimport java.util.List;
98609992b6d222e54a74cc7e6af06173090103a28aHall Liuimport java.util.concurrent.CountDownLatch;
99609992b6d222e54a74cc7e6af06173090103a28aHall Liuimport java.util.concurrent.TimeUnit;
100c6e42ef0465fe01b35bb3aa94fbcbc081e3b45edAbhijith Shastry
101b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn/**
102b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn * Implements mocks and functionality required to implement telecom system tests.
103b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn */
104aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awadpublic class TelecomSystemTest extends TelecomTestCase {
105aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
10632dd7c331c5b4dc475d96b113a052286973f78fcIhab Awad    static final int TEST_POLL_INTERVAL = 10;  // milliseconds
107aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad    static final int TEST_TIMEOUT = 1000;  // milliseconds
108aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
109bcf23de07aed59ed34d0121a76d29b6ed9a14288Tyler Gunn    // Purposely keep the connect time (which is wall clock) and elapsed time (which is time since
110bcf23de07aed59ed34d0121a76d29b6ed9a14288Tyler Gunn    // boot) different to test that wall clock time operations and elapsed time operations perform
111bcf23de07aed59ed34d0121a76d29b6ed9a14288Tyler Gunn    // as they individually should.
112bcf23de07aed59ed34d0121a76d29b6ed9a14288Tyler Gunn    static final long TEST_CREATE_TIME = 100;
113bcf23de07aed59ed34d0121a76d29b6ed9a14288Tyler Gunn    static final long TEST_CREATE_ELAPSED_TIME = 200;
114bcf23de07aed59ed34d0121a76d29b6ed9a14288Tyler Gunn    static final long TEST_CONNECT_TIME = 1000;
115bcf23de07aed59ed34d0121a76d29b6ed9a14288Tyler Gunn    static final long TEST_CONNECT_ELAPSED_TIME = 2000;
116bcf23de07aed59ed34d0121a76d29b6ed9a14288Tyler Gunn    static final long TEST_DISCONNECT_TIME = 8000;
117bcf23de07aed59ed34d0121a76d29b6ed9a14288Tyler Gunn    static final long TEST_DISCONNECT_ELAPSED_TIME = 4000;
118bcf23de07aed59ed34d0121a76d29b6ed9a14288Tyler Gunn
119ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn    public class HeadsetMediaButtonFactoryF implements HeadsetMediaButtonFactory  {
120ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn        @Override
121ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn        public HeadsetMediaButton create(Context context, CallsManager callsManager,
122ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn                TelecomSystem.SyncRoot lock) {
123ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn            return mHeadsetMediaButton;
124ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn        }
125ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn    }
126ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn
127ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn    public class ProximitySensorManagerFactoryF implements ProximitySensorManagerFactory {
128ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn        @Override
129ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn        public ProximitySensorManager create(Context context, CallsManager callsManager) {
130ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn            return mProximitySensorManager;
131ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn        }
132ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn    }
133ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn
134ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn    public class InCallWakeLockControllerFactoryF implements InCallWakeLockControllerFactory {
135ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn        @Override
136ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn        public InCallWakeLockController create(Context context, CallsManager callsManager) {
137ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn            return mInCallWakeLockController;
138ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn        }
139ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn    }
140ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn
141ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn    public static class MissedCallNotifierFakeImpl extends CallsManagerListenerBase
142ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn            implements MissedCallNotifier {
1433037ac6f171b6a3627494bb10042ab7adb34366aHall Liu        List<CallInfo> missedCallsNotified = new ArrayList<>();
144c6e42ef0465fe01b35bb3aa94fbcbc081e3b45edAbhijith Shastry
145ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn        @Override
146a993094840386163e9c2aa65a05e14b49d122318Tony Mak        public void clearMissedCalls(UserHandle userHandle) {
147ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn
148ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn        }
149ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn
150ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn        @Override
1513037ac6f171b6a3627494bb10042ab7adb34366aHall Liu        public void showMissedCallNotification(CallInfo call) {
152c6e42ef0465fe01b35bb3aa94fbcbc081e3b45edAbhijith Shastry            missedCallsNotified.add(call);
153ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn        }
154ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn
155ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn        @Override
1563037ac6f171b6a3627494bb10042ab7adb34366aHall Liu        public void reloadAfterBootComplete(CallerInfoLookupHelper callerInfoLookupHelper,
1573037ac6f171b6a3627494bb10042ab7adb34366aHall Liu                CallInfoFactory callInfoFactory) { }
158a993094840386163e9c2aa65a05e14b49d122318Tony Mak
1593037ac6f171b6a3627494bb10042ab7adb34366aHall Liu        @Override
1603037ac6f171b6a3627494bb10042ab7adb34366aHall Liu        public void reloadFromDatabase(CallerInfoLookupHelper callerInfoLookupHelper,
1613037ac6f171b6a3627494bb10042ab7adb34366aHall Liu                CallInfoFactory callInfoFactory, UserHandle userHandle) { }
162a993094840386163e9c2aa65a05e14b49d122318Tony Mak
163a993094840386163e9c2aa65a05e14b49d122318Tony Mak        @Override
164a993094840386163e9c2aa65a05e14b49d122318Tony Mak        public void setCurrentUserHandle(UserHandle userHandle) {
165ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn
166ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn        }
167ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn    }
168ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn
169c6e42ef0465fe01b35bb3aa94fbcbc081e3b45edAbhijith Shastry    MissedCallNotifierFakeImpl mMissedCallNotifier = new MissedCallNotifierFakeImpl();
1706e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger    private class EmergencyNumberUtilsAdapter extends PhoneNumberUtilsAdapterImpl {
1716e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger
1726e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        @Override
1736e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        public boolean isLocalEmergencyNumber(Context context, String number) {
1746e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger            return mIsEmergencyCall;
1756e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        }
1766e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger
1776e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        @Override
1786e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        public boolean isPotentialLocalEmergencyNumber(Context context, String number) {
1796e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger            return mIsEmergencyCall;
1806e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        }
1816e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger    }
1827bba1112556e122254013562650aac6a6af80ac6Brad Ebinger
1837bba1112556e122254013562650aac6a6af80ac6Brad Ebinger    private class IncomingCallAddedListener extends CallsManagerListenerBase {
1847bba1112556e122254013562650aac6a6af80ac6Brad Ebinger
1857bba1112556e122254013562650aac6a6af80ac6Brad Ebinger        private final CountDownLatch mCountDownLatch;
1867bba1112556e122254013562650aac6a6af80ac6Brad Ebinger
1877bba1112556e122254013562650aac6a6af80ac6Brad Ebinger        public IncomingCallAddedListener(CountDownLatch latch) {
1887bba1112556e122254013562650aac6a6af80ac6Brad Ebinger            mCountDownLatch = latch;
1897bba1112556e122254013562650aac6a6af80ac6Brad Ebinger        }
1907bba1112556e122254013562650aac6a6af80ac6Brad Ebinger
1917bba1112556e122254013562650aac6a6af80ac6Brad Ebinger        @Override
1927bba1112556e122254013562650aac6a6af80ac6Brad Ebinger        public void onCallAdded(com.android.server.telecom.Call call) {
1937bba1112556e122254013562650aac6a6af80ac6Brad Ebinger            mCountDownLatch.countDown();
1947bba1112556e122254013562650aac6a6af80ac6Brad Ebinger        }
1957bba1112556e122254013562650aac6a6af80ac6Brad Ebinger    }
1967bba1112556e122254013562650aac6a6af80ac6Brad Ebinger
1976e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger    PhoneNumberUtilsAdapter mPhoneNumberUtilsAdapter = new EmergencyNumberUtilsAdapter();
198eaaf074d6b8b0b16fb922d8d511d6e8b979bfe0dTyler Gunn
199aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad    @Mock HeadsetMediaButton mHeadsetMediaButton;
200aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad    @Mock ProximitySensorManager mProximitySensorManager;
201aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad    @Mock InCallWakeLockController mInCallWakeLockController;
202b3979ee8e636820cc5e68f26562bc02987e5d489Hall Liu    @Mock BluetoothPhoneServiceImpl mBluetoothPhoneServiceImpl;
2037ade5e2c3f7a849e41de3b81051c12a8fcd6ea83Brad Ebinger    @Mock AsyncRingtonePlayer mAsyncRingtonePlayer;
2042b17f23d3257dec66d965ac7b4a59aa2226b43a5Tyler Gunn    @Mock IncomingCallNotifier mIncomingCallNotifier;
205bcf23de07aed59ed34d0121a76d29b6ed9a14288Tyler Gunn    @Mock ClockProxy mClockProxy;
206aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
207aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad    final ComponentName mInCallServiceComponentNameX =
208aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad            new ComponentName(
209aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                    "incall-service-package-X",
210aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                    "incall-service-class-X");
211aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad    final ComponentName mInCallServiceComponentNameY =
212aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad            new ComponentName(
213aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                    "incall-service-package-Y",
214aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                    "incall-service-class-Y");
215aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
216aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad    InCallServiceFixture mInCallServiceFixtureX;
217aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad    InCallServiceFixture mInCallServiceFixtureY;
218aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
219aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad    final ComponentName mConnectionServiceComponentNameA =
220aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad            new ComponentName(
221aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                    "connection-service-package-A",
222aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                    "connection-service-class-A");
223aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad    final ComponentName mConnectionServiceComponentNameB =
224aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad            new ComponentName(
225aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                    "connection-service-package-B",
226aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                    "connection-service-class-B");
227aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
228aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad    final PhoneAccount mPhoneAccountA0 =
229aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad            PhoneAccount.builder(
230aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                    new PhoneAccountHandle(
231aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                            mConnectionServiceComponentNameA,
232aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                            "id A 0"),
233aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                    "Phone account service A ID 0")
234aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                    .addSupportedUriScheme("tel")
235aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                    .setCapabilities(
236aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                            PhoneAccount.CAPABILITY_CALL_PROVIDER |
237609992b6d222e54a74cc7e6af06173090103a28aHall Liu                                    PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION |
238609992b6d222e54a74cc7e6af06173090103a28aHall Liu                                    PhoneAccount.CAPABILITY_VIDEO_CALLING)
239aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                    .build();
240aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad    final PhoneAccount mPhoneAccountA1 =
241aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad            PhoneAccount.builder(
242aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                    new PhoneAccountHandle(
243aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                            mConnectionServiceComponentNameA,
244aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                            "id A 1"),
245aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                    "Phone account service A ID 1")
246aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                    .addSupportedUriScheme("tel")
247aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                    .setCapabilities(
248aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                            PhoneAccount.CAPABILITY_CALL_PROVIDER |
249eaaf074d6b8b0b16fb922d8d511d6e8b979bfe0dTyler Gunn                                    PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION |
250eaaf074d6b8b0b16fb922d8d511d6e8b979bfe0dTyler Gunn                                    PhoneAccount.CAPABILITY_VIDEO_CALLING)
251aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                    .build();
252ddec5892dbb532e79fd839f34db43243739f92e8Tyler Gunn    final PhoneAccount mPhoneAccountA2 =
253ddec5892dbb532e79fd839f34db43243739f92e8Tyler Gunn            PhoneAccount.builder(
254ddec5892dbb532e79fd839f34db43243739f92e8Tyler Gunn                    new PhoneAccountHandle(
255ddec5892dbb532e79fd839f34db43243739f92e8Tyler Gunn                            mConnectionServiceComponentNameA,
256ddec5892dbb532e79fd839f34db43243739f92e8Tyler Gunn                            "id A 2"),
257ddec5892dbb532e79fd839f34db43243739f92e8Tyler Gunn                    "Phone account service A ID 2")
258ddec5892dbb532e79fd839f34db43243739f92e8Tyler Gunn                    .addSupportedUriScheme("tel")
259ddec5892dbb532e79fd839f34db43243739f92e8Tyler Gunn                    .setCapabilities(
260ddec5892dbb532e79fd839f34db43243739f92e8Tyler Gunn                            PhoneAccount.CAPABILITY_CALL_PROVIDER |
261ddec5892dbb532e79fd839f34db43243739f92e8Tyler Gunn                                    PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)
262ddec5892dbb532e79fd839f34db43243739f92e8Tyler Gunn                    .build();
263f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn    final PhoneAccount mPhoneAccountSelfManaged =
264f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            PhoneAccount.builder(
265f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                    new PhoneAccountHandle(
266f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                            mConnectionServiceComponentNameA,
267f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                            "id SM"),
268f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                    "Phone account service A SM")
269f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                    .addSupportedUriScheme("tel")
270f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                    .setCapabilities(
271f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                            PhoneAccount.CAPABILITY_SELF_MANAGED)
272f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                    .build();
273aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad    final PhoneAccount mPhoneAccountB0 =
274aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad            PhoneAccount.builder(
275aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                    new PhoneAccountHandle(
2761b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad                            mConnectionServiceComponentNameB,
277aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                            "id B 0"),
278aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                    "Phone account service B ID 0")
279aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                    .addSupportedUriScheme("tel")
280aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                    .setCapabilities(
281aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                            PhoneAccount.CAPABILITY_CALL_PROVIDER |
282eaaf074d6b8b0b16fb922d8d511d6e8b979bfe0dTyler Gunn                                    PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION |
283eaaf074d6b8b0b16fb922d8d511d6e8b979bfe0dTyler Gunn                                    PhoneAccount.CAPABILITY_VIDEO_CALLING)
284aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                    .build();
2856e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger    final PhoneAccount mPhoneAccountE0 =
2866e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger            PhoneAccount.builder(
2876e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger                    new PhoneAccountHandle(
2886e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger                            mConnectionServiceComponentNameA,
2896e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger                            "id E 0"),
2906e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger                    "Phone account service E ID 0")
2916e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger                    .addSupportedUriScheme("tel")
2926e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger                    .setCapabilities(
2936e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger                            PhoneAccount.CAPABILITY_CALL_PROVIDER |
2946e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger                                    PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION |
295d1b36695f77189f008e2de82b4391e5e49048c18Brad Ebinger                                    PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS)
2966e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger                    .build();
2976e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger
2986e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger    final PhoneAccount mPhoneAccountE1 =
2996e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger            PhoneAccount.builder(
3006e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger                    new PhoneAccountHandle(
3016e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger                            mConnectionServiceComponentNameA,
3026e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger                            "id E 1"),
3036e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger                    "Phone account service E ID 1")
3046e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger                    .addSupportedUriScheme("tel")
3056e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger                    .setCapabilities(
3066e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger                            PhoneAccount.CAPABILITY_CALL_PROVIDER |
3076e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger                                    PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION |
308d1b36695f77189f008e2de82b4391e5e49048c18Brad Ebinger                                    PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS)
3096e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger                    .build();
310aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
311aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad    ConnectionServiceFixture mConnectionServiceFixtureA;
312aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad    ConnectionServiceFixture mConnectionServiceFixtureB;
3136d4b66df3d918e3f17263ff40ca3ba0ec5a46719Hall Liu    Timeouts.Adapter mTimeoutsAdapter;
314aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
315abcbce4441720c52a443d292d5adc2d95f446494Ihab Awad    CallerInfoAsyncQueryFactoryFixture mCallerInfoAsyncQueryFactoryFixture;
316abcbce4441720c52a443d292d5adc2d95f446494Ihab Awad
3178fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu    IAudioService mAudioService;
3188fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu
319aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad    TelecomSystem mTelecomSystem;
320aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
321ecda55454f4993003e71e09a63d20f94a216cc47Hall Liu    Context mSpyContext;
322ecda55454f4993003e71e09a63d20f94a216cc47Hall Liu
323f7783fb45c262a36d813cb450062d0076490a530Hall Liu    private int mNumOutgoingCallsMade;
324f7783fb45c262a36d813cb450062d0076490a530Hall Liu
3256e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger    private boolean mIsEmergencyCall;
3266e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger
3271b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad    class IdPair {
3281b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad        final String mConnectionId;
3291b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad        final String mCallId;
3301b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad
3311b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad        public IdPair(String connectionId, String callId) {
3321b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad            this.mConnectionId = connectionId;
3331b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad            this.mCallId = callId;
3341b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad        }
3351b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad    }
3361b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad
337aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad    @Override
338aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad    public void setUp() throws Exception {
339aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        super.setUp();
340ecda55454f4993003e71e09a63d20f94a216cc47Hall Liu        mSpyContext = mComponentContextFixture.getTestDouble().getApplicationContext();
341ecda55454f4993003e71e09a63d20f94a216cc47Hall Liu        doReturn(mSpyContext).when(mSpyContext).getApplicationContext();
34293dc55f22d5bab2b552f9e28c14fb0cd49814d52Tyler Gunn        doNothing().when(mSpyContext).sendBroadcastAsUser(any(), any(), any());
343ecda55454f4993003e71e09a63d20f94a216cc47Hall Liu
344f7783fb45c262a36d813cb450062d0076490a530Hall Liu        mNumOutgoingCallsMade = 0;
345aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
3466e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        mIsEmergencyCall = false;
3476e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger
348aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        // First set up information about the In-Call services in the mock Context, since
349aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        // Telecom will search for these as soon as it is instantiated
350aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        setupInCallServices();
351aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
352aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        // Next, create the TelecomSystem, our system under test
353aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        setupTelecomSystem();
354aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
355aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        // Finally, register the ConnectionServices with the PhoneAccountRegistrar of the
356aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        // now-running TelecomSystem
357aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        setupConnectionServices();
3587bba1112556e122254013562650aac6a6af80ac6Brad Ebinger
3597bba1112556e122254013562650aac6a6af80ac6Brad Ebinger        waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
360aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad    }
361aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
362aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad    @Override
363aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad    public void tearDown() throws Exception {
364486cb197d4426a0f740b1c73ba3acdc76b3d67d3Hall Liu        mTelecomSystem.getCallsManager().getCallAudioManager()
365486cb197d4426a0f740b1c73ba3acdc76b3d67d3Hall Liu                .getCallAudioRouteStateMachine().quitNow();
366486cb197d4426a0f740b1c73ba3acdc76b3d67d3Hall Liu        mTelecomSystem.getCallsManager().getCallAudioManager()
367486cb197d4426a0f740b1c73ba3acdc76b3d67d3Hall Liu                .getCallAudioModeStateMachine().quitNow();
368aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        mTelecomSystem = null;
369aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        super.tearDown();
370aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad    }
371aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
372961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn    protected ParcelableCall makeConferenceCall() throws Exception {
373961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn        IdPair callId1 = startAndMakeActiveOutgoingCall("650-555-1212",
374961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn                mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
375961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn
376961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn        IdPair callId2 = startAndMakeActiveOutgoingCall("650-555-1213",
377961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn                mPhoneAccountA0.getAccountHandle(), mConnectionServiceFixtureA);
378961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn
379961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn        IInCallAdapter inCallAdapter = mInCallServiceFixtureX.getInCallAdapter();
380961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn        inCallAdapter.conference(callId1.mCallId, callId2.mCallId);
381961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn        // Wait for wacky non-deterministic behavior
382961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn        Thread.sleep(200);
383961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn        ParcelableCall call1 = mInCallServiceFixtureX.getCall(callId1.mCallId);
384961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn        ParcelableCall call2 = mInCallServiceFixtureX.getCall(callId2.mCallId);
385961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn        // Check that the two calls end up with a parent in the end
386961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn        assertNotNull(call1.getParentCallId());
387961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn        assertNotNull(call2.getParentCallId());
388961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn        assertEquals(call1.getParentCallId(), call2.getParentCallId());
389961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn
390961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn        // Check to make sure that the parent call made it to the in-call service
391961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn        String parentCallId = call1.getParentCallId();
392961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn        ParcelableCall conferenceCall = mInCallServiceFixtureX.getCall(parentCallId);
393961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn        assertEquals(2, conferenceCall.getChildCallIds().size());
394961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn        assertTrue(conferenceCall.getChildCallIds().contains(callId1.mCallId));
395961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn        assertTrue(conferenceCall.getChildCallIds().contains(callId2.mCallId));
396961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn        return conferenceCall;
397961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn    }
398961694a9750626c067be960170bc95f10b5efcc2Tyler Gunn
399aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad    private void setupTelecomSystem() throws Exception {
400ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn        // Use actual implementations instead of mocking the interface out.
401aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        HeadsetMediaButtonFactory headsetMediaButtonFactory =
402ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn                spy(new HeadsetMediaButtonFactoryF());
403aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        ProximitySensorManagerFactory proximitySensorManagerFactory =
404ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn                spy(new ProximitySensorManagerFactoryF());
405aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        InCallWakeLockControllerFactory inCallWakeLockControllerFactory =
406ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn                spy(new InCallWakeLockControllerFactoryF());
4078fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu        mAudioService = setupAudioService();
408aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
409abcbce4441720c52a443d292d5adc2d95f446494Ihab Awad        mCallerInfoAsyncQueryFactoryFixture = new CallerInfoAsyncQueryFactoryFixture();
410abcbce4441720c52a443d292d5adc2d95f446494Ihab Awad
4116d4b66df3d918e3f17263ff40ca3ba0ec5a46719Hall Liu        mTimeoutsAdapter = mock(Timeouts.Adapter.class);
4126d4b66df3d918e3f17263ff40ca3ba0ec5a46719Hall Liu        when(mTimeoutsAdapter.getCallScreeningTimeoutMillis(any(ContentResolver.class)))
413609992b6d222e54a74cc7e6af06173090103a28aHall Liu                .thenReturn(TEST_TIMEOUT / 5L);
4142b17f23d3257dec66d965ac7b4a59aa2226b43a5Tyler Gunn        mIncomingCallNotifier = mock(IncomingCallNotifier.class);
415bcf23de07aed59ed34d0121a76d29b6ed9a14288Tyler Gunn        mClockProxy = mock(ClockProxy.class);
416bcf23de07aed59ed34d0121a76d29b6ed9a14288Tyler Gunn        when(mClockProxy.currentTimeMillis()).thenReturn(TEST_CREATE_TIME);
417bcf23de07aed59ed34d0121a76d29b6ed9a14288Tyler Gunn        when(mClockProxy.elapsedRealtime()).thenReturn(TEST_CREATE_ELAPSED_TIME);
418aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        mTelecomSystem = new TelecomSystem(
419aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                mComponentContextFixture.getTestDouble(),
420a993094840386163e9c2aa65a05e14b49d122318Tony Mak                new MissedCallNotifierImplFactory() {
421a993094840386163e9c2aa65a05e14b49d122318Tony Mak                    @Override
422a993094840386163e9c2aa65a05e14b49d122318Tony Mak                    public MissedCallNotifier makeMissedCallNotifierImpl(Context context,
4237c9283261ad4fdbc5ebbb74257671388f9c758c7Hall Liu                            PhoneAccountRegistrar phoneAccountRegistrar,
4247c9283261ad4fdbc5ebbb74257671388f9c758c7Hall Liu                            DefaultDialerCache defaultDialerCache) {
425a993094840386163e9c2aa65a05e14b49d122318Tony Mak                        return mMissedCallNotifier;
426a993094840386163e9c2aa65a05e14b49d122318Tony Mak                    }
427a993094840386163e9c2aa65a05e14b49d122318Tony Mak                },
428abcbce4441720c52a443d292d5adc2d95f446494Ihab Awad                mCallerInfoAsyncQueryFactoryFixture.getTestDouble(),
429aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                headsetMediaButtonFactory,
430aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                proximitySensorManagerFactory,
4318fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu                inCallWakeLockControllerFactory,
4328fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu                new CallAudioManager.AudioServiceFactory() {
4338fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu                    @Override
4348fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu                    public IAudioService getAudioService() {
4358fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu                        return mAudioService;
4368fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu                    }
437b3979ee8e636820cc5e68f26562bc02987e5d489Hall Liu                },
438b3979ee8e636820cc5e68f26562bc02987e5d489Hall Liu                new BluetoothPhoneServiceImpl.BluetoothPhoneServiceImplFactory() {
439b3979ee8e636820cc5e68f26562bc02987e5d489Hall Liu                    @Override
440b3979ee8e636820cc5e68f26562bc02987e5d489Hall Liu                    public BluetoothPhoneServiceImpl makeBluetoothPhoneServiceImpl(Context context,
441b3979ee8e636820cc5e68f26562bc02987e5d489Hall Liu                            TelecomSystem.SyncRoot lock, CallsManager callsManager,
442b3979ee8e636820cc5e68f26562bc02987e5d489Hall Liu                            PhoneAccountRegistrar phoneAccountRegistrar) {
443b3979ee8e636820cc5e68f26562bc02987e5d489Hall Liu                        return mBluetoothPhoneServiceImpl;
444b3979ee8e636820cc5e68f26562bc02987e5d489Hall Liu                    }
4457ade5e2c3f7a849e41de3b81051c12a8fcd6ea83Brad Ebinger                },
4466d4b66df3d918e3f17263ff40ca3ba0ec5a46719Hall Liu                mTimeoutsAdapter,
4476e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger                mAsyncRingtonePlayer,
448eaaf074d6b8b0b16fb922d8d511d6e8b979bfe0dTyler Gunn                mPhoneNumberUtilsAdapter,
4497bba1112556e122254013562650aac6a6af80ac6Brad Ebinger                mIncomingCallNotifier,
450bcf23de07aed59ed34d0121a76d29b6ed9a14288Tyler Gunn                (streamType, volume) -> mock(ToneGenerator.class),
451bcf23de07aed59ed34d0121a76d29b6ed9a14288Tyler Gunn                mClockProxy);
452aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
4531d903ddbf915a4aef4925a0e90042e76151c97a9Hall Liu        mComponentContextFixture.setTelecomManager(new TelecomManager(
4541d903ddbf915a4aef4925a0e90042e76151c97a9Hall Liu                mComponentContextFixture.getTestDouble(),
4551d903ddbf915a4aef4925a0e90042e76151c97a9Hall Liu                mTelecomSystem.getTelecomServiceImpl().getBinder()));
4561d903ddbf915a4aef4925a0e90042e76151c97a9Hall Liu
457aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        verify(headsetMediaButtonFactory).create(
458aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                eq(mComponentContextFixture.getTestDouble().getApplicationContext()),
459731369c3983628e700f161138fe2ea3230033a1aIhab Awad                any(CallsManager.class),
460731369c3983628e700f161138fe2ea3230033a1aIhab Awad                any(TelecomSystem.SyncRoot.class));
461aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        verify(proximitySensorManagerFactory).create(
462aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                eq(mComponentContextFixture.getTestDouble().getApplicationContext()),
463aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                any(CallsManager.class));
464aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        verify(inCallWakeLockControllerFactory).create(
465aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                eq(mComponentContextFixture.getTestDouble().getApplicationContext()),
466aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                any(CallsManager.class));
467aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad    }
468aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
469aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad    private void setupConnectionServices() throws Exception {
470aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        mConnectionServiceFixtureA = new ConnectionServiceFixture();
471aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        mConnectionServiceFixtureB = new ConnectionServiceFixture();
472aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
473b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn        mComponentContextFixture.addConnectionService(mConnectionServiceComponentNameA,
474aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                mConnectionServiceFixtureA.getTestDouble());
475b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn        mComponentContextFixture.addConnectionService(mConnectionServiceComponentNameB,
476aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                mConnectionServiceFixtureB.getTestDouble());
477aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
478aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        mTelecomSystem.getPhoneAccountRegistrar().registerPhoneAccount(mPhoneAccountA0);
479aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        mTelecomSystem.getPhoneAccountRegistrar().registerPhoneAccount(mPhoneAccountA1);
480ddec5892dbb532e79fd839f34db43243739f92e8Tyler Gunn        mTelecomSystem.getPhoneAccountRegistrar().registerPhoneAccount(mPhoneAccountA2);
481f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn        mTelecomSystem.getPhoneAccountRegistrar().registerPhoneAccount(mPhoneAccountSelfManaged);
482aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        mTelecomSystem.getPhoneAccountRegistrar().registerPhoneAccount(mPhoneAccountB0);
4836e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        mTelecomSystem.getPhoneAccountRegistrar().registerPhoneAccount(mPhoneAccountE0);
4846e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        mTelecomSystem.getPhoneAccountRegistrar().registerPhoneAccount(mPhoneAccountE1);
4850a4b95fc7731943fdd1a9b295daae45eb46b28d0Ihab Awad
4860a4b95fc7731943fdd1a9b295daae45eb46b28d0Ihab Awad        mTelecomSystem.getPhoneAccountRegistrar().setUserSelectedOutgoingPhoneAccount(
4874a3e2fd2b783c9f667a719237ef527ebe686fe32Tony Mak                mPhoneAccountA0.getAccountHandle(), Process.myUserHandle());
488aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad    }
489aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
490aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad    private void setupInCallServices() throws Exception {
491aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        mComponentContextFixture.putResource(
492aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                com.android.server.telecom.R.string.ui_default_package,
493aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                mInCallServiceComponentNameX.getPackageName());
494aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        mComponentContextFixture.putResource(
495aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                com.android.server.telecom.R.string.incall_default_class,
496aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                mInCallServiceComponentNameX.getClassName());
497f4745b6a7d110d6a9d23fe6c385dc1e3d7c6c2f4Brad Ebinger        mComponentContextFixture.putBooleanResource(
498f4745b6a7d110d6a9d23fe6c385dc1e3d7c6c2f4Brad Ebinger                com.android.internal.R.bool.config_voice_capable, true);
499aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
500aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        mInCallServiceFixtureX = new InCallServiceFixture();
501aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        mInCallServiceFixtureY = new InCallServiceFixture();
502aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
503b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn        mComponentContextFixture.addInCallService(mInCallServiceComponentNameX,
504aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                mInCallServiceFixtureX.getTestDouble());
505b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn        mComponentContextFixture.addInCallService(mInCallServiceComponentNameY,
506aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                mInCallServiceFixtureY.getTestDouble());
507aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad    }
508aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
5098fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu    /**
5108fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu     * Helper method for setting up the fake audio service.
5118fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu     * Calls to the fake audio service need to toggle the return
5128fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu     * value of AudioManager#isMicrophoneMute.
5138fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu     * @return mock of IAudioService
5148fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu     */
5158fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu    private IAudioService setupAudioService() {
5168fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu        IAudioService audioService = mock(IAudioService.class);
517ae694b10e9156cfe0c8c57d73989fed13c887f69Tyler Gunn
5188fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu        final AudioManager fakeAudioManager =
5198fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu                (AudioManager) mComponentContextFixture.getTestDouble()
5208fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu                        .getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
5218fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu
5228fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu        try {
5238fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu            doAnswer(new Answer() {
5248fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu                @Override
5258fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu                public Object answer(InvocationOnMock i) {
5268fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu                    Object[] args = i.getArguments();
5278fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu                    doReturn(args[0]).when(fakeAudioManager).isMicrophoneMute();
5288fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu                    return null;
5298fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu                }
5308fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu            }).when(audioService)
5318fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu                    .setMicrophoneMute(any(Boolean.class), any(String.class), any(Integer.class));
5328fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu
5338fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu        } catch (android.os.RemoteException e) {
5348fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu            // Do nothing, leave the faked microphone state as-is
5358fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu        }
5368fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu        return audioService;
5378fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu    }
5388fb1fb72b084a0497a3c3c3037ce5667bde14482Hall Liu
539c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger    protected String startOutgoingPhoneCallWithNoPhoneAccount(String number,
540c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger            ConnectionServiceFixture connectionServiceFixture)
541c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger            throws Exception {
542c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger
543c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger        return startOutgoingPhoneCallPendingCreateConnection(number, null,
544c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger                connectionServiceFixture, Process.myUserHandle(), VideoProfile.STATE_AUDIO_ONLY);
545c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger    }
546c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger
547c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger    protected IdPair outgoingCallPhoneAccountSelected(PhoneAccountHandle phoneAccountHandle,
548c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger            int startingNumConnections, int startingNumCalls,
549c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger            ConnectionServiceFixture connectionServiceFixture) throws Exception {
550c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger
551c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger        IdPair ids = outgoingCallCreateConnectionComplete(startingNumConnections, startingNumCalls,
552c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger                phoneAccountHandle, connectionServiceFixture);
553c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger
554c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger        connectionServiceFixture.sendSetDialing(ids.mConnectionId);
555c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger        assertEquals(Call.STATE_DIALING, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
556c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger        assertEquals(Call.STATE_DIALING, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
557c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger
558c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger        connectionServiceFixture.sendSetVideoState(ids.mConnectionId);
559c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger
560c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger        connectionServiceFixture.sendSetActive(ids.mConnectionId);
561c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger        assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
562c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger        assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
563c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger
564c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger        return ids;
565c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger    }
566c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger
567b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn    protected IdPair startOutgoingPhoneCall(String number, PhoneAccountHandle phoneAccountHandle,
568b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn            ConnectionServiceFixture connectionServiceFixture, UserHandle initiatingUser)
569b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn            throws Exception {
570c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger
571b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn        return startOutgoingPhoneCall(number, phoneAccountHandle, connectionServiceFixture,
572b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn                initiatingUser, VideoProfile.STATE_AUDIO_ONLY);
573b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn    }
574b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn
575b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn    protected IdPair startOutgoingPhoneCall(String number, PhoneAccountHandle phoneAccountHandle,
576b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn            ConnectionServiceFixture connectionServiceFixture, UserHandle initiatingUser,
577b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn            int videoState) throws Exception {
578c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger        int startingNumConnections = connectionServiceFixture.mConnectionById.size();
579c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger        int startingNumCalls = mInCallServiceFixtureX.mCallById.size();
580c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger
581c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger        startOutgoingPhoneCallPendingCreateConnection(number, phoneAccountHandle,
582c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger                connectionServiceFixture, initiatingUser, videoState);
583c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger
584c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger        return outgoingCallCreateConnectionComplete(startingNumConnections, startingNumCalls,
585c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger                phoneAccountHandle, connectionServiceFixture);
586c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger    }
587c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger
5886e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger    protected IdPair triggerEmergencyRedial(PhoneAccountHandle phoneAccountHandle,
5896e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger            ConnectionServiceFixture connectionServiceFixture, IdPair emergencyIds)
5906e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger            throws Exception {
5916e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        int startingNumConnections = connectionServiceFixture.mConnectionById.size();
5926e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        int startingNumCalls = mInCallServiceFixtureX.mCallById.size();
5936e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger
5946e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        // Send the message to disconnect the Emergency call due to an error.
5956e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        // CreateConnectionProcessor should now try the second SIM account
5966e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        connectionServiceFixture.sendSetDisconnected(emergencyIds.mConnectionId,
5976e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger                DisconnectCause.ERROR);
5986e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
5996e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        assertEquals(Call.STATE_DIALING, mInCallServiceFixtureX.getCall(
6006e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger                emergencyIds.mCallId).getState());
6016e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        assertEquals(Call.STATE_DIALING, mInCallServiceFixtureY.getCall(
6026e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger                emergencyIds.mCallId).getState());
6036e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger
6046e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        return redialingCallCreateConnectionComplete(startingNumConnections, startingNumCalls,
6056e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger                phoneAccountHandle, connectionServiceFixture);
6066e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger    }
6076e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger
6086e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger    protected IdPair startOutgoingEmergencyCall(String number,
609c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger            PhoneAccountHandle phoneAccountHandle,
610c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger            ConnectionServiceFixture connectionServiceFixture, UserHandle initiatingUser,
611c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger            int videoState) throws Exception {
6126e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        int startingNumConnections = connectionServiceFixture.mConnectionById.size();
6136e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        int startingNumCalls = mInCallServiceFixtureX.mCallById.size();
6146e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger
6156e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        mIsEmergencyCall = true;
6166e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        // Call will not use the ordered broadcaster, since it is an Emergency Call
6176e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        startOutgoingPhoneCallWaitForBroadcaster(number, phoneAccountHandle,
6186e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger                connectionServiceFixture, initiatingUser, videoState, true /*isEmergency*/);
6196e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger
6206e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        return outgoingCallCreateConnectionComplete(startingNumConnections, startingNumCalls,
6216e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger                phoneAccountHandle, connectionServiceFixture);
6226e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger    }
6236e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger
6246e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger    protected void startOutgoingPhoneCallWaitForBroadcaster(String number,
6256e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger            PhoneAccountHandle phoneAccountHandle,
6266e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger            ConnectionServiceFixture connectionServiceFixture, UserHandle initiatingUser,
6276e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger            int videoState, boolean isEmergency) throws Exception {
628b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn        reset(connectionServiceFixture.getTestDouble(), mInCallServiceFixtureX.getTestDouble(),
6291b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad                mInCallServiceFixtureY.getTestDouble());
6301b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad
631b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn        assertEquals(mInCallServiceFixtureX.mCallById.size(),
6321b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad                mInCallServiceFixtureY.mCallById.size());
633b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn        assertEquals((mInCallServiceFixtureX.mInCallAdapter != null),
6341b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad                (mInCallServiceFixtureY.mInCallAdapter != null));
6351b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad
636f7783fb45c262a36d813cb450062d0076490a530Hall Liu        mNumOutgoingCallsMade++;
637c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger
6381b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad        boolean hasInCallAdapter = mInCallServiceFixtureX.mInCallAdapter != null;
6391b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad
640aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        Intent actionCallIntent = new Intent();
641aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        actionCallIntent.setData(Uri.parse("tel:" + number));
642aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        actionCallIntent.putExtra(Intent.EXTRA_PHONE_NUMBER, number);
6436e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        if(isEmergency) {
6446e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger            actionCallIntent.setAction(Intent.ACTION_CALL_EMERGENCY);
6456e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        } else {
6466e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger            actionCallIntent.setAction(Intent.ACTION_CALL);
6476e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        }
648aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        if (phoneAccountHandle != null) {
649aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad            actionCallIntent.putExtra(
650aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                    TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
651aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                    phoneAccountHandle);
652aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        }
653b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn        if (videoState != VideoProfile.STATE_AUDIO_ONLY) {
654b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn            actionCallIntent.putExtra(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, videoState);
655b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn        }
656aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
657578a4e6661fc1be20d164458acb335356d742f72Tony Mak        final UserHandle userHandle = initiatingUser;
658f4745b6a7d110d6a9d23fe6c385dc1e3d7c6c2f4Brad Ebinger        Context localAppContext = mComponentContextFixture.getTestDouble().getApplicationContext();
659f4745b6a7d110d6a9d23fe6c385dc1e3d7c6c2f4Brad Ebinger        new UserCallIntentProcessor(localAppContext, userHandle).processIntent(
660f4745b6a7d110d6a9d23fe6c385dc1e3d7c6c2f4Brad Ebinger                actionCallIntent, null, true /* hasCallAppOp*/);
661f4745b6a7d110d6a9d23fe6c385dc1e3d7c6c2f4Brad Ebinger        // UserCallIntentProcessor's mContext.sendBroadcastAsUser(...) will call to an empty method
662f4745b6a7d110d6a9d23fe6c385dc1e3d7c6c2f4Brad Ebinger        // as to not actually try to send an intent to PrimaryCallReceiver. We verify that it was
663f4745b6a7d110d6a9d23fe6c385dc1e3d7c6c2f4Brad Ebinger        // called correctly in order to continue.
664f4745b6a7d110d6a9d23fe6c385dc1e3d7c6c2f4Brad Ebinger        verify(localAppContext).sendBroadcastAsUser(actionCallIntent, UserHandle.SYSTEM);
665aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        mTelecomSystem.getCallIntentProcessor().processIntent(actionCallIntent);
666c37ddf1546a8270c8293bbd520b3fc225cd72181Brad Ebinger        // Wait for handler to start CallerInfo lookup.
667c37ddf1546a8270c8293bbd520b3fc225cd72181Brad Ebinger        waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
668c37ddf1546a8270c8293bbd520b3fc225cd72181Brad Ebinger        // Send the CallerInfo lookup reply.
669c37ddf1546a8270c8293bbd520b3fc225cd72181Brad Ebinger        mCallerInfoAsyncQueryFactoryFixture.mRequests.forEach(
670c37ddf1546a8270c8293bbd520b3fc225cd72181Brad Ebinger                CallerInfoAsyncQueryFactoryFixture.Request::reply);
671aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
672f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn        boolean isSelfManaged = phoneAccountHandle == mPhoneAccountSelfManaged.getAccountHandle();
673f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn        if (!hasInCallAdapter && !isSelfManaged) {
6741b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad            verify(mInCallServiceFixtureX.getTestDouble())
6751b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad                    .setInCallAdapter(
6761b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad                            any(IInCallAdapter.class));
6771b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad            verify(mInCallServiceFixtureY.getTestDouble())
6781b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad                    .setInCallAdapter(
6791b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad                            any(IInCallAdapter.class));
6801b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad        }
6816e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger    }
6826e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger
6836e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger    protected String startOutgoingPhoneCallPendingCreateConnection(String number,
6846e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger            PhoneAccountHandle phoneAccountHandle,
6856e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger            ConnectionServiceFixture connectionServiceFixture, UserHandle initiatingUser,
6866e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger            int videoState) throws Exception {
6876e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        startOutgoingPhoneCallWaitForBroadcaster(number,phoneAccountHandle,
6886e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger                connectionServiceFixture, initiatingUser, videoState, false /*isEmergency*/);
6891b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad
690aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        ArgumentCaptor<Intent> newOutgoingCallIntent =
691aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                ArgumentCaptor.forClass(Intent.class);
692aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        ArgumentCaptor<BroadcastReceiver> newOutgoingCallReceiver =
693aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                ArgumentCaptor.forClass(BroadcastReceiver.class);
694aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
695f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn        if (phoneAccountHandle != mPhoneAccountSelfManaged.getAccountHandle()) {
696f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            verify(mComponentContextFixture.getTestDouble().getApplicationContext(),
697f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                    times(mNumOutgoingCallsMade))
698f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                    .sendOrderedBroadcastAsUser(
699f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                            newOutgoingCallIntent.capture(),
700f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                            any(UserHandle.class),
701f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                            anyString(),
702f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                            anyInt(),
703f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                            newOutgoingCallReceiver.capture(),
704f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                            nullable(Handler.class),
705f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                            anyInt(),
706f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                            anyString(),
707f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                            nullable(Bundle.class));
708f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            // Pass on the new outgoing call Intent
709f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            // Set a dummy PendingResult so the BroadcastReceiver agrees to accept onReceive()
710f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            newOutgoingCallReceiver.getValue().setPendingResult(
711f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                    new BroadcastReceiver.PendingResult(0, "", null, 0, true, false, null, 0, 0));
712f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            newOutgoingCallReceiver.getValue().setResultData(
713f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                    newOutgoingCallIntent.getValue().getStringExtra(Intent.EXTRA_PHONE_NUMBER));
714f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            newOutgoingCallReceiver.getValue().onReceive(mComponentContextFixture.getTestDouble(),
715f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                    newOutgoingCallIntent.getValue());
716f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn        }
717aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
718c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger        return mInCallServiceFixtureX.mLatestCallId;
719c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger    }
720c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger
7216e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger    // When Telecom is redialing due to an error, we need to make sure the number of connections
7226e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger    // increase, but not the number of Calls in the InCallService.
7236e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger    protected IdPair redialingCallCreateConnectionComplete(int startingNumConnections,
7246e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger            int startingNumCalls, PhoneAccountHandle phoneAccountHandle,
7256e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger            ConnectionServiceFixture connectionServiceFixture) throws Exception {
7266e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger
7276e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        assertEquals(startingNumConnections + 1, connectionServiceFixture.mConnectionById.size());
7286e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger
7296e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        verify(connectionServiceFixture.getTestDouble())
7306e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger                .createConnection(eq(phoneAccountHandle), anyString(), any(ConnectionRequest.class),
731b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger                        eq(false)/*isIncoming*/, anyBoolean(), any());
7326e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        // Wait for handleCreateConnectionComplete
7336e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
7346e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger
7356e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        // Make sure the number of registered InCallService Calls stays the same.
7366e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        assertEquals(startingNumCalls, mInCallServiceFixtureX.mCallById.size());
7376e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        assertEquals(startingNumCalls, mInCallServiceFixtureY.mCallById.size());
7386e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger
7396e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        assertEquals(mInCallServiceFixtureX.mLatestCallId, mInCallServiceFixtureY.mLatestCallId);
7406e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger
7416e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        return new IdPair(connectionServiceFixture.mLatestConnectionId,
7426e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger                mInCallServiceFixtureX.mLatestCallId);
7436e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger    }
7446e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger
745c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger    protected IdPair outgoingCallCreateConnectionComplete(int startingNumConnections,
746c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger            int startingNumCalls, PhoneAccountHandle phoneAccountHandle,
747c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger            ConnectionServiceFixture connectionServiceFixture) throws Exception {
748c301b5128cf40a1fa5a9c0839d405afaa5747112Brad Ebinger
7491b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad        assertEquals(startingNumConnections + 1, connectionServiceFixture.mConnectionById.size());
7501b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad
751b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn        verify(connectionServiceFixture.getTestDouble())
752b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn                .createConnection(eq(phoneAccountHandle), anyString(), any(ConnectionRequest.class),
753b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger                        eq(false)/*isIncoming*/, anyBoolean(), any());
75484771f8f87f5f582bf848b621eed8c6cd99d41b0Brad Ebinger        // Wait for handleCreateConnectionComplete
75584771f8f87f5f582bf848b621eed8c6cd99d41b0Brad Ebinger        waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
756b3ce510a9392230d003e2b740affab476c78f74fHall Liu        // Wait for the callback in ConnectionService#onAdapterAttached to execute.
757b3ce510a9392230d003e2b740affab476c78f74fHall Liu        waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
758aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
759ddb03e1387a09f9c7da624b064bf4f5b90ed478cTyler Gunn        // Ensure callback to CS on successful creation happened.
760ddb03e1387a09f9c7da624b064bf4f5b90ed478cTyler Gunn        verify(connectionServiceFixture.getTestDouble(), timeout(TEST_TIMEOUT))
761ddb03e1387a09f9c7da624b064bf4f5b90ed478cTyler Gunn                .createConnectionComplete(anyString(), any());
762ddb03e1387a09f9c7da624b064bf4f5b90ed478cTyler Gunn
763f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn        if (phoneAccountHandle == mPhoneAccountSelfManaged.getAccountHandle()) {
764f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            assertEquals(startingNumCalls, mInCallServiceFixtureX.mCallById.size());
765f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            assertEquals(startingNumCalls, mInCallServiceFixtureY.mCallById.size());
766f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn        } else {
767f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            assertEquals(startingNumCalls + 1, mInCallServiceFixtureX.mCallById.size());
768f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            assertEquals(startingNumCalls + 1, mInCallServiceFixtureY.mCallById.size());
769f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn        }
770aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
771b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn        assertEquals(mInCallServiceFixtureX.mLatestCallId, mInCallServiceFixtureY.mLatestCallId);
7721b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad
773b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn        return new IdPair(connectionServiceFixture.mLatestConnectionId,
7741b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad                mInCallServiceFixtureX.mLatestCallId);
775aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad    }
776aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
777b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn    protected IdPair startIncomingPhoneCall(
778aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad            String number,
779aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad            PhoneAccountHandle phoneAccountHandle,
78032dd7c331c5b4dc475d96b113a052286973f78fcIhab Awad            final ConnectionServiceFixture connectionServiceFixture) throws Exception {
78142ef808c284791f21be8675174acc7297418fa45Tyler Gunn        return startIncomingPhoneCall(number, phoneAccountHandle, VideoProfile.STATE_AUDIO_ONLY,
78242ef808c284791f21be8675174acc7297418fa45Tyler Gunn                connectionServiceFixture);
78342ef808c284791f21be8675174acc7297418fa45Tyler Gunn    }
78442ef808c284791f21be8675174acc7297418fa45Tyler Gunn
785b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn    protected IdPair startIncomingPhoneCall(
78642ef808c284791f21be8675174acc7297418fa45Tyler Gunn            String number,
78742ef808c284791f21be8675174acc7297418fa45Tyler Gunn            PhoneAccountHandle phoneAccountHandle,
78842ef808c284791f21be8675174acc7297418fa45Tyler Gunn            int videoState,
78942ef808c284791f21be8675174acc7297418fa45Tyler Gunn            final ConnectionServiceFixture connectionServiceFixture) throws Exception {
790b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn        reset(connectionServiceFixture.getTestDouble(), mInCallServiceFixtureX.getTestDouble(),
7911b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad                mInCallServiceFixtureY.getTestDouble());
7921b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad
793b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn        assertEquals(mInCallServiceFixtureX.mCallById.size(),
7941b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad                mInCallServiceFixtureY.mCallById.size());
795b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn        assertEquals((mInCallServiceFixtureX.mInCallAdapter != null),
7961b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad                (mInCallServiceFixtureY.mInCallAdapter != null));
79732dd7c331c5b4dc475d96b113a052286973f78fcIhab Awad        final int startingNumConnections = connectionServiceFixture.mConnectionById.size();
79832dd7c331c5b4dc475d96b113a052286973f78fcIhab Awad        final int startingNumCalls = mInCallServiceFixtureX.mCallById.size();
7991b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad        boolean hasInCallAdapter = mInCallServiceFixtureX.mInCallAdapter != null;
800b7853c0b716f9cc9ae174d1ca4efaa118ef1740eAbhijith Shastry        connectionServiceFixture.mConnectionServiceDelegate.mVideoState = videoState;
8017bba1112556e122254013562650aac6a6af80ac6Brad Ebinger        CountDownLatch incomingCallAddedLatch = new CountDownLatch(1);
8027bba1112556e122254013562650aac6a6af80ac6Brad Ebinger        IncomingCallAddedListener callAddedListener =
8037bba1112556e122254013562650aac6a6af80ac6Brad Ebinger                new IncomingCallAddedListener(incomingCallAddedLatch);
8047bba1112556e122254013562650aac6a6af80ac6Brad Ebinger        mTelecomSystem.getCallsManager().addListener(callAddedListener);
8051b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad
806aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        Bundle extras = new Bundle();
807aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        extras.putParcelable(
80869fa89790a67c497f091c86a9b1ed5a00aace7aeYorke Lee                TelecomManager.EXTRA_INCOMING_CALL_ADDRESS,
809aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                Uri.fromParts(PhoneAccount.SCHEME_TEL, number, null));
810aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        mTelecomSystem.getTelecomServiceImpl().getBinder()
811aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad                .addNewIncomingCall(phoneAccountHandle, extras);
812aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
813b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn        verify(connectionServiceFixture.getTestDouble())
814b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn                .createConnection(any(PhoneAccountHandle.class), anyString(),
815b78b0234c6e9a937fc00fec6d16e534535b6fab9Brad Ebinger                        any(ConnectionRequest.class), eq(true), eq(false), any());
816aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
817c37ddf1546a8270c8293bbd520b3fc225cd72181Brad Ebinger        // Wait for the handler to start the CallerInfo lookup
818c37ddf1546a8270c8293bbd520b3fc225cd72181Brad Ebinger        waitForHandlerAction(new Handler(Looper.getMainLooper()), TEST_TIMEOUT);
819ddb03e1387a09f9c7da624b064bf4f5b90ed478cTyler Gunn
820ddb03e1387a09f9c7da624b064bf4f5b90ed478cTyler Gunn        // Ensure callback to CS on successful creation happened.
821ddb03e1387a09f9c7da624b064bf4f5b90ed478cTyler Gunn        verify(connectionServiceFixture.getTestDouble(), timeout(TEST_TIMEOUT))
822ddb03e1387a09f9c7da624b064bf4f5b90ed478cTyler Gunn                .createConnectionComplete(anyString(), any());
823ddb03e1387a09f9c7da624b064bf4f5b90ed478cTyler Gunn
824ddb03e1387a09f9c7da624b064bf4f5b90ed478cTyler Gunn
825c37ddf1546a8270c8293bbd520b3fc225cd72181Brad Ebinger        // Process the CallerInfo lookup reply
826c37ddf1546a8270c8293bbd520b3fc225cd72181Brad Ebinger        mCallerInfoAsyncQueryFactoryFixture.mRequests.forEach(
827c37ddf1546a8270c8293bbd520b3fc225cd72181Brad Ebinger                CallerInfoAsyncQueryFactoryFixture.Request::reply);
828aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
8297bba1112556e122254013562650aac6a6af80ac6Brad Ebinger        //Wait for/Verify call blocking happened asynchronously
8307bba1112556e122254013562650aac6a6af80ac6Brad Ebinger        incomingCallAddedLatch.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS);
8317bba1112556e122254013562650aac6a6af80ac6Brad Ebinger
832c6e42ef0465fe01b35bb3aa94fbcbc081e3b45edAbhijith Shastry        IContentProvider blockedNumberProvider =
833c6e42ef0465fe01b35bb3aa94fbcbc081e3b45edAbhijith Shastry                mSpyContext.getContentResolver().acquireProvider(BlockedNumberContract.AUTHORITY);
834c6e42ef0465fe01b35bb3aa94fbcbc081e3b45edAbhijith Shastry        verify(blockedNumberProvider, timeout(TEST_TIMEOUT)).call(
835c6e42ef0465fe01b35bb3aa94fbcbc081e3b45edAbhijith Shastry                anyString(),
836c6e42ef0465fe01b35bb3aa94fbcbc081e3b45edAbhijith Shastry                eq(BlockedNumberContract.SystemContract.METHOD_SHOULD_SYSTEM_BLOCK_NUMBER),
837c6e42ef0465fe01b35bb3aa94fbcbc081e3b45edAbhijith Shastry                eq(number),
838c6e42ef0465fe01b35bb3aa94fbcbc081e3b45edAbhijith Shastry                isNull(Bundle.class));
839c6e42ef0465fe01b35bb3aa94fbcbc081e3b45edAbhijith Shastry
840aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        // For the case of incoming calls, Telecom connecting the InCall services and adding the
841aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        // Call is triggered by the async completion of the CallerInfoAsyncQuery. Once the Call
842aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        // is added, future interactions as triggered by the ConnectionService, through the various
843aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad        // test fixtures, will be synchronous.
844aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
845f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn        if (!hasInCallAdapter
846f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                && phoneAccountHandle != mPhoneAccountSelfManaged.getAccountHandle()) {
847b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn            verify(mInCallServiceFixtureX.getTestDouble(), timeout(TEST_TIMEOUT))
848b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn                    .setInCallAdapter(any(IInCallAdapter.class));
849b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn            verify(mInCallServiceFixtureY.getTestDouble(), timeout(TEST_TIMEOUT))
850b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn                    .setInCallAdapter(any(IInCallAdapter.class));
851aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
852f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            // Give the InCallService time to respond
853f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            assertTrueWithTimeout(new Predicate<Void>() {
854f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                @Override
855f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                public boolean apply(Void v) {
856f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                    return mInCallServiceFixtureX.mInCallAdapter != null;
857f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                }
858f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            });
85932dd7c331c5b4dc475d96b113a052286973f78fcIhab Awad
860f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            assertTrueWithTimeout(new Predicate<Void>() {
861f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                @Override
862f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                public boolean apply(Void v) {
863f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                    return mInCallServiceFixtureY.mInCallAdapter != null;
864f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                }
865f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            });
866aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
867f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            verify(mInCallServiceFixtureX.getTestDouble(), timeout(TEST_TIMEOUT))
868f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                    .addCall(any(ParcelableCall.class));
869f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            verify(mInCallServiceFixtureY.getTestDouble(), timeout(TEST_TIMEOUT))
870f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                    .addCall(any(ParcelableCall.class));
871aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
872f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            // Give the InCallService time to respond
8731b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad
874f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            assertTrueWithTimeout(new Predicate<Void>() {
875f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                @Override
876f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                public boolean apply(Void v) {
877f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                    return startingNumConnections + 1 ==
878f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                            connectionServiceFixture.mConnectionById.size();
879f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                }
880f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            });
881f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            assertTrueWithTimeout(new Predicate<Void>() {
882f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                @Override
883f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                public boolean apply(Void v) {
884f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                    return startingNumCalls + 1 == mInCallServiceFixtureX.mCallById.size();
885f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                }
886f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            });
887f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            assertTrueWithTimeout(new Predicate<Void>() {
888f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                @Override
889f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                public boolean apply(Void v) {
890f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                    return startingNumCalls + 1 == mInCallServiceFixtureY.mCallById.size();
891f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                }
892f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            });
8931b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad
894f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            assertEquals(mInCallServiceFixtureX.mLatestCallId,
895f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                    mInCallServiceFixtureY.mLatestCallId);
896f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn        }
8971b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad
898b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn        return new IdPair(connectionServiceFixture.mLatestConnectionId,
8991b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad                mInCallServiceFixtureX.mLatestCallId);
900aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad    }
901aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
902b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn    protected IdPair startAndMakeActiveOutgoingCall(
903b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn            String number,
904b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn            PhoneAccountHandle phoneAccountHandle,
905b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn            ConnectionServiceFixture connectionServiceFixture) throws Exception {
906b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn        return startAndMakeActiveOutgoingCall(number, phoneAccountHandle, connectionServiceFixture,
907b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn                VideoProfile.STATE_AUDIO_ONLY);
908abcbce4441720c52a443d292d5adc2d95f446494Ihab Awad    }
909abcbce4441720c52a443d292d5adc2d95f446494Ihab Awad
910aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad    // A simple outgoing call, verifying that the appropriate connection service is contacted,
911aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad    // the proper lifecycle is followed, and both In-Call Services are updated correctly.
912b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn    protected IdPair startAndMakeActiveOutgoingCall(
9131b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad            String number,
9141b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad            PhoneAccountHandle phoneAccountHandle,
915b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn            ConnectionServiceFixture connectionServiceFixture, int videoState) throws Exception {
916578a4e6661fc1be20d164458acb335356d742f72Tony Mak        IdPair ids = startOutgoingPhoneCall(number, phoneAccountHandle, connectionServiceFixture,
917b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn                Process.myUserHandle(), videoState);
918aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
9191b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad        connectionServiceFixture.sendSetDialing(ids.mConnectionId);
920f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn        if (phoneAccountHandle != mPhoneAccountSelfManaged.getAccountHandle()) {
921f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            assertEquals(Call.STATE_DIALING,
922f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                    mInCallServiceFixtureX.getCall(ids.mCallId).getState());
923f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            assertEquals(Call.STATE_DIALING,
924f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                    mInCallServiceFixtureY.getCall(ids.mCallId).getState());
925f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn        }
926aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
927b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn        connectionServiceFixture.sendSetVideoState(ids.mConnectionId);
928b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn
929bcf23de07aed59ed34d0121a76d29b6ed9a14288Tyler Gunn        when(mClockProxy.currentTimeMillis()).thenReturn(TEST_CONNECT_TIME);
930bcf23de07aed59ed34d0121a76d29b6ed9a14288Tyler Gunn        when(mClockProxy.elapsedRealtime()).thenReturn(TEST_CONNECT_ELAPSED_TIME);
9311b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad        connectionServiceFixture.sendSetActive(ids.mConnectionId);
932f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn        if (phoneAccountHandle != mPhoneAccountSelfManaged.getAccountHandle()) {
933f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
934f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
935f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn        }
9361b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad        return ids;
9371b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad    }
9380a4b95fc7731943fdd1a9b295daae45eb46b28d0Ihab Awad
939b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn    protected IdPair startAndMakeActiveIncomingCall(
940b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn            String number,
941b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn            PhoneAccountHandle phoneAccountHandle,
942b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn            ConnectionServiceFixture connectionServiceFixture) throws Exception {
943b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn        return startAndMakeActiveIncomingCall(number, phoneAccountHandle, connectionServiceFixture,
944b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn                VideoProfile.STATE_AUDIO_ONLY);
94542ef808c284791f21be8675174acc7297418fa45Tyler Gunn    }
94642ef808c284791f21be8675174acc7297418fa45Tyler Gunn
9471b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad    // A simple incoming call, similar in scope to the previous test
948b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn    protected IdPair startAndMakeActiveIncomingCall(
9491b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad            String number,
9501b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad            PhoneAccountHandle phoneAccountHandle,
951b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn            ConnectionServiceFixture connectionServiceFixture,
952b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn            int videoState) throws Exception {
9531b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad        IdPair ids = startIncomingPhoneCall(number, phoneAccountHandle, connectionServiceFixture);
954aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
955f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn        if (phoneAccountHandle != mPhoneAccountSelfManaged.getAccountHandle()) {
956f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            assertEquals(Call.STATE_RINGING,
957f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                    mInCallServiceFixtureX.getCall(ids.mCallId).getState());
958f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            assertEquals(Call.STATE_RINGING,
959f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                    mInCallServiceFixtureY.getCall(ids.mCallId).getState());
960f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn
961f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            mInCallServiceFixtureX.mInCallAdapter
962f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                    .answerCall(ids.mCallId, videoState);
963f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn
964f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            if (!VideoProfile.isVideo(videoState)) {
965f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                verify(connectionServiceFixture.getTestDouble())
966f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                        .answer(eq(ids.mConnectionId), any());
967f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            } else {
968f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                verify(connectionServiceFixture.getTestDouble())
969f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn                        .answerVideo(eq(ids.mConnectionId), eq(videoState), any());
970f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            }
971b492f4c845e61fac17c0e523363607d2dd6ba987Tyler Gunn        }
97232dd7c331c5b4dc475d96b113a052286973f78fcIhab Awad
973bcf23de07aed59ed34d0121a76d29b6ed9a14288Tyler Gunn        when(mClockProxy.currentTimeMillis()).thenReturn(TEST_CONNECT_TIME);
974bcf23de07aed59ed34d0121a76d29b6ed9a14288Tyler Gunn        when(mClockProxy.elapsedRealtime()).thenReturn(TEST_CONNECT_ELAPSED_TIME);
9751b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad        connectionServiceFixture.sendSetActive(ids.mConnectionId);
976aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
977f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn        if (phoneAccountHandle != mPhoneAccountSelfManaged.getAccountHandle()) {
978f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
979f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn            assertEquals(Call.STATE_ACTIVE, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
980f4cc3112101d48b546464bfb8766e6d8d6e6ae14Tyler Gunn        }
9811b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad        return ids;
9821b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad    }
983aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad
9846e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger    protected IdPair startAndMakeDialingEmergencyCall(
9856e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger            String number,
9866e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger            PhoneAccountHandle phoneAccountHandle,
9876e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger            ConnectionServiceFixture connectionServiceFixture) throws Exception {
9886e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        IdPair ids = startOutgoingEmergencyCall(number, phoneAccountHandle,
9896e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger                connectionServiceFixture, Process.myUserHandle(), VideoProfile.STATE_AUDIO_ONLY);
9906e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger
9916e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        connectionServiceFixture.sendSetDialing(ids.mConnectionId);
9926e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        assertEquals(Call.STATE_DIALING, mInCallServiceFixtureX.getCall(ids.mCallId).getState());
9936e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        assertEquals(Call.STATE_DIALING, mInCallServiceFixtureY.getCall(ids.mCallId).getState());
9946e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger
9956e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger        return ids;
9966e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger    }
9976e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger
99832dd7c331c5b4dc475d96b113a052286973f78fcIhab Awad    protected static void assertTrueWithTimeout(Predicate<Void> predicate) {
99932dd7c331c5b4dc475d96b113a052286973f78fcIhab Awad        int elapsed = 0;
100032dd7c331c5b4dc475d96b113a052286973f78fcIhab Awad        while (elapsed < TEST_TIMEOUT) {
100132dd7c331c5b4dc475d96b113a052286973f78fcIhab Awad            if (predicate.apply(null)) {
100232dd7c331c5b4dc475d96b113a052286973f78fcIhab Awad                return;
100332dd7c331c5b4dc475d96b113a052286973f78fcIhab Awad            } else {
100432dd7c331c5b4dc475d96b113a052286973f78fcIhab Awad                try {
100532dd7c331c5b4dc475d96b113a052286973f78fcIhab Awad                    Thread.sleep(TEST_POLL_INTERVAL);
100632dd7c331c5b4dc475d96b113a052286973f78fcIhab Awad                    elapsed += TEST_POLL_INTERVAL;
100732dd7c331c5b4dc475d96b113a052286973f78fcIhab Awad                } catch (InterruptedException e) {
100832dd7c331c5b4dc475d96b113a052286973f78fcIhab Awad                    fail(e.toString());
100932dd7c331c5b4dc475d96b113a052286973f78fcIhab Awad                }
101032dd7c331c5b4dc475d96b113a052286973f78fcIhab Awad            }
10111b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad        }
101232dd7c331c5b4dc475d96b113a052286973f78fcIhab Awad        fail("Timeout in assertTrueWithTimeout");
10131b5490ac8643a5969adaba6f68d872acd251d666Ihab Awad    }
1014aa383cca668afd8578a6e007c3ea360768dc52f6Ihab Awad}
1015