Merge "Fix issue that music popped up from speaker during ringing call"
diff --git a/src/com/android/server/telecom/Analytics.java b/src/com/android/server/telecom/Analytics.java
index 0a15b26..4daa525 100644
--- a/src/com/android/server/telecom/Analytics.java
+++ b/src/com/android/server/telecom/Analytics.java
@@ -35,6 +35,7 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.PriorityQueue;
import java.util.stream.Collectors;
import static android.telecom.ParcelableCallAnalytics.AnalyticsEvent;
@@ -523,8 +524,11 @@
public static final long MILLIS_IN_1_SECOND = ParcelableCallAnalytics.MILLIS_IN_1_SECOND;
+ public static final int MAX_NUM_CALLS_TO_STORE = 100;
+
private static final Object sLock = new Object(); // Coarse lock for all of analytics
private static final Map<String, CallInfoImpl> sCallIdToInfo = new HashMap<>();
+ private static final LinkedList<String> sActiveCallIds = new LinkedList<>();
private static final List<SessionTiming> sSessionTimings = new LinkedList<>();
public static void addSessionTiming(String sessionName, long time) {
@@ -540,7 +544,12 @@
Log.d(TAG, "Starting analytics for call " + callId);
CallInfoImpl callInfo = new CallInfoImpl(callId, direction);
synchronized (sLock) {
+ while (sActiveCallIds.size() >= MAX_NUM_CALLS_TO_STORE) {
+ String callToRemove = sActiveCallIds.remove();
+ sCallIdToInfo.remove(callToRemove);
+ }
sCallIdToInfo.put(callId, callInfo);
+ sActiveCallIds.add(callId);
}
return callInfo;
}
diff --git a/src/com/android/server/telecom/CallAudioRoutePeripheralAdapter.java b/src/com/android/server/telecom/CallAudioRoutePeripheralAdapter.java
index 9b62443..96646b2 100644
--- a/src/com/android/server/telecom/CallAudioRoutePeripheralAdapter.java
+++ b/src/com/android/server/telecom/CallAudioRoutePeripheralAdapter.java
@@ -16,66 +16,68 @@
package com.android.server.telecom;
+import com.android.server.telecom.bluetooth.BluetoothRouteManager;
+
/**
* A class that acts as a listener to things that could change call audio routing, namely
* bluetooth status, wired headset status, and dock status.
*/
public class CallAudioRoutePeripheralAdapter implements WiredHeadsetManager.Listener,
- DockManager.Listener, BluetoothManager.BluetoothStateListener {
+ DockManager.Listener, BluetoothRouteManager.BluetoothStateListener {
private final CallAudioRouteStateMachine mCallAudioRouteStateMachine;
- private final BluetoothManager mBluetoothManager;
+ private final BluetoothRouteManager mBluetoothRouteManager;
public CallAudioRoutePeripheralAdapter(
CallAudioRouteStateMachine callAudioRouteStateMachine,
- BluetoothManager bluetoothManager,
+ BluetoothRouteManager bluetoothManager,
WiredHeadsetManager wiredHeadsetManager,
DockManager dockManager) {
mCallAudioRouteStateMachine = callAudioRouteStateMachine;
- mBluetoothManager = bluetoothManager;
+ mBluetoothRouteManager = bluetoothManager;
- mBluetoothManager.setBluetoothStateListener(this);
+ mBluetoothRouteManager.setListener(this);
wiredHeadsetManager.addListener(this);
dockManager.addListener(this);
}
public boolean isBluetoothAudioOn() {
- return mBluetoothManager.isBluetoothAudioConnected();
+ return mBluetoothRouteManager.isBluetoothAudioConnectedOrPending();
}
@Override
public void onBluetoothStateChange(int oldState, int newState) {
switch (oldState) {
- case BluetoothManager.BLUETOOTH_DISCONNECTED:
- case BluetoothManager.BLUETOOTH_UNINITIALIZED:
+ case BluetoothRouteManager.BLUETOOTH_DISCONNECTED:
+ case BluetoothRouteManager.BLUETOOTH_UNINITIALIZED:
switch (newState) {
- case BluetoothManager.BLUETOOTH_DEVICE_CONNECTED:
- case BluetoothManager.BLUETOOTH_AUDIO_CONNECTED:
+ case BluetoothRouteManager.BLUETOOTH_DEVICE_CONNECTED:
+ case BluetoothRouteManager.BLUETOOTH_AUDIO_CONNECTED:
mCallAudioRouteStateMachine.sendMessageWithSessionInfo(
CallAudioRouteStateMachine.CONNECT_BLUETOOTH);
break;
}
break;
- case BluetoothManager.BLUETOOTH_DEVICE_CONNECTED:
+ case BluetoothRouteManager.BLUETOOTH_DEVICE_CONNECTED:
switch (newState) {
- case BluetoothManager.BLUETOOTH_DISCONNECTED:
+ case BluetoothRouteManager.BLUETOOTH_DISCONNECTED:
mCallAudioRouteStateMachine.sendMessageWithSessionInfo(
CallAudioRouteStateMachine.DISCONNECT_BLUETOOTH);
break;
- case BluetoothManager.BLUETOOTH_AUDIO_CONNECTED:
+ case BluetoothRouteManager.BLUETOOTH_AUDIO_CONNECTED:
mCallAudioRouteStateMachine.sendMessageWithSessionInfo(
CallAudioRouteStateMachine.SWITCH_BLUETOOTH);
break;
}
break;
- case BluetoothManager.BLUETOOTH_AUDIO_CONNECTED:
- case BluetoothManager.BLUETOOTH_AUDIO_PENDING:
+ case BluetoothRouteManager.BLUETOOTH_AUDIO_CONNECTED:
+ case BluetoothRouteManager.BLUETOOTH_AUDIO_PENDING:
switch (newState) {
- case BluetoothManager.BLUETOOTH_DISCONNECTED:
+ case BluetoothRouteManager.BLUETOOTH_DISCONNECTED:
mCallAudioRouteStateMachine.sendMessageWithSessionInfo(
CallAudioRouteStateMachine.DISCONNECT_BLUETOOTH);
break;
- case BluetoothManager.BLUETOOTH_DEVICE_CONNECTED:
+ case BluetoothRouteManager.BLUETOOTH_DEVICE_CONNECTED:
mCallAudioRouteStateMachine.sendMessageWithSessionInfo(
CallAudioRouteStateMachine.BT_AUDIO_DISCONNECT);
break;
diff --git a/src/com/android/server/telecom/CallAudioRouteStateMachine.java b/src/com/android/server/telecom/CallAudioRouteStateMachine.java
index cb1526a..377ab48 100644
--- a/src/com/android/server/telecom/CallAudioRouteStateMachine.java
+++ b/src/com/android/server/telecom/CallAudioRouteStateMachine.java
@@ -39,6 +39,7 @@
import com.android.internal.util.IState;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
+import com.android.server.telecom.bluetooth.BluetoothRouteManager;
import java.util.HashMap;
@@ -829,6 +830,7 @@
super.enter();
mHasUserExplicitlyLeftBluetooth = false;
updateInternalCallAudioState();
+ setBluetoothOn(false);
}
@Override
@@ -1135,7 +1137,7 @@
private final Context mContext;
private final CallsManager mCallsManager;
private final AudioManager mAudioManager;
- private final BluetoothManager mBluetoothManager;
+ private final BluetoothRouteManager mBluetoothRouteManager;
private final WiredHeadsetManager mWiredHeadsetManager;
private final StatusBarNotifier mStatusBarNotifier;
private final CallAudioManager.AudioServiceFactory mAudioServiceFactory;
@@ -1155,7 +1157,7 @@
public CallAudioRouteStateMachine(
Context context,
CallsManager callsManager,
- BluetoothManager bluetoothManager,
+ BluetoothRouteManager bluetoothManager,
WiredHeadsetManager wiredHeadsetManager,
StatusBarNotifier statusBarNotifier,
CallAudioManager.AudioServiceFactory audioServiceFactory,
@@ -1175,7 +1177,7 @@
mContext = context;
mCallsManager = callsManager;
mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
- mBluetoothManager = bluetoothManager;
+ mBluetoothRouteManager = bluetoothManager;
mWiredHeadsetManager = wiredHeadsetManager;
mStatusBarNotifier = statusBarNotifier;
mAudioServiceFactory = audioServiceFactory;
@@ -1290,7 +1292,7 @@
return;
default:
Log.e(this, new IllegalStateException(),
- "Unexpected message code");
+ "Unexpected message code %d", msg.what);
}
}
@@ -1350,14 +1352,13 @@
}
private void setBluetoothOn(boolean on) {
- if (mBluetoothManager.isBluetoothAvailable()) {
- boolean isAlreadyOn = mBluetoothManager.isBluetoothAudioConnectedOrPending();
- if (on != isAlreadyOn) {
+ if (mBluetoothRouteManager.isBluetoothAvailable()) {
+ if (on != mBluetoothRouteManager.isBluetoothAudioConnectedOrPending()) {
Log.i(this, "connecting bluetooth %s", on);
if (on) {
- mBluetoothManager.connectBluetoothAudio();
+ mBluetoothRouteManager.connectBluetoothAudio(null /*TODO: add real address*/);
} else {
- mBluetoothManager.disconnectBluetoothAudio();
+ mBluetoothRouteManager.disconnectBluetoothAudio();
}
}
}
@@ -1365,8 +1366,8 @@
private void setMuteOn(boolean mute) {
mIsMuted = mute;
- Log.addEvent(mCallsManager.getForegroundCall(), mute ? LogUtils.Events.MUTE : LogUtils.Events.UNMUTE);
-
+ Log.addEvent(mCallsManager.getForegroundCall(), mute ?
+ LogUtils.Events.MUTE : LogUtils.Events.UNMUTE);
if (mute != mAudioManager.isMicrophoneMute() && isInActiveState()) {
IAudioService audio = mAudioServiceFactory.getAudioService();
Log.i(this, "changing microphone mute state to: %b [serviceIsNull=%b]",
@@ -1450,7 +1451,7 @@
routeMask |= CallAudioState.ROUTE_EARPIECE;
}
- if (mBluetoothManager.isBluetoothAvailable()) {
+ if (mBluetoothRouteManager.isBluetoothAvailable()) {
routeMask |= CallAudioState.ROUTE_BLUETOOTH;
}
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index 432eddd..2aacfab 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -57,6 +57,7 @@
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.TelephonyProperties;
import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.telecom.bluetooth.BluetoothRouteManager;
import com.android.server.telecom.callfiltering.AsyncBlockCheckFilter;
import com.android.server.telecom.callfiltering.BlockCheckerAdapter;
import com.android.server.telecom.callfiltering.CallFilterResultCallback;
@@ -179,7 +180,7 @@
new ConcurrentHashMap<CallsManagerListener, Boolean>(16, 0.9f, 1));
private final HeadsetMediaButton mHeadsetMediaButton;
private final WiredHeadsetManager mWiredHeadsetManager;
- private final BluetoothManager mBluetoothManager;
+ private final BluetoothRouteManager mBluetoothRouteManager;
private final DockManager mDockManager;
private final TtyManager mTtyManager;
private final ProximitySensorManager mProximitySensorManager;
@@ -221,7 +222,7 @@
ProximitySensorManagerFactory proximitySensorManagerFactory,
InCallWakeLockControllerFactory inCallWakeLockControllerFactory,
CallAudioManager.AudioServiceFactory audioServiceFactory,
- BluetoothManager bluetoothManager,
+ BluetoothRouteManager bluetoothManager,
WiredHeadsetManager wiredHeadsetManager,
SystemStateProvider systemStateProvider,
DefaultDialerCache defaultDialerCache,
@@ -238,8 +239,8 @@
mMissedCallNotifier = missedCallNotifier;
StatusBarNotifier statusBarNotifier = new StatusBarNotifier(context, this);
mWiredHeadsetManager = wiredHeadsetManager;
- mBluetoothManager = bluetoothManager;
mDefaultDialerCache = defaultDialerCache;
+ mBluetoothRouteManager = bluetoothManager;
mDockManager = new DockManager(context);
mTimeoutsAdapter = timeoutsAdapter;
mCallerInfoLookupHelper = new CallerInfoLookupHelper(context, mCallerInfoAsyncQueryFactory,
@@ -1069,7 +1070,7 @@
public boolean isSpeakerphoneAutoEnabledForVideoCalls(int videoState) {
return VideoProfile.isVideo(videoState) &&
!mWiredHeadsetManager.isPluggedIn() &&
- !mBluetoothManager.isBluetoothAvailable() &&
+ !mBluetoothRouteManager.isBluetoothAvailable() &&
isSpeakerEnabledForVideoCalls();
}
@@ -1083,7 +1084,7 @@
private boolean isSpeakerphoneEnabledForDock() {
return mDockManager.isDocked() &&
!mWiredHeadsetManager.isPluggedIn() &&
- !mBluetoothManager.isBluetoothAvailable();
+ !mBluetoothRouteManager.isBluetoothAvailable();
}
/**
diff --git a/src/com/android/server/telecom/TelecomSystem.java b/src/com/android/server/telecom/TelecomSystem.java
index 8fec2dd..5c95fb0 100644
--- a/src/com/android/server/telecom/TelecomSystem.java
+++ b/src/com/android/server/telecom/TelecomSystem.java
@@ -17,6 +17,8 @@
package com.android.server.telecom;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.telecom.bluetooth.BluetoothDeviceManager;
+import com.android.server.telecom.bluetooth.BluetoothRouteManager;
import com.android.server.telecom.components.UserCallIntentProcessor;
import com.android.server.telecom.components.UserCallIntentProcessorFactory;
import com.android.server.telecom.ui.MissedCallNotifierImpl.MissedCallNotifierImplFactory;
@@ -200,8 +202,10 @@
return context.getContentResolver().openInputStream(uri);
}
});
- BluetoothManager bluetoothManager = new BluetoothManager(mContext,
- new BluetoothAdapterProxy());
+ BluetoothDeviceManager bluetoothDeviceManager = new BluetoothDeviceManager(mContext,
+ new BluetoothAdapterProxy(), mLock);
+ BluetoothRouteManager bluetoothRouteManager = new BluetoothRouteManager(mContext, mLock,
+ bluetoothDeviceManager, new Timeouts.Adapter());
WiredHeadsetManager wiredHeadsetManager = new WiredHeadsetManager(mContext);
SystemStateProvider systemStateProvider = new SystemStateProvider(mContext);
@@ -219,7 +223,7 @@
proximitySensorManagerFactory,
inCallWakeLockControllerFactory,
audioServiceFactory,
- bluetoothManager,
+ bluetoothRouteManager,
wiredHeadsetManager,
systemStateProvider,
defaultDialerCache,
diff --git a/tests/src/com/android/server/telecom/tests/AnalyticsTests.java b/tests/src/com/android/server/telecom/tests/AnalyticsTests.java
index b22ae82..601e1b6 100644
--- a/tests/src/com/android/server/telecom/tests/AnalyticsTests.java
+++ b/tests/src/com/android/server/telecom/tests/AnalyticsTests.java
@@ -37,6 +37,7 @@
import java.io.PrintWriter;
import java.io.StringWriter;
+import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -338,6 +339,26 @@
analyticsProto.callLogs[0].getConnectionProperties() & expectedProperties);
}
+ @SmallTest
+ public void testAnalyticsMaxSize() throws Exception {
+ Analytics.reset();
+ for (int i = 0; i < Analytics.MAX_NUM_CALLS_TO_STORE * 2; i++) {
+ Analytics.initiateCallAnalytics(String.valueOf(i), Analytics.INCOMING_DIRECTION)
+ .addCallTechnology(i);
+ }
+
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ Analytics.dumpToEncodedProto(pw, new String[]{});
+ TelecomLogClass.TelecomLog analyticsProto =
+ TelecomLogClass.TelecomLog.parseFrom(Base64.decode(sw.toString(), Base64.DEFAULT));
+
+ assertEquals(Analytics.MAX_NUM_CALLS_TO_STORE, analyticsProto.callLogs.length);
+ assertEquals(Arrays.stream(analyticsProto.callLogs)
+ .filter(x -> x.getCallTechnologies() < 100)
+ .count(), 0);
+ }
+
private void assertIsRoundedToOneSigFig(long x) {
assertEquals(x, Analytics.roundToOneSigFig(x));
}
diff --git a/tests/src/com/android/server/telecom/tests/CallAudioModeStateMachineTest.java b/tests/src/com/android/server/telecom/tests/CallAudioModeStateMachineTest.java
index 38ea10e..af1d3a2 100644
--- a/tests/src/com/android/server/telecom/tests/CallAudioModeStateMachineTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallAudioModeStateMachineTest.java
@@ -604,6 +604,8 @@
verify(mCallAudioManager).stopCallWaiting();
break;
}
+
+ sm.quitNow();
}
private void resetMocks() {
diff --git a/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java b/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java
index 0766b72..d53f270 100644
--- a/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java
@@ -25,7 +25,7 @@
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
-import com.android.server.telecom.BluetoothManager;
+import com.android.server.telecom.bluetooth.BluetoothRouteManager;
import com.android.server.telecom.Call;
import com.android.server.telecom.CallAudioModeStateMachine;
import com.android.server.telecom.CallAudioRouteStateMachine;
@@ -135,7 +135,7 @@
}
@Mock CallsManager mockCallsManager;
- @Mock BluetoothManager mockBluetoothManager;
+ @Mock BluetoothRouteManager mockBluetoothRouteManager;
@Mock IAudioService mockAudioService;
@Mock ConnectionServiceWrapper mockConnectionServiceWrapper;
@Mock WiredHeadsetManager mockWiredHeadsetManager;
@@ -207,15 +207,15 @@
CallAudioRouteStateMachine stateMachine = new CallAudioRouteStateMachine(
mContext,
mockCallsManager,
- mockBluetoothManager,
+ mockBluetoothRouteManager,
mockWiredHeadsetManager,
mockStatusBarNotifier,
mAudioServiceFactory,
mMockInterruptionFilterProxy,
true);
- when(mockBluetoothManager.isBluetoothAudioConnectedOrPending()).thenReturn(false);
- when(mockBluetoothManager.isBluetoothAvailable()).thenReturn(true);
+ when(mockBluetoothRouteManager.isBluetoothAudioConnectedOrPending()).thenReturn(false);
+ when(mockBluetoothRouteManager.isBluetoothAvailable()).thenReturn(true);
when(mockAudioManager.isSpeakerphoneOn()).thenReturn(true);
doAnswer(new Answer() {
@Override
@@ -236,7 +236,7 @@
CallAudioState.ROUTE_WIRED_HEADSET,
CallAudioState.ROUTE_WIRED_HEADSET | CallAudioState.ROUTE_SPEAKER);
verifyNewSystemCallAudioState(initState, expectedMiddleState);
- resetMocks();
+ resetMocks(true);
stateMachine.sendMessageWithSessionInfo(
CallAudioRouteStateMachine.DISCONNECT_WIRED_HEADSET);
@@ -248,15 +248,15 @@
CallAudioRouteStateMachine stateMachine = new CallAudioRouteStateMachine(
mContext,
mockCallsManager,
- mockBluetoothManager,
+ mockBluetoothRouteManager,
mockWiredHeadsetManager,
mockStatusBarNotifier,
mAudioServiceFactory,
mMockInterruptionFilterProxy,
true);
- when(mockBluetoothManager.isBluetoothAudioConnectedOrPending()).thenReturn(false);
- when(mockBluetoothManager.isBluetoothAvailable()).thenReturn(true);
+ when(mockBluetoothRouteManager.isBluetoothAudioConnectedOrPending()).thenReturn(false);
+ when(mockBluetoothRouteManager.isBluetoothAvailable()).thenReturn(true);
when(mockAudioManager.isSpeakerphoneOn()).thenReturn(true);
CallAudioState initState = new CallAudioState(false, CallAudioState.ROUTE_BLUETOOTH,
@@ -276,7 +276,7 @@
// Expecting to end up in earpiece, so we expect notifications to be filtered.
assertEquals(NotificationManager.INTERRUPTION_FILTER_ALARMS,
mMockInterruptionFilterProxy.getCurrentInterruptionFilter());
- resetMocks();
+ resetMocks(false);
stateMachine.sendMessageWithSessionInfo(
CallAudioRouteStateMachine.DISCONNECT_BLUETOOTH);
stateMachine.sendMessageWithSessionInfo(
@@ -291,15 +291,15 @@
CallAudioRouteStateMachine stateMachine = new CallAudioRouteStateMachine(
mContext,
mockCallsManager,
- mockBluetoothManager,
+ mockBluetoothRouteManager,
mockWiredHeadsetManager,
mockStatusBarNotifier,
mAudioServiceFactory,
mMockInterruptionFilterProxy,
true);
- when(mockBluetoothManager.isBluetoothAudioConnectedOrPending()).thenReturn(false);
- when(mockBluetoothManager.isBluetoothAvailable()).thenReturn(true);
+ when(mockBluetoothRouteManager.isBluetoothAudioConnectedOrPending()).thenReturn(false);
+ when(mockBluetoothRouteManager.isBluetoothAvailable()).thenReturn(true);
when(mockAudioManager.isSpeakerphoneOn()).thenReturn(false);
CallAudioState initState = new CallAudioState(false, CallAudioState.ROUTE_BLUETOOTH,
@@ -310,7 +310,7 @@
CallAudioRouteStateMachine.RINGING_FOCUS);
waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE);
- verify(mockBluetoothManager, never()).connectBluetoothAudio();
+ verify(mockBluetoothRouteManager, never()).connectBluetoothAudio(null);
// Shouldn't change interruption filter when in bluetooth route.
assertEquals(NotificationManager.INTERRUPTION_FILTER_ALL,
mMockInterruptionFilterProxy.getCurrentInterruptionFilter());
@@ -318,7 +318,7 @@
stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.SWITCH_FOCUS,
CallAudioRouteStateMachine.ACTIVE_FOCUS);
waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE);
- verify(mockBluetoothManager, times(1)).connectBluetoothAudio();
+ verify(mockBluetoothRouteManager, times(1)).connectBluetoothAudio(null);
}
@MediumTest
@@ -326,15 +326,15 @@
CallAudioRouteStateMachine stateMachine = new CallAudioRouteStateMachine(
mContext,
mockCallsManager,
- mockBluetoothManager,
+ mockBluetoothRouteManager,
mockWiredHeadsetManager,
mockStatusBarNotifier,
mAudioServiceFactory,
mMockInterruptionFilterProxy,
true);
- when(mockBluetoothManager.isBluetoothAudioConnectedOrPending()).thenReturn(false);
- when(mockBluetoothManager.isBluetoothAvailable()).thenReturn(false);
+ when(mockBluetoothRouteManager.isBluetoothAudioConnectedOrPending()).thenReturn(false);
+ when(mockBluetoothRouteManager.isBluetoothAvailable()).thenReturn(false);
when(mockAudioManager.isSpeakerphoneOn()).thenReturn(false);
CallAudioState initState = new CallAudioState(false, CallAudioState.ROUTE_EARPIECE,
CallAudioState.ROUTE_EARPIECE);
@@ -342,10 +342,12 @@
stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.SWITCH_FOCUS,
CallAudioRouteStateMachine.RINGING_FOCUS);
- when(mockBluetoothManager.isBluetoothAvailable()).thenReturn(true);
+
+ when(mockBluetoothRouteManager.isBluetoothAvailable()).thenReturn(true);
stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.CONNECT_BLUETOOTH);
waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE);
- verify(mockBluetoothManager, never()).connectBluetoothAudio();
+
+ verify(mockBluetoothRouteManager, never()).connectBluetoothAudio(null);
CallAudioState expectedEndState = new CallAudioState(false,
CallAudioState.ROUTE_BLUETOOTH,
CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH);
@@ -354,7 +356,7 @@
stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.SWITCH_FOCUS,
CallAudioRouteStateMachine.ACTIVE_FOCUS);
waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE);
- verify(mockBluetoothManager, times(1)).connectBluetoothAudio();
+ verify(mockBluetoothRouteManager, times(1)).connectBluetoothAudio(null);
}
@SmallTest
@@ -420,13 +422,13 @@
boolean doesDeviceSupportEarpiece) {
when(mockWiredHeadsetManager.isPluggedIn()).thenReturn(
(expectedState.getSupportedRouteMask() & CallAudioState.ROUTE_WIRED_HEADSET) != 0);
- when(mockBluetoothManager.isBluetoothAvailable()).thenReturn(
+ when(mockBluetoothRouteManager.isBluetoothAvailable()).thenReturn(
(expectedState.getSupportedRouteMask() & CallAudioState.ROUTE_BLUETOOTH) != 0);
CallAudioRouteStateMachine stateMachine = new CallAudioRouteStateMachine(
mContext,
mockCallsManager,
- mockBluetoothManager,
+ mockBluetoothRouteManager,
mockWiredHeadsetManager,
mockStatusBarNotifier,
mAudioServiceFactory,
@@ -933,7 +935,7 @@
private void runParametrizedTestCaseWithFocus(final RoutingTestParameters params)
throws Throwable {
- resetMocks();
+ resetMocks(true);
when(mMockInterruptionFilterProxy.getCurrentInterruptionFilter()).thenReturn(
params.initialNotificationFilter);
@@ -941,22 +943,14 @@
final CallAudioRouteStateMachine stateMachine = new CallAudioRouteStateMachine(
mContext,
mockCallsManager,
- mockBluetoothManager,
+ mockBluetoothRouteManager,
mockWiredHeadsetManager,
mockStatusBarNotifier,
mAudioServiceFactory,
mMockInterruptionFilterProxy,
params.doesDeviceSupportEarpiece);
- // Set up bluetooth and speakerphone state
- when(mockBluetoothManager.isBluetoothAudioConnectedOrPending()).thenReturn(
- params.initialRoute == CallAudioState.ROUTE_BLUETOOTH);
- when(mockBluetoothManager.isBluetoothAvailable()).thenReturn(
- (params.availableRoutes & CallAudioState.ROUTE_BLUETOOTH) != 0
- || (params.expectedAvailableRoutes & CallAudioState.ROUTE_BLUETOOTH) != 0);
- doReturn(params.initialRoute == CallAudioState.ROUTE_SPEAKER).when(mockAudioManager).
- isSpeakerphoneOn();
- when(fakeCall.getSupportedAudioRoutes()).thenReturn(params.callSupportedRoutes);
+ setupMocksForParams(params);
// Set the initial CallAudioState object
final CallAudioState initState = new CallAudioState(false,
@@ -966,6 +960,11 @@
// Make the state machine have focus so that we actually do something
stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.SWITCH_FOCUS,
CallAudioRouteStateMachine.ACTIVE_FOCUS);
+ waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE);
+
+ // Reset mocks one more time to discard stuff from initialization
+ resetMocks(false);
+ setupMocksForParams(params);
stateMachine.sendMessageWithSessionInfo(params.action);
waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE);
@@ -991,17 +990,17 @@
// Verify interactions with the speakerphone and bluetooth systems
switch (params.bluetoothInteraction) {
case NONE:
- verify(mockBluetoothManager, never()).disconnectBluetoothAudio();
- verify(mockBluetoothManager, never()).connectBluetoothAudio();
+ verify(mockBluetoothRouteManager, never()).disconnectBluetoothAudio();
+ verify(mockBluetoothRouteManager, never()).connectBluetoothAudio(null);
break;
case ON:
- verify(mockBluetoothManager).connectBluetoothAudio();
+ verify(mockBluetoothRouteManager).connectBluetoothAudio(null);
- verify(mockBluetoothManager, never()).disconnectBluetoothAudio();
+ verify(mockBluetoothRouteManager, never()).disconnectBluetoothAudio();
break;
case OFF:
- verify(mockBluetoothManager, never()).connectBluetoothAudio();
- verify(mockBluetoothManager).disconnectBluetoothAudio();
+ verify(mockBluetoothRouteManager, never()).connectBluetoothAudio(null);
+ verify(mockBluetoothRouteManager).disconnectBluetoothAudio();
}
switch (params.speakerInteraction) {
@@ -1019,15 +1018,27 @@
verifyNewSystemCallAudioState(initState, expectedState);
}
+ private void setupMocksForParams(RoutingTestParameters params) {
+ // Set up bluetooth and speakerphone state
+ when(mockBluetoothRouteManager.isBluetoothAudioConnectedOrPending()).thenReturn(
+ params.initialRoute == CallAudioState.ROUTE_BLUETOOTH);
+ when(mockBluetoothRouteManager.isBluetoothAvailable()).thenReturn(
+ (params.availableRoutes & CallAudioState.ROUTE_BLUETOOTH) != 0
+ || (params.expectedAvailableRoutes & CallAudioState.ROUTE_BLUETOOTH) != 0);
+ when(mockAudioManager.isSpeakerphoneOn()).thenReturn(
+ params.initialRoute == CallAudioState.ROUTE_SPEAKER);
+ when(fakeCall.getSupportedAudioRoutes()).thenReturn(params.callSupportedRoutes);
+ }
+
private void runParametrizedTestCaseWithoutFocus(final RoutingTestParameters params)
throws Throwable {
- resetMocks();
+ resetMocks(true);
// Construct a fresh state machine on every case
final CallAudioRouteStateMachine stateMachine = new CallAudioRouteStateMachine(
mContext,
mockCallsManager,
- mockBluetoothManager,
+ mockBluetoothRouteManager,
mockWiredHeadsetManager,
mockStatusBarNotifier,
mAudioServiceFactory,
@@ -1035,7 +1046,7 @@
params.doesDeviceSupportEarpiece);
// Set up bluetooth and speakerphone state
- when(mockBluetoothManager.isBluetoothAvailable()).thenReturn(
+ when(mockBluetoothRouteManager.isBluetoothAvailable()).thenReturn(
(params.availableRoutes & CallAudioState.ROUTE_BLUETOOTH) != 0
|| (params.expectedAvailableRoutes & CallAudioState.ROUTE_BLUETOOTH) != 0);
when(mockAudioManager.isSpeakerphoneOn()).thenReturn(
@@ -1064,8 +1075,8 @@
}
private void verifyNoSystemAudioChanges() {
- verify(mockBluetoothManager, never()).disconnectBluetoothAudio();
- verify(mockBluetoothManager, never()).connectBluetoothAudio();
+ verify(mockBluetoothRouteManager, never()).disconnectBluetoothAudio();
+ verify(mockBluetoothRouteManager, never()).connectBluetoothAudio(null);
verify(mockAudioManager, never()).setSpeakerphoneOn(any(Boolean.class));
verify(mockCallsManager, never()).onCallAudioStateChanged(any(CallAudioState.class),
any(CallAudioState.class));
@@ -1091,11 +1102,14 @@
assertTrue(newStateCaptor2.getValue().equals(expectedNewState));
}
- private void resetMocks() {
- reset(mockAudioManager, mockBluetoothManager, mockCallsManager,
- mockConnectionServiceWrapper, mMockInterruptionFilterProxy, fakeCall);
- mMockInterruptionFilterProxy = mock(InterruptionFilterProxy.class);
- setupInterruptionFilterMocks();
+ private void resetMocks(boolean resetNotificationFilter) {
+ reset(mockAudioManager, mockBluetoothRouteManager, mockCallsManager,
+ mockConnectionServiceWrapper, fakeCall);
+ if (resetNotificationFilter) {
+ reset(mMockInterruptionFilterProxy);
+ mMockInterruptionFilterProxy = mock(InterruptionFilterProxy.class);
+ setupInterruptionFilterMocks();
+ }
when(mockCallsManager.getForegroundCall()).thenReturn(fakeCall);
when(fakeCall.getConnectionService()).thenReturn(mockConnectionServiceWrapper);
when(fakeCall.isAlive()).thenReturn(true);
diff --git a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
index ece6b73..f590e8c 100644
--- a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
+++ b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
@@ -322,6 +322,10 @@
@Override
public void tearDown() throws Exception {
+ mTelecomSystem.getCallsManager().getCallAudioManager()
+ .getCallAudioRouteStateMachine().quitNow();
+ mTelecomSystem.getCallsManager().getCallAudioManager()
+ .getCallAudioModeStateMachine().quitNow();
mTelecomSystem = null;
super.tearDown();
}