Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License
     15  */
     16 
     17 package com.android.server.telecom.tests;
     18 
     19 import android.Manifest;
     20 import android.content.ComponentName;
     21 import android.content.ContentResolver;
     22 import android.content.Context;
     23 import android.content.Intent;
     24 import android.content.ServiceConnection;
     25 import android.content.pm.PackageManager;
     26 import android.content.pm.ResolveInfo;
     27 import android.content.pm.ServiceInfo;
     28 import android.content.res.Resources;
     29 import android.os.Bundle;
     30 import android.os.IBinder;
     31 import android.os.Handler;
     32 import android.os.Looper;
     33 import android.os.UserHandle;
     34 import android.telecom.InCallService;
     35 import android.telecom.ParcelableCall;
     36 import android.telecom.PhoneAccountHandle;
     37 import android.telecom.TelecomManager;
     38 import android.test.mock.MockContext;
     39 import android.test.suitebuilder.annotation.MediumTest;
     40 import android.text.TextUtils;
     41 
     42 import com.android.internal.telecom.IInCallAdapter;
     43 import com.android.internal.telecom.IInCallService;
     44 import com.android.server.telecom.Analytics;
     45 import com.android.server.telecom.BluetoothHeadsetProxy;
     46 import com.android.server.telecom.Call;
     47 import com.android.server.telecom.CallsManager;
     48 import com.android.server.telecom.DefaultDialerCache;
     49 import com.android.server.telecom.EmergencyCallHelper;
     50 import com.android.server.telecom.InCallController;
     51 import com.android.server.telecom.PhoneAccountRegistrar;
     52 import com.android.server.telecom.R;
     53 import com.android.server.telecom.SystemStateProvider;
     54 import com.android.server.telecom.TelecomSystem;
     55 import com.android.server.telecom.Timeouts;
     56 
     57 import org.junit.After;
     58 import org.junit.Before;
     59 import org.junit.Test;
     60 import org.junit.runner.RunWith;
     61 import org.junit.runners.JUnit4;
     62 import org.mockito.ArgumentCaptor;
     63 import org.mockito.Mock;
     64 import org.mockito.MockitoAnnotations;
     65 import org.mockito.invocation.InvocationOnMock;
     66 import org.mockito.stubbing.Answer;
     67 
     68 import java.util.Collections;
     69 import java.util.LinkedList;
     70 
     71 import static org.junit.Assert.assertEquals;
     72 import static org.junit.Assert.assertNull;
     73 import static org.mockito.ArgumentMatchers.nullable;
     74 import static org.mockito.Matchers.any;
     75 import static org.mockito.Matchers.anyInt;
     76 import static org.mockito.Matchers.anyString;
     77 import static org.mockito.Matchers.eq;
     78 import static org.mockito.Mockito.doAnswer;
     79 import static org.mockito.Mockito.doReturn;
     80 import static org.mockito.Mockito.mock;
     81 import static org.mockito.Mockito.never;
     82 import static org.mockito.Mockito.times;
     83 import static org.mockito.Mockito.when;
     84 import static org.mockito.Mockito.verify;
     85 
     86 @RunWith(JUnit4.class)
     87 public class InCallControllerTests extends TelecomTestCase {
     88     @Mock CallsManager mMockCallsManager;
     89     @Mock PhoneAccountRegistrar mMockPhoneAccountRegistrar;
     90     @Mock BluetoothHeadsetProxy mMockBluetoothHeadset;
     91     @Mock SystemStateProvider mMockSystemStateProvider;
     92     @Mock PackageManager mMockPackageManager;
     93     @Mock Call mMockCall;
     94     @Mock Resources mMockResources;
     95     @Mock MockContext mMockContext;
     96     @Mock Timeouts.Adapter mTimeoutsAdapter;
     97     @Mock DefaultDialerCache mDefaultDialerCache;
     98 
     99     private static final int CURRENT_USER_ID = 900973;
    100     private static final String DEF_PKG = "defpkg";
    101     private static final String DEF_CLASS = "defcls";
    102     private static final String SYS_PKG = "syspkg";
    103     private static final String SYS_CLASS = "syscls";
    104     private static final PhoneAccountHandle PA_HANDLE =
    105             new PhoneAccountHandle(new ComponentName("pa_pkg", "pa_cls"), "pa_id");
    106 
    107     private UserHandle mUserHandle = UserHandle.of(CURRENT_USER_ID);
    108     private InCallController mInCallController;
    109     private TelecomSystem.SyncRoot mLock = new TelecomSystem.SyncRoot() {};
    110     private EmergencyCallHelper mEmergencyCallHelper;
    111 
    112     @Override
    113     @Before
    114     public void setUp() throws Exception {
    115         super.setUp();
    116         MockitoAnnotations.initMocks(this);
    117         when(mMockCall.getAnalytics()).thenReturn(new Analytics.CallInfo());
    118         doReturn(mMockResources).when(mMockContext).getResources();
    119         doReturn(SYS_PKG).when(mMockResources).getString(R.string.ui_default_package);
    120         doReturn(SYS_CLASS).when(mMockResources).getString(R.string.incall_default_class);
    121         doReturn(true).when(mMockResources).getBoolean(R.bool.grant_location_permission_enabled);
    122         mEmergencyCallHelper = new EmergencyCallHelper(mMockContext, SYS_PKG,
    123                 mTimeoutsAdapter);
    124         mInCallController = new InCallController(mMockContext, mLock, mMockCallsManager,
    125                 mMockSystemStateProvider, mDefaultDialerCache, mTimeoutsAdapter,
    126                 mEmergencyCallHelper);
    127     }
    128 
    129     @Override
    130     @After
    131     public void tearDown() throws Exception {
    132         super.tearDown();
    133     }
    134 
    135     @MediumTest
    136     @Test
    137     public void testBindToService_NoServicesFound_IncomingCall() throws Exception {
    138         when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
    139         when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
    140         when(mMockCallsManager.hasEmergencyCall()).thenReturn(false);
    141         when(mMockCall.isIncoming()).thenReturn(true);
    142         when(mMockCall.isExternalCall()).thenReturn(false);
    143         when(mTimeoutsAdapter.getEmergencyCallbackWindowMillis(any(ContentResolver.class)))
    144                 .thenReturn(300_000L);
    145 
    146         setupMockPackageManager(false /* default */, true /* system */, false /* external calls */);
    147         mInCallController.bindToServices(mMockCall);
    148 
    149         ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
    150         verify(mMockContext).bindServiceAsUser(
    151                 bindIntentCaptor.capture(),
    152                 any(ServiceConnection.class),
    153                 eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
    154                 eq(UserHandle.CURRENT));
    155 
    156         Intent bindIntent = bindIntentCaptor.getValue();
    157         assertEquals(InCallService.SERVICE_INTERFACE, bindIntent.getAction());
    158         assertEquals(SYS_PKG, bindIntent.getComponent().getPackageName());
    159         assertEquals(SYS_CLASS, bindIntent.getComponent().getClassName());
    160         assertNull(bindIntent.getExtras());
    161     }
    162 
    163     @MediumTest
    164     @Test
    165     public void testBindToService_NoServicesFound_OutgoingCall() throws Exception {
    166         Bundle callExtras = new Bundle();
    167         callExtras.putBoolean("whatever", true);
    168 
    169         when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
    170         when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
    171         when(mMockCallsManager.hasEmergencyCall()).thenReturn(false);
    172         when(mMockCall.isIncoming()).thenReturn(false);
    173         when(mMockCall.getTargetPhoneAccount()).thenReturn(PA_HANDLE);
    174         when(mMockCall.getIntentExtras()).thenReturn(callExtras);
    175         when(mMockCall.isExternalCall()).thenReturn(false);
    176         when(mTimeoutsAdapter.getEmergencyCallbackWindowMillis(any(ContentResolver.class)))
    177                 .thenReturn(300_000L);
    178 
    179         Intent queryIntent = new Intent(InCallService.SERVICE_INTERFACE);
    180         setupMockPackageManager(false /* default */, true /* system */, false /* external calls */);
    181         mInCallController.bindToServices(mMockCall);
    182 
    183         ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
    184         verify(mMockContext).bindServiceAsUser(
    185                 bindIntentCaptor.capture(),
    186                 any(ServiceConnection.class),
    187                 eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
    188                 eq(UserHandle.CURRENT));
    189 
    190         Intent bindIntent = bindIntentCaptor.getValue();
    191         assertEquals(InCallService.SERVICE_INTERFACE, bindIntent.getAction());
    192         assertEquals(SYS_PKG, bindIntent.getComponent().getPackageName());
    193         assertEquals(SYS_CLASS, bindIntent.getComponent().getClassName());
    194         assertEquals(PA_HANDLE, bindIntent.getExtras().getParcelable(
    195                 TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE));
    196         assertEquals(callExtras, bindIntent.getExtras().getParcelable(
    197                 TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS));
    198     }
    199 
    200     @MediumTest
    201     @Test
    202     public void testBindToService_DefaultDialer_NoEmergency() throws Exception {
    203         Bundle callExtras = new Bundle();
    204         callExtras.putBoolean("whatever", true);
    205 
    206         when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
    207         when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
    208         when(mMockCallsManager.hasEmergencyCall()).thenReturn(false);
    209         when(mMockCall.isIncoming()).thenReturn(false);
    210         when(mMockCall.getTargetPhoneAccount()).thenReturn(PA_HANDLE);
    211         when(mMockCall.getIntentExtras()).thenReturn(callExtras);
    212         when(mMockCall.isExternalCall()).thenReturn(false);
    213         when(mDefaultDialerCache.getDefaultDialerApplication(CURRENT_USER_ID))
    214                 .thenReturn(DEF_PKG);
    215         when(mMockContext.bindServiceAsUser(any(Intent.class), any(ServiceConnection.class),
    216                 anyInt(), eq(UserHandle.CURRENT))).thenReturn(true);
    217 
    218         setupMockPackageManager(true /* default */, true /* system */, false /* external calls */);
    219         mInCallController.bindToServices(mMockCall);
    220 
    221         // Query for the different InCallServices
    222         ArgumentCaptor<Intent> queryIntentCaptor = ArgumentCaptor.forClass(Intent.class);
    223         verify(mMockPackageManager, times(4)).queryIntentServicesAsUser(
    224                 queryIntentCaptor.capture(),
    225                 eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
    226 
    227         // Verify call for default dialer InCallService
    228         assertEquals(DEF_PKG, queryIntentCaptor.getAllValues().get(0).getPackage());
    229         // Verify call for car-mode InCallService
    230         assertEquals(null, queryIntentCaptor.getAllValues().get(1).getPackage());
    231         // Verify call for non-UI InCallServices
    232         assertEquals(null, queryIntentCaptor.getAllValues().get(2).getPackage());
    233 
    234         ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
    235         verify(mMockContext, times(1)).bindServiceAsUser(
    236                 bindIntentCaptor.capture(),
    237                 any(ServiceConnection.class),
    238                 eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
    239                 eq(UserHandle.CURRENT));
    240 
    241         Intent bindIntent = bindIntentCaptor.getValue();
    242         assertEquals(InCallService.SERVICE_INTERFACE, bindIntent.getAction());
    243         assertEquals(DEF_PKG, bindIntent.getComponent().getPackageName());
    244         assertEquals(DEF_CLASS, bindIntent.getComponent().getClassName());
    245         assertEquals(PA_HANDLE, bindIntent.getExtras().getParcelable(
    246                 TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE));
    247         assertEquals(callExtras, bindIntent.getExtras().getParcelable(
    248                 TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS));
    249     }
    250 
    251     @MediumTest
    252     @Test
    253     public void testBindToService_SystemDialer_Emergency() throws Exception {
    254         Bundle callExtras = new Bundle();
    255         callExtras.putBoolean("whatever", true);
    256 
    257         when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
    258         when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
    259         when(mMockCallsManager.hasEmergencyCall()).thenReturn(true);
    260         when(mMockCall.isEmergencyCall()).thenReturn(true);
    261         when(mMockCall.isIncoming()).thenReturn(false);
    262         when(mMockCall.getTargetPhoneAccount()).thenReturn(PA_HANDLE);
    263         when(mMockCall.getIntentExtras()).thenReturn(callExtras);
    264         when(mMockCall.isExternalCall()).thenReturn(false);
    265         when(mDefaultDialerCache.getDefaultDialerApplication(CURRENT_USER_ID))
    266                 .thenReturn(DEF_PKG);
    267         when(mMockContext.bindServiceAsUser(any(Intent.class), any(ServiceConnection.class),
    268                 eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
    269                 eq(UserHandle.CURRENT))).thenReturn(true);
    270         when(mTimeoutsAdapter.getEmergencyCallbackWindowMillis(any(ContentResolver.class)))
    271                 .thenReturn(300_000L);
    272 
    273         setupMockPackageManager(true /* default */, true /* system */, false /* external calls */);
    274         setupMockPackageManagerLocationPermission(SYS_PKG, false /* granted */);
    275 
    276         mInCallController.bindToServices(mMockCall);
    277 
    278         // Query for the different InCallServices
    279         ArgumentCaptor<Intent> queryIntentCaptor = ArgumentCaptor.forClass(Intent.class);
    280         verify(mMockPackageManager, times(4)).queryIntentServicesAsUser(
    281                 queryIntentCaptor.capture(),
    282                 eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
    283 
    284         // Verify call for default dialer InCallService
    285         assertEquals(DEF_PKG, queryIntentCaptor.getAllValues().get(0).getPackage());
    286         // Verify call for car-mode InCallService
    287         assertEquals(null, queryIntentCaptor.getAllValues().get(1).getPackage());
    288         // Verify call for non-UI InCallServices
    289         assertEquals(null, queryIntentCaptor.getAllValues().get(2).getPackage());
    290 
    291         ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
    292         verify(mMockContext, times(1)).bindServiceAsUser(
    293                 bindIntentCaptor.capture(),
    294                 any(ServiceConnection.class),
    295                 eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
    296                 eq(UserHandle.CURRENT));
    297 
    298         Intent bindIntent = bindIntentCaptor.getValue();
    299         assertEquals(InCallService.SERVICE_INTERFACE, bindIntent.getAction());
    300         assertEquals(SYS_PKG, bindIntent.getComponent().getPackageName());
    301         assertEquals(SYS_CLASS, bindIntent.getComponent().getClassName());
    302         assertEquals(PA_HANDLE, bindIntent.getExtras().getParcelable(
    303                 TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE));
    304         assertEquals(callExtras, bindIntent.getExtras().getParcelable(
    305                 TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS));
    306 
    307         verify(mMockPackageManager).grantRuntimePermission(eq(SYS_PKG),
    308                 eq(Manifest.permission.ACCESS_FINE_LOCATION), eq(mUserHandle));
    309 
    310         // Pretend that the call has gone away.
    311         when(mMockCallsManager.getCalls()).thenReturn(Collections.emptyList());
    312         mInCallController.onCallRemoved(mMockCall);
    313         waitForHandlerAction(new Handler(Looper.getMainLooper()), TelecomSystemTest.TEST_TIMEOUT);
    314 
    315         verify(mMockPackageManager).revokeRuntimePermission(eq(SYS_PKG),
    316                 eq(Manifest.permission.ACCESS_FINE_LOCATION), eq(mUserHandle));
    317     }
    318 
    319     @MediumTest
    320     @Test
    321     public void testBindToService_DefaultDialer_FallBackToSystem() throws Exception {
    322         Bundle callExtras = new Bundle();
    323         callExtras.putBoolean("whatever", true);
    324 
    325         when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
    326         when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
    327         when(mMockCallsManager.hasEmergencyCall()).thenReturn(false);
    328         when(mMockCallsManager.getCalls()).thenReturn(Collections.singletonList(mMockCall));
    329         when(mMockCallsManager.getAudioState()).thenReturn(null);
    330         when(mMockCallsManager.canAddCall()).thenReturn(false);
    331         when(mMockCall.isIncoming()).thenReturn(false);
    332         when(mMockCall.getTargetPhoneAccount()).thenReturn(PA_HANDLE);
    333         when(mMockCall.getIntentExtras()).thenReturn(callExtras);
    334         when(mMockCall.isExternalCall()).thenReturn(false);
    335         when(mMockCall.getConferenceableCalls()).thenReturn(Collections.emptyList());
    336         when(mDefaultDialerCache.getDefaultDialerApplication(CURRENT_USER_ID))
    337                 .thenReturn(DEF_PKG);
    338         when(mMockContext.bindServiceAsUser(
    339                 any(Intent.class), any(ServiceConnection.class), anyInt(), any(UserHandle.class)))
    340                 .thenReturn(true);
    341 
    342         setupMockPackageManager(true /* default */, true /* system */, false /* external calls */);
    343         mInCallController.bindToServices(mMockCall);
    344 
    345         // Query for the different InCallServices
    346         ArgumentCaptor<Intent> queryIntentCaptor = ArgumentCaptor.forClass(Intent.class);
    347         verify(mMockPackageManager, times(4)).queryIntentServicesAsUser(
    348                 queryIntentCaptor.capture(),
    349                 eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
    350 
    351         // Verify call for default dialer InCallService
    352         assertEquals(DEF_PKG, queryIntentCaptor.getAllValues().get(0).getPackage());
    353         // Verify call for car-mode InCallService
    354         assertEquals(null, queryIntentCaptor.getAllValues().get(1).getPackage());
    355         // Verify call for non-UI InCallServices
    356         assertEquals(null, queryIntentCaptor.getAllValues().get(2).getPackage());
    357 
    358         ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
    359         ArgumentCaptor<ServiceConnection> serviceConnectionCaptor =
    360                 ArgumentCaptor.forClass(ServiceConnection.class);
    361         verify(mMockContext, times(1)).bindServiceAsUser(
    362                 bindIntentCaptor.capture(),
    363                 serviceConnectionCaptor.capture(),
    364                 eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
    365                 eq(UserHandle.CURRENT));
    366 
    367         Intent bindIntent = bindIntentCaptor.getValue();
    368         assertEquals(InCallService.SERVICE_INTERFACE, bindIntent.getAction());
    369         assertEquals(DEF_PKG, bindIntent.getComponent().getPackageName());
    370         assertEquals(DEF_CLASS, bindIntent.getComponent().getClassName());
    371         assertEquals(PA_HANDLE, bindIntent.getExtras().getParcelable(
    372                 TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE));
    373         assertEquals(callExtras, bindIntent.getExtras().getParcelable(
    374                 TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS));
    375 
    376         // We have a ServiceConnection for the default dialer, lets start the connection, and then
    377         // simulate a crash so that we fallback to system.
    378         ServiceConnection serviceConnection = serviceConnectionCaptor.getValue();
    379         ComponentName defDialerComponentName = new ComponentName(DEF_PKG, DEF_CLASS);
    380         IBinder mockBinder = mock(IBinder.class);
    381         IInCallService mockInCallService = mock(IInCallService.class);
    382         when(mockBinder.queryLocalInterface(anyString())).thenReturn(mockInCallService);
    383 
    384 
    385         // Start the connection with IInCallService
    386         serviceConnection.onServiceConnected(defDialerComponentName, mockBinder);
    387         verify(mockInCallService).setInCallAdapter(any(IInCallAdapter.class));
    388 
    389         // Now crash the damn thing!
    390         serviceConnection.onServiceDisconnected(defDialerComponentName);
    391 
    392         ArgumentCaptor<Intent> bindIntentCaptor2 = ArgumentCaptor.forClass(Intent.class);
    393         verify(mMockContext, times(2)).bindServiceAsUser(
    394                 bindIntentCaptor2.capture(),
    395                 any(ServiceConnection.class),
    396                 eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
    397                 eq(UserHandle.CURRENT));
    398 
    399         bindIntent = bindIntentCaptor2.getValue();
    400         assertEquals(SYS_PKG, bindIntent.getComponent().getPackageName());
    401         assertEquals(SYS_CLASS, bindIntent.getComponent().getClassName());
    402     }
    403 
    404     /**
    405      * Ensures that the {@link InCallController} will bind to an {@link InCallService} which
    406      * supports external calls.
    407      */
    408     @MediumTest
    409     @Test
    410     public void testBindToService_IncludeExternal() throws Exception {
    411         setupMocks(true /* isExternalCall */);
    412         setupMockPackageManager(true /* default */, true /* system */, true /* external calls */);
    413         mInCallController.bindToServices(mMockCall);
    414 
    415         // Query for the different InCallServices
    416         ArgumentCaptor<Intent> queryIntentCaptor = ArgumentCaptor.forClass(Intent.class);
    417         verify(mMockPackageManager, times(4)).queryIntentServicesAsUser(
    418                 queryIntentCaptor.capture(),
    419                 eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
    420 
    421         // Verify call for default dialer InCallService
    422         assertEquals(DEF_PKG, queryIntentCaptor.getAllValues().get(0).getPackage());
    423         // Verify call for car-mode InCallService
    424         assertEquals(null, queryIntentCaptor.getAllValues().get(1).getPackage());
    425         // Verify call for non-UI InCallServices
    426         assertEquals(null, queryIntentCaptor.getAllValues().get(2).getPackage());
    427 
    428         ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
    429         verify(mMockContext, times(1)).bindServiceAsUser(
    430                 bindIntentCaptor.capture(),
    431                 any(ServiceConnection.class),
    432                 eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
    433                 eq(UserHandle.CURRENT));
    434 
    435         Intent bindIntent = bindIntentCaptor.getValue();
    436         assertEquals(InCallService.SERVICE_INTERFACE, bindIntent.getAction());
    437         assertEquals(DEF_PKG, bindIntent.getComponent().getPackageName());
    438         assertEquals(DEF_CLASS, bindIntent.getComponent().getClassName());
    439     }
    440 
    441     /**
    442      * Make sure that if a call goes away before the in-call service finishes binding and another
    443      * call gets connected soon after, the new call will still be sent to the in-call service.
    444      */
    445     @MediumTest
    446     @Test
    447     public void testUnbindDueToCallDisconnect() throws Exception {
    448         when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
    449         when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
    450         when(mMockCallsManager.hasEmergencyCall()).thenReturn(false);
    451         when(mMockCall.isIncoming()).thenReturn(true);
    452         when(mMockCall.isExternalCall()).thenReturn(false);
    453         when(mDefaultDialerCache.getDefaultDialerApplication(CURRENT_USER_ID)).thenReturn(DEF_PKG);
    454         when(mMockContext.bindServiceAsUser(nullable(Intent.class),
    455                 nullable(ServiceConnection.class), anyInt(), nullable(UserHandle.class)))
    456                 .thenReturn(true);
    457         when(mTimeoutsAdapter.getCallRemoveUnbindInCallServicesDelay(
    458                 nullable(ContentResolver.class))).thenReturn(500L);
    459 
    460         when(mMockCallsManager.getCalls()).thenReturn(Collections.singletonList(mMockCall));
    461         setupMockPackageManager(true /* default */, true /* system */, false /* external calls */);
    462         mInCallController.bindToServices(mMockCall);
    463 
    464         ArgumentCaptor<Intent> bindIntentCaptor = ArgumentCaptor.forClass(Intent.class);
    465         ArgumentCaptor<ServiceConnection> serviceConnectionCaptor =
    466                 ArgumentCaptor.forClass(ServiceConnection.class);
    467         verify(mMockContext, times(1)).bindServiceAsUser(
    468                 bindIntentCaptor.capture(),
    469                 serviceConnectionCaptor.capture(),
    470                 eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
    471                 eq(UserHandle.CURRENT));
    472 
    473         // Pretend that the call has gone away.
    474         when(mMockCallsManager.getCalls()).thenReturn(Collections.emptyList());
    475         mInCallController.onCallRemoved(mMockCall);
    476 
    477         // Start the connection, make sure we don't unbind, and make sure that we don't send
    478         // anything to the in-call service yet.
    479         ServiceConnection serviceConnection = serviceConnectionCaptor.getValue();
    480         ComponentName defDialerComponentName = new ComponentName(DEF_PKG, DEF_CLASS);
    481         IBinder mockBinder = mock(IBinder.class);
    482         IInCallService mockInCallService = mock(IInCallService.class);
    483         when(mockBinder.queryLocalInterface(anyString())).thenReturn(mockInCallService);
    484 
    485         serviceConnection.onServiceConnected(defDialerComponentName, mockBinder);
    486         verify(mockInCallService).setInCallAdapter(nullable(IInCallAdapter.class));
    487         verify(mMockContext, never()).unbindService(serviceConnection);
    488         verify(mockInCallService, never()).addCall(any(ParcelableCall.class));
    489 
    490         // Now, we add in the call again and make sure that it's sent to the InCallService.
    491         when(mMockCallsManager.getCalls()).thenReturn(Collections.singletonList(mMockCall));
    492         mInCallController.onCallAdded(mMockCall);
    493         verify(mockInCallService).addCall(any(ParcelableCall.class));
    494     }
    495 
    496     private void setupMocks(boolean isExternalCall) {
    497         when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
    498         when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
    499         when(mMockCallsManager.hasEmergencyCall()).thenReturn(false);
    500         when(mMockCall.isIncoming()).thenReturn(false);
    501         when(mMockCall.getTargetPhoneAccount()).thenReturn(PA_HANDLE);
    502         when(mDefaultDialerCache.getDefaultDialerApplication(CURRENT_USER_ID)).thenReturn(DEF_PKG);
    503         when(mMockContext.bindServiceAsUser(any(Intent.class), any(ServiceConnection.class),
    504                 anyInt(), eq(UserHandle.CURRENT))).thenReturn(true);
    505         when(mMockCall.isExternalCall()).thenReturn(isExternalCall);
    506     }
    507 
    508     private ResolveInfo getDefResolveInfo(final boolean includeExternalCalls) {
    509         return new ResolveInfo() {{
    510             serviceInfo = new ServiceInfo();
    511             serviceInfo.packageName = DEF_PKG;
    512             serviceInfo.name = DEF_CLASS;
    513             serviceInfo.permission = Manifest.permission.BIND_INCALL_SERVICE;
    514             serviceInfo.metaData = new Bundle();
    515             serviceInfo.metaData.putBoolean(
    516                     TelecomManager.METADATA_IN_CALL_SERVICE_UI, true);
    517             if (includeExternalCalls) {
    518                 serviceInfo.metaData.putBoolean(
    519                         TelecomManager.METADATA_INCLUDE_EXTERNAL_CALLS, true);
    520             }
    521         }};
    522     }
    523 
    524     private ResolveInfo getSysResolveinfo() {
    525         return new ResolveInfo() {{
    526             serviceInfo = new ServiceInfo();
    527             serviceInfo.packageName = SYS_PKG;
    528             serviceInfo.name = SYS_CLASS;
    529             serviceInfo.permission = Manifest.permission.BIND_INCALL_SERVICE;
    530         }};
    531     }
    532 
    533     private void setupMockPackageManager(final boolean useDefaultDialer,
    534             final boolean useSystemDialer, final boolean includeExternalCalls) {
    535 
    536         doAnswer(new Answer() {
    537             @Override
    538             public Object answer(InvocationOnMock invocation) throws Throwable {
    539                 Object[] args = invocation.getArguments();
    540                 Intent intent = (Intent) args[0];
    541                 String packageName = intent.getPackage();
    542                 ComponentName componentName = intent.getComponent();
    543                 if (componentName != null) {
    544                     packageName = componentName.getPackageName();
    545                 }
    546                 LinkedList<ResolveInfo> resolveInfo = new LinkedList<ResolveInfo>();
    547                 if (!TextUtils.isEmpty(packageName)) {
    548                     if ((TextUtils.isEmpty(packageName) || packageName.equals(DEF_PKG)) &&
    549                             useDefaultDialer) {
    550                         resolveInfo.add(getDefResolveInfo(includeExternalCalls));
    551                     }
    552 
    553                     if ((TextUtils.isEmpty(packageName) || packageName.equals(SYS_PKG)) &&
    554                            useSystemDialer) {
    555                         resolveInfo.add(getSysResolveinfo());
    556                     }
    557                 }
    558                 return resolveInfo;
    559             }
    560         }).when(mMockPackageManager).queryIntentServicesAsUser(
    561                 any(Intent.class), eq(PackageManager.GET_META_DATA), eq(CURRENT_USER_ID));
    562     }
    563 
    564     private void setupMockPackageManagerLocationPermission(final String pkg,
    565             final boolean granted) {
    566         when(mMockPackageManager.checkPermission(Manifest.permission.ACCESS_FINE_LOCATION, pkg))
    567                 .thenReturn(granted
    568                         ? PackageManager.PERMISSION_GRANTED
    569                         : PackageManager.PERMISSION_DENIED);
    570   }
    571 }
    572