1f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon/*
2f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon * Copyright (C) 2016 The Android Open Source Project
3f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon *
4f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon * Licensed under the Apache License, Version 2.0 (the "License");
5f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon * you may not use this file except in compliance with the License.
6f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon * You may obtain a copy of the License at
7f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon *
8f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon *      http://www.apache.org/licenses/LICENSE-2.0
9f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon *
10f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon * Unless required by applicable law or agreed to in writing, software
11f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon * distributed under the License is distributed on an "AS IS" BASIS,
12f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon * See the License for the specific language governing permissions and
14f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon * limitations under the License
15f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon */
16f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon
17f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonpackage com.android.server.telecom.tests;
18f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon
19501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordonimport android.Manifest;
20f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport android.content.ComponentName;
2128b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liuimport android.content.ContentResolver;
22f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport android.content.Context;
23f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport android.content.Intent;
24f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport android.content.ServiceConnection;
25f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport android.content.pm.PackageManager;
26f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport android.content.pm.ResolveInfo;
27501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordonimport android.content.pm.ServiceInfo;
28f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport android.content.res.Resources;
29f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport android.os.Bundle;
30501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordonimport android.os.IBinder;
31f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport android.os.UserHandle;
32f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport android.telecom.InCallService;
3328b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liuimport android.telecom.ParcelableCall;
34f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport android.telecom.PhoneAccountHandle;
35f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport android.telecom.TelecomManager;
36f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport android.test.mock.MockContext;
37a3799ae6aafba8ccd6448a7c4337acd3460b49f2Hall Liuimport android.test.suitebuilder.annotation.MediumTest;
38f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunnimport android.text.TextUtils;
39f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon
40501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordonimport com.android.internal.telecom.IInCallAdapter;
41501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordonimport com.android.internal.telecom.IInCallService;
423f54d497235aebd98d5b8e8e0e52da92f838d657Hall Liuimport com.android.server.telecom.Analytics;
43f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport com.android.server.telecom.BluetoothHeadsetProxy;
44f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport com.android.server.telecom.Call;
45f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport com.android.server.telecom.CallsManager;
46f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport com.android.server.telecom.InCallController;
47f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport com.android.server.telecom.PhoneAccountRegistrar;
48f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport com.android.server.telecom.R;
49f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport com.android.server.telecom.SystemStateProvider;
50501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordonimport com.android.server.telecom.TelecomServiceImpl.DefaultDialerManagerAdapter;
51f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport com.android.server.telecom.TelecomSystem;
5228b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liuimport com.android.server.telecom.Timeouts;
53f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon
54f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport org.mockito.ArgumentCaptor;
55f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport org.mockito.Mock;
56f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport org.mockito.MockitoAnnotations;
57f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunnimport org.mockito.invocation.InvocationOnMock;
58f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunnimport org.mockito.stubbing.Answer;
59f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon
6028b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liuimport java.util.Collections;
61f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport java.util.LinkedList;
62f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon
63f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport static org.mockito.Matchers.any;
64f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport static org.mockito.Matchers.anyInt;
65f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport static org.mockito.Matchers.anyString;
66f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport static org.mockito.Matchers.eq;
67f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport static org.mockito.Matchers.isNull;
68f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport static org.mockito.Matchers.isNull;
69f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunnimport static org.mockito.Mockito.doAnswer;
70f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport static org.mockito.Mockito.doReturn;
71f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport static org.mockito.Mockito.mock;
72f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport static org.mockito.Mockito.never;
73f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport static org.mockito.Mockito.times;
74f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport static org.mockito.Mockito.when;
75f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonimport static org.mockito.Mockito.verify;
76f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon
77f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordonpublic class InCallControllerTests extends TelecomTestCase {
78f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon    @Mock CallsManager mMockCallsManager;
79f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon    @Mock PhoneAccountRegistrar mMockPhoneAccountRegistrar;
80f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon    @Mock BluetoothHeadsetProxy mMockBluetoothHeadset;
81f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon    @Mock SystemStateProvider mMockSystemStateProvider;
82f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon    @Mock PackageManager mMockPackageManager;
83f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon    @Mock Call mMockCall;
84f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon    @Mock Resources mMockResources;
85f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon    @Mock MockContext mMockContext;
86501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon    @Mock DefaultDialerManagerAdapter mMockDefaultDialerAdapter;
8728b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu    @Mock Timeouts.Adapter mTimeoutsAdapter;
88f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon
89f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon    private static final int CURRENT_USER_ID = 900973;
90f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon    private static final String DEF_PKG = "defpkg";
91f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon    private static final String DEF_CLASS = "defcls";
92501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon    private static final String SYS_PKG = "syspkg";
93501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon    private static final String SYS_CLASS = "syscls";
94f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon    private static final PhoneAccountHandle PA_HANDLE =
95f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon            new PhoneAccountHandle(new ComponentName("pa_pkg", "pa_cls"), "pa_id");
96f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon
97f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon    private UserHandle mUserHandle = UserHandle.of(CURRENT_USER_ID);
98f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon    private InCallController mInCallController;
996e8f3d70ac7397afb4cb5ab276d1cd385c92dd21Brad Ebinger    private TelecomSystem.SyncRoot mLock = new TelecomSystem.SyncRoot() {};
100f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon
101f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon    @Override
102f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon    public void setUp() throws Exception {
103f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        super.setUp();
104f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        MockitoAnnotations.initMocks(this);
1053f54d497235aebd98d5b8e8e0e52da92f838d657Hall Liu        when(mMockCall.getAnalytics()).thenReturn(new Analytics.CallInfo());
106f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        doReturn(mMockResources).when(mMockContext).getResources();
107501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        doReturn(SYS_PKG).when(mMockResources).getString(R.string.ui_default_package);
108501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        doReturn(SYS_CLASS).when(mMockResources).getString(R.string.incall_default_class);
109f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        mInCallController = new InCallController(mMockContext, mLock, mMockCallsManager,
11028b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu                mMockSystemStateProvider, mMockDefaultDialerAdapter, mTimeoutsAdapter);
111f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon    }
112f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon
113f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon    @Override
114f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon    public void tearDown() throws Exception {
115f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        super.tearDown();
116f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon    }
117f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon
118a3799ae6aafba8ccd6448a7c4337acd3460b49f2Hall Liu    @MediumTest
119f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon    public void testBindToService_NoServicesFound_IncomingCall() throws Exception {
120f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
121f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
122f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        when(mMockCallsManager.hasEmergencyCall()).thenReturn(false);
123f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        when(mMockCall.isIncoming()).thenReturn(true);
124f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        when(mMockCall.isExternalCall()).thenReturn(false);
125f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon
126f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        setupMockPackageManager(false /* default */, true /* system */, false /* external calls */);
127f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        mInCallController.bindToServices(mMockCall);
128f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon
129f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
130f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        verify(mMockContext).bindServiceAsUser(
131f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon                bindIntentCaptor.capture(),
132f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon                any(ServiceConnection.class),
133f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon                eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
134f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon                eq(UserHandle.CURRENT));
135f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon
136f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        Intent bindIntent = bindIntentCaptor.getValue();
137f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        assertEquals(InCallService.SERVICE_INTERFACE, bindIntent.getAction());
138501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        assertEquals(SYS_PKG, bindIntent.getComponent().getPackageName());
139501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        assertEquals(SYS_CLASS, bindIntent.getComponent().getClassName());
140f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        assertNull(bindIntent.getExtras());
141f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon    }
142f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon
143a3799ae6aafba8ccd6448a7c4337acd3460b49f2Hall Liu    @MediumTest
144f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon    public void testBindToService_NoServicesFound_OutgoingCall() throws Exception {
145f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        Bundle callExtras = new Bundle();
146f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        callExtras.putBoolean("whatever", true);
147f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon
148f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
149f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
150f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        when(mMockCallsManager.hasEmergencyCall()).thenReturn(false);
151f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        when(mMockCall.isIncoming()).thenReturn(false);
152f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        when(mMockCall.getTargetPhoneAccount()).thenReturn(PA_HANDLE);
153f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        when(mMockCall.getIntentExtras()).thenReturn(callExtras);
154f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        when(mMockCall.isExternalCall()).thenReturn(false);
155f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon
156f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        Intent queryIntent = new Intent(InCallService.SERVICE_INTERFACE);
157f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        setupMockPackageManager(false /* default */, true /* system */, false /* external calls */);
158f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        mInCallController.bindToServices(mMockCall);
159f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon
160f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
161f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        verify(mMockContext).bindServiceAsUser(
162f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon                bindIntentCaptor.capture(),
163f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon                any(ServiceConnection.class),
164f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon                eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
165f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon                eq(UserHandle.CURRENT));
166f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon
167f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        Intent bindIntent = bindIntentCaptor.getValue();
168f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        assertEquals(InCallService.SERVICE_INTERFACE, bindIntent.getAction());
169501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        assertEquals(SYS_PKG, bindIntent.getComponent().getPackageName());
170501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        assertEquals(SYS_CLASS, bindIntent.getComponent().getClassName());
171501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        assertEquals(PA_HANDLE, bindIntent.getExtras().getParcelable(
172501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE));
173501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        assertEquals(callExtras, bindIntent.getExtras().getParcelable(
174501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS));
175501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon    }
176501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon
177501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon    @MediumTest
178501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon    public void testBindToService_DefaultDialer_NoEmergency() throws Exception {
179501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        Bundle callExtras = new Bundle();
180501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        callExtras.putBoolean("whatever", true);
181501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon
182501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
183501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
184501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        when(mMockCallsManager.hasEmergencyCall()).thenReturn(false);
185501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        when(mMockCall.isIncoming()).thenReturn(false);
186501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        when(mMockCall.getTargetPhoneAccount()).thenReturn(PA_HANDLE);
187501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        when(mMockCall.getIntentExtras()).thenReturn(callExtras);
188f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        when(mMockCall.isExternalCall()).thenReturn(false);
189501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        when(mMockDefaultDialerAdapter.getDefaultDialerApplication(mMockContext, CURRENT_USER_ID))
190501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                .thenReturn(DEF_PKG);
191501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        when(mMockContext.bindServiceAsUser(any(Intent.class), any(ServiceConnection.class),
192501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                anyInt(), eq(UserHandle.CURRENT))).thenReturn(true);
193501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon
194f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        setupMockPackageManager(true /* default */, true /* system */, false /* external calls */);
195501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        mInCallController.bindToServices(mMockCall);
196501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon
197501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        // Query for the different InCallServices
198501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        ArgumentCaptor<Intent> queryIntentCaptor = ArgumentCaptor.forClass(Intent.class);
199f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        verify(mMockPackageManager, times(4)).queryIntentServicesAsUser(
200501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                queryIntentCaptor.capture(),
201501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
202501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon
203501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        // Verify call for default dialer InCallService
204501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        assertEquals(DEF_PKG, queryIntentCaptor.getAllValues().get(0).getPackage());
205501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        // Verify call for car-mode InCallService
206501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        assertEquals(null, queryIntentCaptor.getAllValues().get(1).getPackage());
207501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        // Verify call for non-UI InCallServices
208501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        assertEquals(null, queryIntentCaptor.getAllValues().get(2).getPackage());
209501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon
210501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
211501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        verify(mMockContext, times(1)).bindServiceAsUser(
212501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                bindIntentCaptor.capture(),
213501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                any(ServiceConnection.class),
214501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
215501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                eq(UserHandle.CURRENT));
216501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon
217501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        Intent bindIntent = bindIntentCaptor.getValue();
218501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        assertEquals(InCallService.SERVICE_INTERFACE, bindIntent.getAction());
219f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        assertEquals(DEF_PKG, bindIntent.getComponent().getPackageName());
220f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        assertEquals(DEF_CLASS, bindIntent.getComponent().getClassName());
221f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        assertEquals(PA_HANDLE, bindIntent.getExtras().getParcelable(
222f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon                TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE));
223f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon        assertEquals(callExtras, bindIntent.getExtras().getParcelable(
224f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon                TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS));
225f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon    }
226501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon
227501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon    @MediumTest
228501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon    public void testBindToService_SystemDialer_Emergency() throws Exception {
229501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        Bundle callExtras = new Bundle();
230501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        callExtras.putBoolean("whatever", true);
231501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon
232501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
233501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
234501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        when(mMockCallsManager.hasEmergencyCall()).thenReturn(true);
235501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        when(mMockCall.isIncoming()).thenReturn(false);
236501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        when(mMockCall.getTargetPhoneAccount()).thenReturn(PA_HANDLE);
237501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        when(mMockCall.getIntentExtras()).thenReturn(callExtras);
238f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        when(mMockCall.isExternalCall()).thenReturn(false);
239501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        when(mMockDefaultDialerAdapter.getDefaultDialerApplication(mMockContext, CURRENT_USER_ID))
240501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                .thenReturn(DEF_PKG);
241501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        when(mMockContext.bindServiceAsUser(any(Intent.class), any(ServiceConnection.class),
242501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
243501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                eq(UserHandle.CURRENT))).thenReturn(true);
244501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon
245f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        setupMockPackageManager(true /* default */, true /* system */, false /* external calls */);
246f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn
247501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        mInCallController.bindToServices(mMockCall);
248501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon
249501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        // Query for the different InCallServices
250501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        ArgumentCaptor<Intent> queryIntentCaptor = ArgumentCaptor.forClass(Intent.class);
251f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        verify(mMockPackageManager, times(4)).queryIntentServicesAsUser(
252501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                queryIntentCaptor.capture(),
253501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
254501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon
255501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        // Verify call for default dialer InCallService
256501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        assertEquals(DEF_PKG, queryIntentCaptor.getAllValues().get(0).getPackage());
257501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        // Verify call for car-mode InCallService
258501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        assertEquals(null, queryIntentCaptor.getAllValues().get(1).getPackage());
259501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        // Verify call for non-UI InCallServices
260501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        assertEquals(null, queryIntentCaptor.getAllValues().get(2).getPackage());
261501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon
262501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
263501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        verify(mMockContext, times(1)).bindServiceAsUser(
264501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                bindIntentCaptor.capture(),
265501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                any(ServiceConnection.class),
266501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
267501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                eq(UserHandle.CURRENT));
268501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon
269501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        Intent bindIntent = bindIntentCaptor.getValue();
270501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        assertEquals(InCallService.SERVICE_INTERFACE, bindIntent.getAction());
271501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        assertEquals(SYS_PKG, bindIntent.getComponent().getPackageName());
272501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        assertEquals(SYS_CLASS, bindIntent.getComponent().getClassName());
273501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        assertEquals(PA_HANDLE, bindIntent.getExtras().getParcelable(
274501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE));
275501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        assertEquals(callExtras, bindIntent.getExtras().getParcelable(
276501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS));
277501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon    }
278501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon
279501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon    @MediumTest
280501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon    public void testBindToService_DefaultDialer_FallBackToSystem() throws Exception {
281501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        Bundle callExtras = new Bundle();
282501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        callExtras.putBoolean("whatever", true);
283501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon
284501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
285501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
286501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        when(mMockCallsManager.hasEmergencyCall()).thenReturn(false);
28728b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        when(mMockCallsManager.getCalls()).thenReturn(Collections.singletonList(mMockCall));
28828b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        when(mMockCallsManager.getAudioState()).thenReturn(null);
28928b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        when(mMockCallsManager.canAddCall()).thenReturn(false);
290501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        when(mMockCall.isIncoming()).thenReturn(false);
291501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        when(mMockCall.getTargetPhoneAccount()).thenReturn(PA_HANDLE);
292501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        when(mMockCall.getIntentExtras()).thenReturn(callExtras);
293f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        when(mMockCall.isExternalCall()).thenReturn(false);
29428b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        when(mMockCall.getConferenceableCalls()).thenReturn(Collections.emptyList());
295501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        when(mMockDefaultDialerAdapter.getDefaultDialerApplication(mMockContext, CURRENT_USER_ID))
296501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                .thenReturn(DEF_PKG);
297501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        when(mMockContext.bindServiceAsUser(
298501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                any(Intent.class), any(ServiceConnection.class), anyInt(), any(UserHandle.class)))
299501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                .thenReturn(true);
300501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon
301f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        setupMockPackageManager(true /* default */, true /* system */, false /* external calls */);
302501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        mInCallController.bindToServices(mMockCall);
303501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon
304501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        // Query for the different InCallServices
305501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        ArgumentCaptor<Intent> queryIntentCaptor = ArgumentCaptor.forClass(Intent.class);
306f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        verify(mMockPackageManager, times(4)).queryIntentServicesAsUser(
307501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                queryIntentCaptor.capture(),
308501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
309501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon
310501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        // Verify call for default dialer InCallService
311501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        assertEquals(DEF_PKG, queryIntentCaptor.getAllValues().get(0).getPackage());
312501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        // Verify call for car-mode InCallService
313501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        assertEquals(null, queryIntentCaptor.getAllValues().get(1).getPackage());
314501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        // Verify call for non-UI InCallServices
315501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        assertEquals(null, queryIntentCaptor.getAllValues().get(2).getPackage());
316501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon
317501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
318501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        ArgumentCaptor<ServiceConnection> serviceConnectionCaptor =
319501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                ArgumentCaptor.forClass(ServiceConnection.class);
320501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        verify(mMockContext, times(1)).bindServiceAsUser(
321501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                bindIntentCaptor.capture(),
322501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                serviceConnectionCaptor.capture(),
323501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
324501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                eq(UserHandle.CURRENT));
325501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon
326501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        Intent bindIntent = bindIntentCaptor.getValue();
327501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        assertEquals(InCallService.SERVICE_INTERFACE, bindIntent.getAction());
328501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        assertEquals(DEF_PKG, bindIntent.getComponent().getPackageName());
329501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        assertEquals(DEF_CLASS, bindIntent.getComponent().getClassName());
330501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        assertEquals(PA_HANDLE, bindIntent.getExtras().getParcelable(
331501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE));
332501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        assertEquals(callExtras, bindIntent.getExtras().getParcelable(
333501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS));
334501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon
335501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        // We have a ServiceConnection for the default dialer, lets start the connection, and then
336501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        // simulate a crash so that we fallback to system.
337501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        ServiceConnection serviceConnection = serviceConnectionCaptor.getValue();
338501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        ComponentName defDialerComponentName = new ComponentName(DEF_PKG, DEF_CLASS);
339501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        IBinder mockBinder = mock(IBinder.class);
340501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        IInCallService mockInCallService = mock(IInCallService.class);
341501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        when(mockBinder.queryLocalInterface(anyString())).thenReturn(mockInCallService);
342501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon
343501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon
344501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        // Start the connection with IInCallService
345501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        serviceConnection.onServiceConnected(defDialerComponentName, mockBinder);
346501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        verify(mockInCallService).setInCallAdapter(any(IInCallAdapter.class));
347501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon
348501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        // Now crash the damn thing!
349501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        serviceConnection.onServiceDisconnected(defDialerComponentName);
350501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon
351501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        ArgumentCaptor<Intent> bindIntentCaptor2 = ArgumentCaptor.forClass(Intent.class);
352501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        verify(mMockContext, times(2)).bindServiceAsUser(
353501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                bindIntentCaptor2.capture(),
354501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                any(ServiceConnection.class),
355501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
356501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon                eq(UserHandle.CURRENT));
357501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon
358501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        bindIntent = bindIntentCaptor2.getValue();
359501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        assertEquals(SYS_PKG, bindIntent.getComponent().getPackageName());
360501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon        assertEquals(SYS_CLASS, bindIntent.getComponent().getClassName());
361501b9b3775232bb3033afd9f1fd608dd07d0b91eSantos Cordon    }
362f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn
363f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn    /**
364f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn     * Ensures that the {@link InCallController} will bind to an {@link InCallService} which
365f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn     * supports external calls.
366f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn     */
367f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn    @MediumTest
368f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn    public void testBindToService_IncludeExternal() throws Exception {
369f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        setupMocks(true /* isExternalCall */);
370f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        setupMockPackageManager(true /* default */, true /* system */, true /* external calls */);
371f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        mInCallController.bindToServices(mMockCall);
372f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn
373f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        // Query for the different InCallServices
374f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        ArgumentCaptor<Intent> queryIntentCaptor = ArgumentCaptor.forClass(Intent.class);
375f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        verify(mMockPackageManager, times(4)).queryIntentServicesAsUser(
376f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn                queryIntentCaptor.capture(),
377f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn                eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
378f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn
379f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        // Verify call for default dialer InCallService
380f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        assertEquals(DEF_PKG, queryIntentCaptor.getAllValues().get(0).getPackage());
381f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        // Verify call for car-mode InCallService
382f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        assertEquals(null, queryIntentCaptor.getAllValues().get(1).getPackage());
383f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        // Verify call for non-UI InCallServices
384f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        assertEquals(null, queryIntentCaptor.getAllValues().get(2).getPackage());
385f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn
386f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
387f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        verify(mMockContext, times(1)).bindServiceAsUser(
388f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn                bindIntentCaptor.capture(),
389f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn                any(ServiceConnection.class),
390f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn                eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
391f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn                eq(UserHandle.CURRENT));
392f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn
393f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        Intent bindIntent = bindIntentCaptor.getValue();
394f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        assertEquals(InCallService.SERVICE_INTERFACE, bindIntent.getAction());
395f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        assertEquals(DEF_PKG, bindIntent.getComponent().getPackageName());
396f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        assertEquals(DEF_CLASS, bindIntent.getComponent().getClassName());
397f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn    }
398f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn
39928b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu    /**
40028b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu     * Make sure that if a call goes away before the in-call service finishes binding and another
40128b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu     * call gets connected soon after, the new call will still be sent to the in-call service.
40228b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu     */
40328b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu    @MediumTest
40428b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu    public void testUnbindDueToCallDisconnect() throws Exception {
40528b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
40628b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
40728b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        when(mMockCallsManager.hasEmergencyCall()).thenReturn(false);
40828b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        when(mMockCall.isIncoming()).thenReturn(true);
40928b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        when(mMockCall.isExternalCall()).thenReturn(false);
41028b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        when(mMockDefaultDialerAdapter.getDefaultDialerApplication(mMockContext, CURRENT_USER_ID))
41128b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu                .thenReturn(DEF_PKG);
41228b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        when(mMockContext.bindServiceAsUser(
41328b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu                any(Intent.class), any(ServiceConnection.class), anyInt(), any(UserHandle.class)))
41428b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu                .thenReturn(true);
41528b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        when(mTimeoutsAdapter.getCallRemoveUnbindInCallServicesDelay(any(ContentResolver.class)))
41628b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu                .thenReturn(500L);
41728b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu
41828b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        when(mMockCallsManager.getCalls()).thenReturn(Collections.singletonList(mMockCall));
41928b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        setupMockPackageManager(true /* default */, true /* system */, false /* external calls */);
42028b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        mInCallController.bindToServices(mMockCall);
42128b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu
42228b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
42328b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        ArgumentCaptor<ServiceConnection> serviceConnectionCaptor =
42428b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu                ArgumentCaptor.forClass(ServiceConnection.class);
42528b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        verify(mMockContext, times(1)).bindServiceAsUser(
42628b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu                bindIntentCaptor.capture(),
42728b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu                serviceConnectionCaptor.capture(),
42828b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu                eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
42928b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu                eq(UserHandle.CURRENT));
43028b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu
43128b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        // Pretend that the call has gone away.
43228b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        when(mMockCallsManager.getCalls()).thenReturn(Collections.emptyList());
43328b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        mInCallController.onCallRemoved(mMockCall);
43428b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu
43528b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        // Start the connection, make sure we don't unbind, and make sure that we don't send
43628b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        // anything to the in-call service yet.
43728b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        ServiceConnection serviceConnection = serviceConnectionCaptor.getValue();
43828b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        ComponentName defDialerComponentName = new ComponentName(DEF_PKG, DEF_CLASS);
43928b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        IBinder mockBinder = mock(IBinder.class);
44028b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        IInCallService mockInCallService = mock(IInCallService.class);
44128b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        when(mockBinder.queryLocalInterface(anyString())).thenReturn(mockInCallService);
44228b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu
44328b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        serviceConnection.onServiceConnected(defDialerComponentName, mockBinder);
44428b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        verify(mockInCallService).setInCallAdapter(any(IInCallAdapter.class));
44528b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        verify(mMockContext, never()).unbindService(serviceConnection);
44628b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        verify(mockInCallService, never()).addCall(any(ParcelableCall.class));
44728b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu
44828b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        // Now, we add in the call again and make sure that it's sent to the InCallService.
44928b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        when(mMockCallsManager.getCalls()).thenReturn(Collections.singletonList(mMockCall));
45028b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        mInCallController.onCallAdded(mMockCall);
45128b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu        verify(mockInCallService).addCall(any(ParcelableCall.class));
45228b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu    }
45328b82f0fe9b55b3bd826ba3a4204329988447c57Hall Liu
454f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn    private void setupMocks(boolean isExternalCall) {
455f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
456f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
457f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        when(mMockCallsManager.hasEmergencyCall()).thenReturn(false);
458f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        when(mMockCall.isIncoming()).thenReturn(false);
459f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        when(mMockCall.getTargetPhoneAccount()).thenReturn(PA_HANDLE);
460f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        when(mMockDefaultDialerAdapter.getDefaultDialerApplication(mMockContext, CURRENT_USER_ID))
461f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn                .thenReturn(DEF_PKG);
462f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        when(mMockContext.bindServiceAsUser(any(Intent.class), any(ServiceConnection.class),
463f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn                anyInt(), eq(UserHandle.CURRENT))).thenReturn(true);
464f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        when(mMockCall.isExternalCall()).thenReturn(isExternalCall);
465f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn    }
466f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn
467f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn    private ResolveInfo getDefResolveInfo(final boolean includeExternalCalls) {
468f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        return new ResolveInfo() {{
469f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn            serviceInfo = new ServiceInfo();
470f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn            serviceInfo.packageName = DEF_PKG;
471f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn            serviceInfo.name = DEF_CLASS;
472f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn            serviceInfo.permission = Manifest.permission.BIND_INCALL_SERVICE;
473f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn            serviceInfo.metaData = new Bundle();
474f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn            serviceInfo.metaData.putBoolean(
475f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn                    TelecomManager.METADATA_IN_CALL_SERVICE_UI, true);
476f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn            if (includeExternalCalls) {
477f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn                serviceInfo.metaData.putBoolean(
478f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn                        TelecomManager.METADATA_INCLUDE_EXTERNAL_CALLS, true);
479f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn            }
480f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        }};
481f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn    }
482f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn
483f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn    private ResolveInfo getSysResolveinfo() {
484f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        return new ResolveInfo() {{
485f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn            serviceInfo = new ServiceInfo();
486f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn            serviceInfo.packageName = SYS_PKG;
487f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn            serviceInfo.name = SYS_CLASS;
488f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn            serviceInfo.permission = Manifest.permission.BIND_INCALL_SERVICE;
489f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        }};
490f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn    }
491f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn
492f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn    private void setupMockPackageManager(final boolean useDefaultDialer,
493f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn            final boolean useSystemDialer, final boolean includeExternalCalls) {
494f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn
495f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        doAnswer(new Answer() {
496f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn            @Override
497f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn            public Object answer(InvocationOnMock invocation) throws Throwable {
498f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn                Object[] args = invocation.getArguments();
499f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn                Intent intent = (Intent) args[0];
500f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn                String packageName = intent.getPackage();
501f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn                ComponentName componentName = intent.getComponent();
502f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn                if (componentName != null) {
503f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn                    packageName = componentName.getPackageName();
504f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn                }
505f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn                LinkedList<ResolveInfo> resolveInfo = new LinkedList<ResolveInfo>();
506f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn                if (!TextUtils.isEmpty(packageName)) {
507f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn                    if ((TextUtils.isEmpty(packageName) || packageName.equals(DEF_PKG)) &&
508f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn                            useDefaultDialer) {
509f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn                        resolveInfo.add(getDefResolveInfo(includeExternalCalls));
510f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn                    }
511f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn
512f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn                    if ((TextUtils.isEmpty(packageName) || packageName.equals(SYS_PKG)) &&
513f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn                           useSystemDialer) {
514f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn                        resolveInfo.add(getSysResolveinfo());
515f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn                    }
516f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn                }
517f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn                return resolveInfo;
518f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn            }
519f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn        }).when(mMockPackageManager).queryIntentServicesAsUser(
520f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn                any(Intent.class), eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
521f15dc33f87f88e21ef745952a68af65c86e1bf1eTyler Gunn    }
522f0f99f34fc993dc72c335133c6b04720c826c891Santos Cordon}
523