blob: d3db9c6c191d79f24ee7e7ababeaf6a900074235 [file] [log] [blame]
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.bluetooth.hfp;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
import android.bluetooth.BluetoothAdapter;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Binder;
import android.os.IBinder;
import android.telecom.Call;
import android.telecom.Connection;
import android.telecom.GatewayInfo;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
import android.telephony.PhoneNumberUtils;
import android.telephony.TelephonyManager;
import android.util.Log;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.rule.ServiceTestRule;
import androidx.test.filters.MediumTest;
import androidx.test.runner.AndroidJUnit4;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
/**
* Tests for {@link BluetoothInCallService}
*/
@MediumTest
@RunWith(AndroidJUnit4.class)
public class BluetoothInCallServiceTest {
private static final int TEST_DTMF_TONE = 0;
private static final String TEST_ACCOUNT_ADDRESS = "//foo.com/";
private static final int TEST_ACCOUNT_INDEX = 0;
private static final int CALL_STATE_ACTIVE = 0;
private static final int CALL_STATE_HELD = 1;
private static final int CALL_STATE_DIALING = 2;
private static final int CALL_STATE_ALERTING = 3;
private static final int CALL_STATE_INCOMING = 4;
private static final int CALL_STATE_WAITING = 5;
private static final int CALL_STATE_IDLE = 6;
private static final int CALL_STATE_DISCONNECTED = 7;
// Terminate all held or set UDUB("busy") to a waiting call
private static final int CHLD_TYPE_RELEASEHELD = 0;
// Terminate all active calls and accepts a waiting/held call
private static final int CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD = 1;
// Hold all active calls and accepts a waiting/held call
private static final int CHLD_TYPE_HOLDACTIVE_ACCEPTHELD = 2;
// Add all held calls to a conference
private static final int CHLD_TYPE_ADDHELDTOCONF = 3;
private TestableBluetoothInCallService mBluetoothInCallService;
@Rule public final ServiceTestRule mServiceRule
= ServiceTestRule.withTimeout(1, TimeUnit.SECONDS);
@Mock private BluetoothHeadsetProxy mMockBluetoothHeadset;
@Mock private BluetoothInCallService.CallInfo mMockCallInfo;
@Mock private TelephonyManager mMockTelephonyManager;
public class TestableBluetoothInCallService extends BluetoothInCallService {
@Override
public IBinder onBind(Intent intent) {
IBinder binder = super.onBind(intent);
IntentFilter intentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
registerReceiver(mBluetoothAdapterReceiver, intentFilter);
mTelephonyManager = getSystemService(TelephonyManager.class);
mTelecomManager = getSystemService(TelecomManager.class);
return binder;
}
@Override
protected void enforceModifyPermission() {}
}
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
// Create the service Intent.
Intent serviceIntent =
new Intent(ApplicationProvider.getApplicationContext(),
TestableBluetoothInCallService.class);
// Bind the service
mServiceRule.bindService(serviceIntent);
// Ensure initialization does not actually try to access any of the CallsManager fields.
// This also works to return null if it is not overwritten later in the test.
doReturn(null).when(mMockCallInfo).getActiveCall();
doReturn(null).when(mMockCallInfo)
.getRingingOrSimulatedRingingCall();
doReturn(null).when(mMockCallInfo).getHeldCall();
doReturn(null).when(mMockCallInfo).getOutgoingCall();
doReturn(0).when(mMockCallInfo).getNumHeldCalls();
doReturn(false).when(mMockCallInfo).hasOnlyDisconnectedCalls();
doReturn(true).when(mMockCallInfo).isNullCall(null);
doReturn(false).when(mMockCallInfo).isNullCall(notNull());
mBluetoothInCallService = new TestableBluetoothInCallService();
mBluetoothInCallService.setBluetoothHeadset(mMockBluetoothHeadset);
mBluetoothInCallService.mCallInfo = mMockCallInfo;
}
@After
public void tearDown() throws Exception {
mServiceRule.unbindService();
mBluetoothInCallService = null;
}
@Test
public void testHeadsetAnswerCall() throws Exception {
BluetoothCall mockCall = createRingingCall();
boolean callAnswered = mBluetoothInCallService.answerCall();
verify(mockCall).answer(any(int.class));
Assert.assertTrue(callAnswered);
}
@Test
public void testHeadsetAnswerCallNull() throws Exception {
when(mMockCallInfo.getRingingOrSimulatedRingingCall()).thenReturn(null);
boolean callAnswered = mBluetoothInCallService.answerCall();
Assert.assertFalse(callAnswered);
}
@Test
public void testHeadsetHangupCall() throws Exception {
BluetoothCall mockCall = createForegroundCall();
boolean callHungup = mBluetoothInCallService.hangupCall();
verify(mockCall).disconnect();
Assert.assertTrue(callHungup);
}
@Test
public void testHeadsetHangupCallNull() throws Exception {
when(mMockCallInfo.getForegroundCall()).thenReturn(null);
boolean callHungup = mBluetoothInCallService.hangupCall();
Assert.assertFalse(callHungup);
}
@Test
public void testHeadsetSendDTMF() throws Exception {
BluetoothCall mockCall = createForegroundCall();
boolean sentDtmf = mBluetoothInCallService.sendDtmf(TEST_DTMF_TONE);
verify(mockCall).playDtmfTone(eq((char) TEST_DTMF_TONE));
verify(mockCall).stopDtmfTone();
Assert.assertTrue(sentDtmf);
}
@Test
public void testHeadsetSendDTMFNull() throws Exception {
when(mMockCallInfo.getForegroundCall()).thenReturn(null);
boolean sentDtmf = mBluetoothInCallService.sendDtmf(TEST_DTMF_TONE);
Assert.assertFalse(sentDtmf);
}
@Test
public void testGetNetworkOperator() throws Exception {
PhoneAccount fakePhoneAccount = makeQuickAccount("id0", TEST_ACCOUNT_INDEX);
when(mMockCallInfo.getBestPhoneAccount()).thenReturn(fakePhoneAccount);
String networkOperator = mBluetoothInCallService.getNetworkOperator();
Assert.assertEquals(networkOperator, "label0");
}
@Test
public void testGetNetworkOperatorNoPhoneAccount() throws Exception {
when(mMockCallInfo.getForegroundCall()).thenReturn(null);
when(mMockTelephonyManager.getNetworkOperatorName()).thenReturn("label1");
mBluetoothInCallService.mTelephonyManager = mMockTelephonyManager;
String networkOperator = mBluetoothInCallService.getNetworkOperator();
Assert.assertEquals(networkOperator, "label1");
}
@Test
public void testGetSubscriberNumber() throws Exception {
PhoneAccount fakePhoneAccount = makeQuickAccount("id0", TEST_ACCOUNT_INDEX);
when(mMockCallInfo.getBestPhoneAccount()).thenReturn(fakePhoneAccount);
String subscriberNumber = mBluetoothInCallService.getSubscriberNumber();
Assert.assertEquals(subscriberNumber, TEST_ACCOUNT_ADDRESS + TEST_ACCOUNT_INDEX);
}
@Test
public void testGetSubscriberNumberFallbackToTelephony() throws Exception {
String fakeNumber = "8675309";
when(mMockCallInfo.getBestPhoneAccount()).thenReturn(null);
when(mMockTelephonyManager.getLine1Number())
.thenReturn(fakeNumber);
mBluetoothInCallService.mTelephonyManager = mMockTelephonyManager;
String subscriberNumber = mBluetoothInCallService.getSubscriberNumber();
Assert.assertEquals(subscriberNumber, fakeNumber);
}
@Test
public void testListCurrentCallsOneCall() throws Exception {
ArrayList<BluetoothCall> calls = new ArrayList<>();
BluetoothCall activeCall = createActiveCall();
when(activeCall.getState()).thenReturn(Call.STATE_ACTIVE);
calls.add(activeCall);
mBluetoothInCallService.onCallAdded(activeCall);
when(activeCall.isConference()).thenReturn(false);
when(activeCall.getHandle()).thenReturn(Uri.parse("tel:555-000"));
when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls);
clearInvocations(mMockBluetoothHeadset);
mBluetoothInCallService.listCurrentCalls();
verify(mMockBluetoothHeadset).clccResponse(eq(1), eq(0), eq(0), eq(0), eq(false),
eq("555000"), eq(PhoneNumberUtils.TOA_Unknown));
verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
}
@Test
public void testListCurrentCallsSilentRinging() throws Exception {
ArrayList<BluetoothCall> calls = new ArrayList<>();
BluetoothCall silentRingingCall = createActiveCall();
when(silentRingingCall.getState()).thenReturn(Call.STATE_RINGING);
when(silentRingingCall.isSilentRingingRequested()).thenReturn(true);
calls.add(silentRingingCall);
mBluetoothInCallService.onCallAdded(silentRingingCall);
when(silentRingingCall.isConference()).thenReturn(false);
when(silentRingingCall.getHandle()).thenReturn(Uri.parse("tel:555-000"));
when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls);
when(mMockCallInfo.getRingingOrSimulatedRingingCall()).thenReturn(silentRingingCall);
clearInvocations(mMockBluetoothHeadset);
mBluetoothInCallService.listCurrentCalls();
verify(mMockBluetoothHeadset, never()).clccResponse(eq(1), eq(0), eq(0), eq(0), eq(false),
eq("555000"), eq(PhoneNumberUtils.TOA_Unknown));
verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
}
@Test
public void testConferenceInProgressCDMA() throws Exception {
// If two calls are being conferenced and updateHeadsetWithCallState runs while this is
// still occurring, it will look like there is an active and held BluetoothCall still while
// we are transitioning into a conference.
// BluetoothCall has been put into a CDMA "conference" with one BluetoothCall on hold.
ArrayList<BluetoothCall> calls = new ArrayList<>();
BluetoothCall parentCall = createActiveCall();
final BluetoothCall confCall1 = getMockCall();
final BluetoothCall confCall2 = createHeldCall();
calls.add(parentCall);
calls.add(confCall1);
calls.add(confCall2);
mBluetoothInCallService.onCallAdded(parentCall);
mBluetoothInCallService.onCallAdded(confCall1);
mBluetoothInCallService.onCallAdded(confCall2);
when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls);
when(confCall1.getState()).thenReturn(Call.STATE_ACTIVE);
when(confCall2.getState()).thenReturn(Call.STATE_ACTIVE);
when(confCall1.isIncoming()).thenReturn(false);
when(confCall2.isIncoming()).thenReturn(true);
when(confCall1.getGatewayInfo()).thenReturn(
new GatewayInfo(null, null, Uri.parse("tel:555-0000")));
when(confCall2.getGatewayInfo()).thenReturn(
new GatewayInfo(null, null, Uri.parse("tel:555-0001")));
addCallCapability(parentCall, Connection.CAPABILITY_MERGE_CONFERENCE);
addCallCapability(parentCall, Connection.CAPABILITY_SWAP_CONFERENCE);
removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
String confCall1Id = confCall1.getTelecomCallId();
when(parentCall.getGenericConferenceActiveChildCallId())
.thenReturn(confCall1Id);
when(parentCall.isConference()).thenReturn(true);
List<String> childrenIds = new LinkedList<String>(){{
add(confCall1.getTelecomCallId());
add(confCall2.getTelecomCallId());
}};
when(parentCall.getChildrenIds()).thenReturn(childrenIds);
//Add links from child calls to parent
String parentId = parentCall.getTelecomCallId();
when(confCall1.getParentId()).thenReturn(parentId);
when(confCall2.getParentId()).thenReturn(parentId);
clearInvocations(mMockBluetoothHeadset);
mBluetoothInCallService.queryPhoneState();
verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(1), eq(CALL_STATE_IDLE),
eq(""), eq(128), nullable(String.class));
when(parentCall.wasConferencePreviouslyMerged()).thenReturn(true);
List<BluetoothCall> children =
mBluetoothInCallService.getBluetoothCallsByIds(parentCall.getChildrenIds());
mBluetoothInCallService.getCallback(parentCall)
.onChildrenChanged(parentCall, children);
verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(0), eq(CALL_STATE_IDLE),
eq(""), eq(128), nullable(String.class));
when(mMockCallInfo.getHeldCall()).thenReturn(null);
// Spurious BluetoothCall to onIsConferencedChanged.
mBluetoothInCallService.getCallback(parentCall)
.onChildrenChanged(parentCall, children);
// Make sure the BluetoothCall has only occurred collectively 2 times (not on the third)
verify(mMockBluetoothHeadset, times(2)).phoneStateChanged(any(int.class),
any(int.class), any(int.class), nullable(String.class), any(int.class),
nullable(String.class));
}
@Test
public void testListCurrentCallsCdmaHold() throws Exception {
// BluetoothCall has been put into a CDMA "conference" with one BluetoothCall on hold.
List<BluetoothCall> calls = new ArrayList<BluetoothCall>();
BluetoothCall parentCall = createActiveCall();
final BluetoothCall foregroundCall = getMockCall();
final BluetoothCall heldCall = createHeldCall();
calls.add(parentCall);
calls.add(foregroundCall);
calls.add(heldCall);
mBluetoothInCallService.onCallAdded(parentCall);
mBluetoothInCallService.onCallAdded(foregroundCall);
mBluetoothInCallService.onCallAdded(heldCall);
when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls);
when(foregroundCall.getState()).thenReturn(Call.STATE_ACTIVE);
when(heldCall.getState()).thenReturn(Call.STATE_ACTIVE);
when(foregroundCall.isIncoming()).thenReturn(false);
when(heldCall.isIncoming()).thenReturn(true);
when(foregroundCall.getGatewayInfo()).thenReturn(
new GatewayInfo(null, null, Uri.parse("tel:555-0000")));
when(heldCall.getGatewayInfo()).thenReturn(
new GatewayInfo(null, null, Uri.parse("tel:555-0001")));
addCallCapability(parentCall, Connection.CAPABILITY_MERGE_CONFERENCE);
addCallCapability(parentCall, Connection.CAPABILITY_SWAP_CONFERENCE);
removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
String foregroundCallId = foregroundCall.getTelecomCallId();
when(parentCall.getGenericConferenceActiveChildCallId()).thenReturn(foregroundCallId);
when(parentCall.isConference()).thenReturn(true);
List<String> childrenIds = new LinkedList<String>(){{
add(foregroundCall.getTelecomCallId());
add(heldCall.getTelecomCallId());
}};
when(parentCall.getChildrenIds()).thenReturn(childrenIds);
//Add links from child calls to parent
String parentId = parentCall.getTelecomCallId();
when(foregroundCall.getParentId()).thenReturn(parentId);
when(heldCall.getParentId()).thenReturn(parentId);
clearInvocations(mMockBluetoothHeadset);
mBluetoothInCallService.listCurrentCalls();
verify(mMockBluetoothHeadset).clccResponse(eq(1), eq(0), eq(CALL_STATE_ACTIVE), eq(0),
eq(false), eq("5550000"), eq(PhoneNumberUtils.TOA_Unknown));
verify(mMockBluetoothHeadset).clccResponse(eq(2), eq(1), eq(CALL_STATE_HELD), eq(0),
eq(false), eq("5550001"), eq(PhoneNumberUtils.TOA_Unknown));
verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
}
@Test
public void testListCurrentCallsCdmaConference() throws Exception {
// BluetoothCall is in a true CDMA conference
ArrayList<BluetoothCall> calls = new ArrayList<>();
BluetoothCall parentCall = createActiveCall();
final BluetoothCall confCall1 = getMockCall();
final BluetoothCall confCall2 = createHeldCall();
calls.add(parentCall);
calls.add(confCall1);
calls.add(confCall2);
mBluetoothInCallService.onCallAdded(parentCall);
mBluetoothInCallService.onCallAdded(confCall1);
mBluetoothInCallService.onCallAdded(confCall2);
when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls);
when(confCall1.getState()).thenReturn(Call.STATE_ACTIVE);
when(confCall2.getState()).thenReturn(Call.STATE_ACTIVE);
when(confCall1.isIncoming()).thenReturn(false);
when(confCall2.isIncoming()).thenReturn(true);
when(confCall1.getGatewayInfo()).thenReturn(
new GatewayInfo(null, null, Uri.parse("tel:555-0000")));
when(confCall2.getGatewayInfo()).thenReturn(
new GatewayInfo(null, null, Uri.parse("tel:555-0001")));
removeCallCapability(parentCall, Connection.CAPABILITY_MERGE_CONFERENCE);
removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
when(parentCall.wasConferencePreviouslyMerged()).thenReturn(true);
//when(parentCall.getConferenceLevelActiveCall()).thenReturn(confCall1);
when(parentCall.isConference()).thenReturn(true);
List<String> childrenIds = new LinkedList<String>(){{
add(confCall1.getTelecomCallId());
add(confCall2.getTelecomCallId());
}};
when(parentCall.getChildrenIds()).thenReturn(childrenIds);
//Add links from child calls to parent
String parentId = parentCall.getTelecomCallId();
when(confCall1.getParentId()).thenReturn(parentId);
when(confCall2.getParentId()).thenReturn(parentId);
clearInvocations(mMockBluetoothHeadset);
mBluetoothInCallService.listCurrentCalls();
verify(mMockBluetoothHeadset).clccResponse(eq(1), eq(0), eq(CALL_STATE_ACTIVE), eq(0),
eq(true), eq("5550000"), eq(PhoneNumberUtils.TOA_Unknown));
verify(mMockBluetoothHeadset).clccResponse(eq(2), eq(1), eq(CALL_STATE_ACTIVE), eq(0),
eq(true), eq("5550001"), eq(PhoneNumberUtils.TOA_Unknown));
verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
}
@Test
public void testWaitingCallClccResponse() throws Exception {
ArrayList<BluetoothCall> calls = new ArrayList<>();
when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls);
// This test does not define a value for getForegroundCall(), so this ringing
// BluetoothCall will be treated as if it is a waiting BluetoothCall
// when listCurrentCalls() is invoked.
BluetoothCall waitingCall = createRingingCall();
calls.add(waitingCall);
mBluetoothInCallService.onCallAdded(waitingCall);
when(waitingCall.isIncoming()).thenReturn(true);
when(waitingCall.getGatewayInfo()).thenReturn(
new GatewayInfo(null, null, Uri.parse("tel:555-0000")));
when(waitingCall.getState()).thenReturn(Call.STATE_RINGING);
when(waitingCall.isConference()).thenReturn(false);
clearInvocations(mMockBluetoothHeadset);
mBluetoothInCallService.listCurrentCalls();
verify(mMockBluetoothHeadset).clccResponse(1, 1, CALL_STATE_WAITING, 0, false,
"5550000", PhoneNumberUtils.TOA_Unknown);
verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
verify(mMockBluetoothHeadset, times(2)).clccResponse(anyInt(),
anyInt(), anyInt(), anyInt(), anyBoolean(), nullable(String.class), anyInt());
}
@Test
public void testNewCallClccResponse() throws Exception {
ArrayList<BluetoothCall> calls = new ArrayList<>();
when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls);
BluetoothCall newCall = createForegroundCall();
calls.add(newCall);
mBluetoothInCallService.onCallAdded(newCall);
when(newCall.getState()).thenReturn(Call.STATE_NEW);
when(newCall.isConference()).thenReturn(false);
clearInvocations(mMockBluetoothHeadset);
mBluetoothInCallService.listCurrentCalls();
verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
verify(mMockBluetoothHeadset, times(1)).clccResponse(anyInt(),
anyInt(), anyInt(), anyInt(), anyBoolean(), nullable(String.class), anyInt());
}
@Test
public void testRingingCallClccResponse() throws Exception {
ArrayList<BluetoothCall> calls = new ArrayList<>();
when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls);
BluetoothCall ringingCall = createForegroundCall();
calls.add(ringingCall);
mBluetoothInCallService.onCallAdded(ringingCall);
when(ringingCall.getState()).thenReturn(Call.STATE_RINGING);
when(ringingCall.isIncoming()).thenReturn(true);
when(ringingCall.isConference()).thenReturn(false);
when(ringingCall.getGatewayInfo()).thenReturn(
new GatewayInfo(null, null, Uri.parse("tel:555-0000")));
clearInvocations(mMockBluetoothHeadset);
mBluetoothInCallService.listCurrentCalls();
verify(mMockBluetoothHeadset).clccResponse(1, 1, CALL_STATE_INCOMING, 0, false,
"5550000", PhoneNumberUtils.TOA_Unknown);
verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
verify(mMockBluetoothHeadset, times(2)).clccResponse(anyInt(),
anyInt(), anyInt(), anyInt(), anyBoolean(), nullable(String.class), anyInt());
}
@Test
public void testCallClccCache() throws Exception {
ArrayList<BluetoothCall> calls = new ArrayList<>();
when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls);
BluetoothCall ringingCall = createForegroundCall();
calls.add(ringingCall);
mBluetoothInCallService.onCallAdded(ringingCall);
when(ringingCall.getState()).thenReturn(Call.STATE_RINGING);
when(ringingCall.isIncoming()).thenReturn(true);
when(ringingCall.isConference()).thenReturn(false);
when(ringingCall.getGatewayInfo()).thenReturn(
new GatewayInfo(null, null, Uri.parse("tel:5550000")));
clearInvocations(mMockBluetoothHeadset);
mBluetoothInCallService.listCurrentCalls();
verify(mMockBluetoothHeadset).clccResponse(1, 1, CALL_STATE_INCOMING, 0, false,
"5550000", PhoneNumberUtils.TOA_Unknown);
// Test Caching of old BluetoothCall indices in clcc
when(ringingCall.getState()).thenReturn(Call.STATE_ACTIVE);
BluetoothCall newHoldingCall = createHeldCall();
calls.add(0, newHoldingCall);
mBluetoothInCallService.onCallAdded(newHoldingCall);
when(newHoldingCall.getState()).thenReturn(Call.STATE_HOLDING);
when(newHoldingCall.isIncoming()).thenReturn(true);
when(newHoldingCall.isConference()).thenReturn(false);
when(newHoldingCall.getGatewayInfo()).thenReturn(
new GatewayInfo(null, null, Uri.parse("tel:555-0001")));
mBluetoothInCallService.listCurrentCalls();
verify(mMockBluetoothHeadset).clccResponse(1, 1, CALL_STATE_ACTIVE, 0, false,
"5550000", PhoneNumberUtils.TOA_Unknown);
verify(mMockBluetoothHeadset).clccResponse(2, 1, CALL_STATE_HELD, 0, false,
"5550001", PhoneNumberUtils.TOA_Unknown);
verify(mMockBluetoothHeadset, times(2)).clccResponse(0, 0, 0, 0, false, null, 0);
}
@Test
public void testAlertingCallClccResponse() throws Exception {
ArrayList<BluetoothCall> calls = new ArrayList<>();
when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls);
BluetoothCall dialingCall = createForegroundCall();
calls.add(dialingCall);
mBluetoothInCallService.onCallAdded(dialingCall);
when(dialingCall.getState()).thenReturn(Call.STATE_DIALING);
when(dialingCall.isIncoming()).thenReturn(false);
when(dialingCall.isConference()).thenReturn(false);
when(dialingCall.getGatewayInfo()).thenReturn(
new GatewayInfo(null, null, Uri.parse("tel:555-0000")));
clearInvocations(mMockBluetoothHeadset);
mBluetoothInCallService.listCurrentCalls();
verify(mMockBluetoothHeadset).clccResponse(1, 0, CALL_STATE_ALERTING, 0, false,
"5550000", PhoneNumberUtils.TOA_Unknown);
verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
verify(mMockBluetoothHeadset, times(2)).clccResponse(anyInt(),
anyInt(), anyInt(), anyInt(), anyBoolean(), nullable(String.class), anyInt());
}
@Test
public void testHoldingCallClccResponse() throws Exception {
ArrayList<BluetoothCall> calls = new ArrayList<>();
when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls);
BluetoothCall dialingCall = createForegroundCall();
calls.add(dialingCall);
mBluetoothInCallService.onCallAdded(dialingCall);
when(dialingCall.getState()).thenReturn(Call.STATE_DIALING);
when(dialingCall.isIncoming()).thenReturn(false);
when(dialingCall.isConference()).thenReturn(false);
when(dialingCall.getGatewayInfo()).thenReturn(
new GatewayInfo(null, null, Uri.parse("tel:555-0000")));
BluetoothCall holdingCall = createHeldCall();
calls.add(holdingCall);
mBluetoothInCallService.onCallAdded(holdingCall);
when(holdingCall.getState()).thenReturn(Call.STATE_HOLDING);
when(holdingCall.isIncoming()).thenReturn(true);
when(holdingCall.isConference()).thenReturn(false);
when(holdingCall.getGatewayInfo()).thenReturn(
new GatewayInfo(null, null, Uri.parse("tel:555-0001")));
clearInvocations(mMockBluetoothHeadset);
mBluetoothInCallService.listCurrentCalls();
verify(mMockBluetoothHeadset).clccResponse(1, 0, CALL_STATE_ALERTING, 0, false,
"5550000", PhoneNumberUtils.TOA_Unknown);
verify(mMockBluetoothHeadset).clccResponse(2, 1, CALL_STATE_HELD, 0, false,
"5550001", PhoneNumberUtils.TOA_Unknown);
verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
verify(mMockBluetoothHeadset, times(3)).clccResponse(anyInt(),
anyInt(), anyInt(), anyInt(), anyBoolean(), nullable(String.class), anyInt());
}
@Test
public void testListCurrentCallsImsConference() throws Exception {
ArrayList<BluetoothCall> calls = new ArrayList<>();
BluetoothCall parentCall = createActiveCall();
calls.add(parentCall);
mBluetoothInCallService.onCallAdded(parentCall);
addCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
when(parentCall.isConference()).thenReturn(true);
when(parentCall.getState()).thenReturn(Call.STATE_ACTIVE);
when(parentCall.isIncoming()).thenReturn(true);
when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls);
clearInvocations(mMockBluetoothHeadset);
mBluetoothInCallService.listCurrentCalls();
verify(mMockBluetoothHeadset).clccResponse(eq(1), eq(1), eq(CALL_STATE_ACTIVE), eq(0),
eq(true), (String) isNull(), eq(-1));
verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
}
@Test
public void testListCurrentCallsHeldImsCepConference() throws Exception {
ArrayList<BluetoothCall> calls = new ArrayList<>();
BluetoothCall parentCall = createHeldCall();
BluetoothCall childCall1 = createActiveCall();
BluetoothCall childCall2 = createActiveCall();
calls.add(parentCall);
calls.add(childCall1);
calls.add(childCall2);
mBluetoothInCallService.onCallAdded(parentCall);
mBluetoothInCallService.onCallAdded(childCall1);
mBluetoothInCallService.onCallAdded(childCall2);
addCallCapability(parentCall, Connection.CAPABILITY_MANAGE_CONFERENCE);
String parentId = parentCall.getTelecomCallId();
when(childCall1.getParentId()).thenReturn(parentId);
when(childCall2.getParentId()).thenReturn(parentId);
when(parentCall.isConference()).thenReturn(true);
when(parentCall.getState()).thenReturn(Call.STATE_HOLDING);
when(childCall1.getState()).thenReturn(Call.STATE_ACTIVE);
when(childCall2.getState()).thenReturn(Call.STATE_ACTIVE);
when(parentCall.isIncoming()).thenReturn(true);
when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls);
clearInvocations(mMockBluetoothHeadset);
mBluetoothInCallService.listCurrentCalls();
verify(mMockBluetoothHeadset).clccResponse(eq(1), eq(0), eq(CALL_STATE_HELD), eq(0),
eq(true), (String) isNull(), eq(-1));
verify(mMockBluetoothHeadset).clccResponse(eq(2), eq(0), eq(CALL_STATE_HELD), eq(0),
eq(true), (String) isNull(), eq(-1));
verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
}
@Test
public void testQueryPhoneState() throws Exception {
BluetoothCall ringingCall = createRingingCall();
when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:5550000"));
clearInvocations(mMockBluetoothHeadset);
mBluetoothInCallService.queryPhoneState();
verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_INCOMING),
eq("5550000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
}
@Test
public void testCDMAConferenceQueryState() throws Exception {
BluetoothCall parentConfCall = createActiveCall();
final BluetoothCall confCall1 = getMockCall();
final BluetoothCall confCall2 = getMockCall();
mBluetoothInCallService.onCallAdded(confCall1);
mBluetoothInCallService.onCallAdded(confCall2);
when(parentConfCall.getHandle()).thenReturn(Uri.parse("tel:555-0000"));
addCallCapability(parentConfCall, Connection.CAPABILITY_SWAP_CONFERENCE);
removeCallCapability(parentConfCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
when(parentConfCall.wasConferencePreviouslyMerged()).thenReturn(true);
when(parentConfCall.isConference()).thenReturn(true);
List<String> childrenIds = new LinkedList<String>(){{
add(confCall1.getTelecomCallId());
add(confCall2.getTelecomCallId());
}};
when(parentConfCall.getChildrenIds()).thenReturn(childrenIds);
clearInvocations(mMockBluetoothHeadset);
mBluetoothInCallService.queryPhoneState();
verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(0), eq(CALL_STATE_IDLE),
eq(""), eq(128), nullable(String.class));
}
@Test
public void testProcessChldTypeReleaseHeldRinging() throws Exception {
BluetoothCall ringingCall = createRingingCall();
Log.i("BluetoothInCallService", "asdf start " + Integer.toString(ringingCall.hashCode()));
boolean didProcess = mBluetoothInCallService.processChld(CHLD_TYPE_RELEASEHELD);
verify(ringingCall).reject(eq(false), nullable(String.class));
Assert.assertTrue(didProcess);
}
@Test
public void testProcessChldTypeReleaseHeldHold() throws Exception {
BluetoothCall onHoldCall = createHeldCall();
boolean didProcess = mBluetoothInCallService.processChld(CHLD_TYPE_RELEASEHELD);
verify(onHoldCall).disconnect();
Assert.assertTrue(didProcess);
}
@Test
public void testProcessChldReleaseActiveRinging() throws Exception {
BluetoothCall activeCall = createActiveCall();
BluetoothCall ringingCall = createRingingCall();
boolean didProcess = mBluetoothInCallService.processChld(
CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD);
verify(activeCall).disconnect();
verify(ringingCall).answer(any(int.class));
Assert.assertTrue(didProcess);
}
@Test
public void testProcessChldReleaseActiveHold() throws Exception {
BluetoothCall activeCall = createActiveCall();
BluetoothCall heldCall = createHeldCall();
boolean didProcess = mBluetoothInCallService.processChld(
CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD);
verify(activeCall).disconnect();
// BluetoothCall unhold will occur as part of CallsManager auto-unholding
// the background BluetoothCall on its own.
Assert.assertTrue(didProcess);
}
@Test
public void testProcessChldHoldActiveRinging() throws Exception {
BluetoothCall ringingCall = createRingingCall();
boolean didProcess = mBluetoothInCallService.processChld(
CHLD_TYPE_HOLDACTIVE_ACCEPTHELD);
verify(ringingCall).answer(any(int.class));
Assert.assertTrue(didProcess);
}
@Test
public void testProcessChldHoldActiveUnhold() throws Exception {
BluetoothCall heldCall = createHeldCall();
boolean didProcess = mBluetoothInCallService.processChld(
CHLD_TYPE_HOLDACTIVE_ACCEPTHELD);
verify(heldCall).unhold();
Assert.assertTrue(didProcess);
}
@Test
public void testProcessChldHoldActiveHold() throws Exception {
BluetoothCall activeCall = createActiveCall();
addCallCapability(activeCall, Connection.CAPABILITY_HOLD);
boolean didProcess = mBluetoothInCallService.processChld(
CHLD_TYPE_HOLDACTIVE_ACCEPTHELD);
verify(activeCall).hold();
Assert.assertTrue(didProcess);
}
@Test
public void testProcessChldAddHeldToConfHolding() throws Exception {
BluetoothCall activeCall = createActiveCall();
addCallCapability(activeCall, Connection.CAPABILITY_MERGE_CONFERENCE);
boolean didProcess = mBluetoothInCallService.processChld(CHLD_TYPE_ADDHELDTOCONF);
verify(activeCall).mergeConference();
Assert.assertTrue(didProcess);
}
@Test
public void testProcessChldAddHeldToConf() throws Exception {
BluetoothCall activeCall = createActiveCall();
removeCallCapability(activeCall, Connection.CAPABILITY_MERGE_CONFERENCE);
BluetoothCall conferenceableCall = getMockCall();
ArrayList<String> conferenceableCalls = new ArrayList<>();
conferenceableCalls.add(conferenceableCall.getTelecomCallId());
mBluetoothInCallService.onCallAdded(conferenceableCall);
when(activeCall.getConferenceableCalls()).thenReturn(conferenceableCalls);
boolean didProcess = mBluetoothInCallService.processChld(CHLD_TYPE_ADDHELDTOCONF);
verify(activeCall).conference(conferenceableCall);
Assert.assertTrue(didProcess);
}
@Test
public void testProcessChldHoldActiveSwapConference() throws Exception {
// Create an active CDMA BluetoothCall with a BluetoothCall on hold
// and simulate a swapConference().
BluetoothCall parentCall = createActiveCall();
final BluetoothCall foregroundCall = getMockCall();
final BluetoothCall heldCall = createHeldCall();
addCallCapability(parentCall, Connection.CAPABILITY_SWAP_CONFERENCE);
removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
when(parentCall.isConference()).thenReturn(true);
when(parentCall.wasConferencePreviouslyMerged()).thenReturn(false);
List<String> childrenIds = new LinkedList<String>(){{
add(foregroundCall.getTelecomCallId());
add(heldCall.getTelecomCallId());
}};
when(parentCall.getChildrenIds()).thenReturn(childrenIds);
clearInvocations(mMockBluetoothHeadset);
boolean didProcess = mBluetoothInCallService.processChld(
CHLD_TYPE_HOLDACTIVE_ACCEPTHELD);
verify(parentCall).swapConference();
verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(1), eq(CALL_STATE_IDLE), eq(""),
eq(128), nullable(String.class));
Assert.assertTrue(didProcess);
}
// Testing the CallsManager Listener Functionality on Bluetooth
@Test
public void testOnCallAddedRinging() throws Exception {
BluetoothCall ringingCall = createRingingCall();
when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:555000"));
mBluetoothInCallService.onCallAdded(ringingCall);
verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_INCOMING),
eq("555000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
}
@Test
public void testSilentRingingCallState() throws Exception {
BluetoothCall ringingCall = createRingingCall();
when(ringingCall.isSilentRingingRequested()).thenReturn(true);
when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:555000"));
mBluetoothInCallService.onCallAdded(ringingCall);
verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
anyString(), anyInt(), nullable(String.class));
}
@Test
public void testOnCallAddedCdmaActiveHold() throws Exception {
// BluetoothCall has been put into a CDMA "conference" with one BluetoothCall on hold.
BluetoothCall parentCall = createActiveCall();
final BluetoothCall foregroundCall = getMockCall();
final BluetoothCall heldCall = createHeldCall();
addCallCapability(parentCall, Connection.CAPABILITY_MERGE_CONFERENCE);
removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
when(parentCall.isConference()).thenReturn(true);
List<String> childrenIds = new LinkedList<String>(){{
add(foregroundCall.getTelecomCallId());
add(heldCall.getTelecomCallId());
}};
when(parentCall.getChildrenIds()).thenReturn(childrenIds);
mBluetoothInCallService.onCallAdded(parentCall);
verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(1), eq(CALL_STATE_IDLE),
eq(""), eq(128), nullable(String.class));
}
@Test
public void testOnCallRemoved() throws Exception {
BluetoothCall activeCall = createActiveCall();
mBluetoothInCallService.onCallAdded(activeCall);
doReturn(null).when(mMockCallInfo).getActiveCall();
mBluetoothInCallService.onCallRemoved(activeCall);
verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_IDLE),
eq(""), eq(128), nullable(String.class));
}
@Test
public void testOnCallStateChangedConnectingCall() throws Exception {
BluetoothCall activeCall = getMockCall();
BluetoothCall connectingCall = getMockCall();
when(connectingCall.getState()).thenReturn(Call.STATE_CONNECTING);
ArrayList<BluetoothCall> calls = new ArrayList<>();
calls.add(connectingCall);
calls.add(activeCall);
mBluetoothInCallService.onCallAdded(connectingCall);
mBluetoothInCallService.onCallAdded(activeCall);
when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls);
mBluetoothInCallService.getCallback(activeCall)
.onStateChanged(activeCall, Call.STATE_HOLDING);
verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
anyString(), anyInt(), nullable(String.class));
}
@Test
public void testOnCallAddedAudioProcessing() throws Exception {
BluetoothCall call = getMockCall();
when(call.getState()).thenReturn(Call.STATE_AUDIO_PROCESSING);
mBluetoothInCallService.onCallAdded(call);
verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
anyString(), anyInt(), nullable(String.class));
}
@Test
public void testOnCallStateChangedRingingToAudioProcessing() throws Exception {
BluetoothCall ringingCall = createRingingCall();
when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:555000"));
mBluetoothInCallService.onCallAdded(ringingCall);
verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_INCOMING),
eq("555000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
when(ringingCall.getState()).thenReturn(Call.STATE_AUDIO_PROCESSING);
when(mMockCallInfo.getRingingOrSimulatedRingingCall()).thenReturn(null);
mBluetoothInCallService.getCallback(ringingCall)
.onStateChanged(ringingCall, Call.STATE_AUDIO_PROCESSING);
verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_IDLE),
eq(""), eq(128), nullable(String.class));
}
@Test
public void testOnCallStateChangedAudioProcessingToSimulatedRinging() throws Exception {
BluetoothCall ringingCall = createRingingCall();
when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:555-0000"));
mBluetoothInCallService.onCallAdded(ringingCall);
mBluetoothInCallService.getCallback(ringingCall)
.onStateChanged(ringingCall, Call.STATE_SIMULATED_RINGING);
verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_INCOMING),
eq("555-0000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
}
@Test
public void testOnCallStateChangedAudioProcessingToActive() throws Exception {
BluetoothCall activeCall = createActiveCall();
when(activeCall.getState()).thenReturn(Call.STATE_ACTIVE);
mBluetoothInCallService.onCallAdded(activeCall);
mBluetoothInCallService.getCallback(activeCall)
.onStateChanged(activeCall, Call.STATE_ACTIVE);
verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(0), eq(CALL_STATE_IDLE),
eq(""), eq(128), nullable(String.class));
}
@Test
public void testOnCallStateChangedDialing() throws Exception {
BluetoothCall activeCall = createActiveCall();
// make "mLastState" STATE_CONNECTING
BluetoothInCallService.CallStateCallback callback =
mBluetoothInCallService.new CallStateCallback(Call.STATE_CONNECTING);
mBluetoothInCallService.mCallbacks.put(
activeCall.getTelecomCallId(), callback);
mBluetoothInCallService.mCallbacks.get(activeCall.getTelecomCallId())
.onStateChanged(activeCall, Call.STATE_DIALING);
verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
anyString(), anyInt(), nullable(String.class));
}
@Test
public void testOnCallStateChangedAlerting() throws Exception {
BluetoothCall outgoingCall = createOutgoingCall();
mBluetoothInCallService.onCallAdded(outgoingCall);
mBluetoothInCallService.getCallback(outgoingCall)
.onStateChanged(outgoingCall, Call.STATE_DIALING);
verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_DIALING),
eq(""), eq(128), nullable(String.class));
verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_ALERTING),
eq(""), eq(128), nullable(String.class));
}
@Test
public void testOnCallStateChangedDisconnected() throws Exception {
BluetoothCall disconnectedCall = createDisconnectedCall();
doReturn(true).when(mMockCallInfo).hasOnlyDisconnectedCalls();
mBluetoothInCallService.onCallAdded(disconnectedCall);
mBluetoothInCallService.getCallback(disconnectedCall)
.onStateChanged(disconnectedCall, Call.STATE_DISCONNECTED);
verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_DISCONNECTED),
eq(""), eq(128), nullable(String.class));
}
@Test
public void testOnCallStateChanged() throws Exception {
BluetoothCall ringingCall = createRingingCall();
when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:555-0000"));
mBluetoothInCallService.onCallAdded(ringingCall);
verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_INCOMING),
eq("555-0000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
//Switch to active
doReturn(null).when(mMockCallInfo).getRingingOrSimulatedRingingCall();
when(mMockCallInfo.getActiveCall()).thenReturn(ringingCall);
mBluetoothInCallService.getCallback(ringingCall)
.onStateChanged(ringingCall, Call.STATE_ACTIVE);
verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(0), eq(CALL_STATE_IDLE),
eq(""), eq(128), nullable(String.class));
}
@Test
public void testOnCallStateChangedGSMSwap() throws Exception {
BluetoothCall heldCall = createHeldCall();
when(heldCall.getHandle()).thenReturn(Uri.parse("tel:555-0000"));
mBluetoothInCallService.onCallAdded(heldCall);
doReturn(2).when(mMockCallInfo).getNumHeldCalls();
clearInvocations(mMockBluetoothHeadset);
mBluetoothInCallService.getCallback(heldCall)
.onStateChanged(heldCall, Call.STATE_HOLDING);
verify(mMockBluetoothHeadset, never()).phoneStateChanged(eq(0), eq(2), eq(CALL_STATE_HELD),
eq("5550000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
}
@Test
public void testOnParentOnChildrenChanged() throws Exception {
// Start with two calls that are being merged into a CDMA conference call. The
// onIsConferencedChanged method will be called multiple times during the call. Make sure
// that the bluetooth phone state is updated properly.
BluetoothCall parentCall = createActiveCall();
BluetoothCall activeCall = getMockCall();
BluetoothCall heldCall = createHeldCall();
mBluetoothInCallService.onCallAdded(parentCall);
mBluetoothInCallService.onCallAdded(activeCall);
mBluetoothInCallService.onCallAdded(heldCall);
String parentId = parentCall.getTelecomCallId();
when(activeCall.getParentId()).thenReturn(parentId);
when(heldCall.getParentId()).thenReturn(parentId);
ArrayList<String> calls = new ArrayList<>();
calls.add(activeCall.getTelecomCallId());
when(parentCall.getChildrenIds()).thenReturn(calls);
when(parentCall.isConference()).thenReturn(true);
removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
addCallCapability(parentCall, Connection.CAPABILITY_SWAP_CONFERENCE);
when(parentCall.wasConferencePreviouslyMerged()).thenReturn(false);
clearInvocations(mMockBluetoothHeadset);
// Be sure that onIsConferencedChanged rejects spurious changes during set up of
// CDMA "conference"
mBluetoothInCallService.getCallback(activeCall).onParentChanged(activeCall);
verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
anyString(), anyInt(), nullable(String.class));
mBluetoothInCallService.getCallback(heldCall).onParentChanged(heldCall);
verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
anyString(), anyInt(), nullable(String.class));
mBluetoothInCallService.getCallback(parentCall)
.onChildrenChanged(
parentCall,
mBluetoothInCallService.getBluetoothCallsByIds(calls));
verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
anyString(), anyInt(), nullable(String.class));
calls.add(heldCall.getTelecomCallId());
mBluetoothInCallService.onCallAdded(heldCall);
mBluetoothInCallService.getCallback(parentCall)
.onChildrenChanged(
parentCall,
mBluetoothInCallService.getBluetoothCallsByIds(calls));
verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(1), eq(CALL_STATE_IDLE),
eq(""), eq(128), nullable(String.class));
}
@Test
public void testBluetoothAdapterReceiver() throws Exception {
BluetoothCall ringingCall = createRingingCall();
when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:5550000"));
Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
intent.putExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_ON);
clearInvocations(mMockBluetoothHeadset);
mBluetoothInCallService.mBluetoothAdapterReceiver
= mBluetoothInCallService.new BluetoothAdapterReceiver();
mBluetoothInCallService.mBluetoothAdapterReceiver
.onReceive(mBluetoothInCallService, intent);
verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_INCOMING),
eq("5550000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
}
private void addCallCapability(BluetoothCall call, int capability) {
when(call.can(capability)).thenReturn(true);
}
private void removeCallCapability(BluetoothCall call, int capability) {
when(call.can(capability)).thenReturn(false);
}
private BluetoothCall createActiveCall() {
BluetoothCall call = getMockCall();
when(mMockCallInfo.getActiveCall()).thenReturn(call);
return call;
}
private BluetoothCall createRingingCall() {
BluetoothCall call = getMockCall();
Log.i("BluetoothInCallService", "asdf creaete " + Integer.toString(call.hashCode()));
when(mMockCallInfo.getRingingOrSimulatedRingingCall()).thenReturn(call);
return call;
}
private BluetoothCall createHeldCall() {
BluetoothCall call = getMockCall();
when(mMockCallInfo.getHeldCall()).thenReturn(call);
return call;
}
private BluetoothCall createOutgoingCall() {
BluetoothCall call = getMockCall();
when(mMockCallInfo.getOutgoingCall()).thenReturn(call);
return call;
}
private BluetoothCall createDisconnectedCall() {
BluetoothCall call = getMockCall();
when(mMockCallInfo.getCallByState(Call.STATE_DISCONNECTED)).thenReturn(call);
return call;
}
private BluetoothCall createForegroundCall() {
BluetoothCall call = getMockCall();
when(mMockCallInfo.getForegroundCall()).thenReturn(call);
return call;
}
private static ComponentName makeQuickConnectionServiceComponentName() {
return new ComponentName("com.android.server.telecom.tests",
"com.android.server.telecom.tests.MockConnectionService");
}
private static PhoneAccountHandle makeQuickAccountHandle(String id) {
return new PhoneAccountHandle(makeQuickConnectionServiceComponentName(), id,
Binder.getCallingUserHandle());
}
private PhoneAccount.Builder makeQuickAccountBuilder(String id, int idx) {
return new PhoneAccount.Builder(makeQuickAccountHandle(id), "label" + idx);
}
private PhoneAccount makeQuickAccount(String id, int idx) {
return makeQuickAccountBuilder(id, idx)
.setAddress(Uri.parse(TEST_ACCOUNT_ADDRESS + idx))
.setSubscriptionAddress(Uri.parse("tel:555-000" + idx))
.setCapabilities(idx)
.setShortDescription("desc" + idx)
.setIsEnabled(true)
.build();
}
private BluetoothCall getMockCall() {
BluetoothCall call = mock(com.android.bluetooth.hfp.BluetoothCall.class);
String uuid = UUID.randomUUID().toString();
when(call.getTelecomCallId()).thenReturn(uuid);
return call;
}
}