Loading src/com/android/server/telecom/AudioRoute.java +8 −7 Original line number Diff line number Diff line Loading @@ -70,7 +70,7 @@ public class AudioRoute { return; } Log.i(this, "creating AudioRoute with type %s and address %s, retry count %d", Log.i(this, "createRetry; type=%s, address=%s, retryCount=%d", DEVICE_TYPE_STRINGS.get(type), bluetoothAddress, retryCount); AudioDeviceInfo routeInfo = null; List<AudioDeviceInfo> infos = audioManager.getAvailableCommunicationDevices(); Loading Loading @@ -239,7 +239,8 @@ public class AudioRoute { void onDestRouteAsPendingRoute(boolean active, PendingAudioRoute pendingAudioRoute, BluetoothDevice device, AudioManager audioManager, BluetoothRouteManager bluetoothRouteManager, boolean isScoAudioConnected) { Log.i(this, "onDestRouteAsPendingRoute: active (%b), type (%d)", active, mAudioRouteType); Log.i(this, "onDestRouteAsPendingRoute: active (%b), type (%s)", active, DEVICE_TYPE_STRINGS.get(mAudioRouteType)); if (pendingAudioRoute.isActive() && !active) { clearCommunicationDevice(pendingAudioRoute, bluetoothRouteManager, audioManager); } else if (active) { Loading Loading @@ -281,8 +282,8 @@ public class AudioRoute { if (result) { pendingAudioRoute.setCommunicationDeviceType(mAudioRouteType); } Log.i(this, "Result of setting communication device for audio " + "route (%s) - %b", this, result); Log.i(this, "onDestRouteAsPendingRoute: route=%s, " + "AudioManager#setCommunicationDevice()=%b", this, result); break; } } Loading Loading @@ -380,11 +381,11 @@ public class AudioRoute { int result = BluetoothStatusCodes.SUCCESS; if (pendingAudioRoute.getCommunicationDeviceType() == TYPE_BLUETOOTH_SCO) { Log.i(this, "Disconnecting SCO device."); Log.i(this, "clearCommunicationDevice: Disconnecting SCO device."); result = bluetoothRouteManager.getDeviceManager().disconnectSco(); } else { Log.i(this, "Clearing communication device for audio type %d.", pendingAudioRoute.getCommunicationDeviceType()); Log.i(this, "clearCommunicationDevice: AudioManager#clearCommunicationDevice, type=%s", DEVICE_TYPE_STRINGS.get(pendingAudioRoute.getCommunicationDeviceType())); audioManager.clearCommunicationDevice(); } Loading src/com/android/server/telecom/CallAudioModeStateMachine.java +18 −2 Original line number Diff line number Diff line Loading @@ -288,12 +288,14 @@ public class CallAudioModeStateMachine extends StateMachine { .getCurrentLocallyRequestedCommunicationDevice()); } if (mFeatureFlags.setAudioModeBeforeAbandonFocus()) { Log.i(this, "enter: AudioManager#setMode(MODE_NORMAL)"); mAudioManager.setMode(AudioManager.MODE_NORMAL); mCallAudioManager.setCallAudioRouteFocusState( CallAudioRouteStateMachine.NO_FOCUS); } else { mCallAudioManager.setCallAudioRouteFocusState( CallAudioRouteStateMachine.NO_FOCUS); Log.i(this, "enter: AudioManager#setMode(MODE_NORMAL)"); mAudioManager.setMode(AudioManager.MODE_NORMAL); } mLocalLog.log("Mode MODE_NORMAL"); Loading Loading @@ -347,11 +349,14 @@ public class CallAudioModeStateMachine extends StateMachine { + args.toString()); return HANDLED; case AUDIO_OPERATIONS_COMPLETE: Log.i(LOG_TAG, "Abandoning audio focus: now UNFOCUSED"); if (mFeatureFlags.telecomResolveHiddenDependencies()) { if (mCurrentAudioFocusRequest != null) { Log.i(this, "AudioOperationsComplete: " + "AudioManager#abandonAudioFocusRequest(); now unfocused"); mAudioManager.abandonAudioFocusRequest(mCurrentAudioFocusRequest); mCurrentAudioFocusRequest = null; } else { Log.i(this, "AudioOperationsComplete: already unfocused"); } } else { mAudioManager.abandonAudioFocusForCall(); Loading @@ -377,6 +382,7 @@ public class CallAudioModeStateMachine extends StateMachine { mLocalLog.log("Enter AUDIO_PROCESSING"); if (mIsInitialized) { mCallAudioManager.setCallAudioRouteFocusState(CallAudioRouteStateMachine.NO_FOCUS); Log.i(this, "enter: AudioManager#setMode(MODE_AUDIO_PROCESSING)"); mAudioManager.setMode(NEW_AUDIO_MODE_FOR_AUDIO_PROCESSING); mLocalLog.log("Mode MODE_CALL_SCREENING"); mMostRecentMode = NEW_AUDIO_MODE_FOR_AUDIO_PROCESSING; Loading Loading @@ -431,7 +437,8 @@ public class CallAudioModeStateMachine extends StateMachine { transitionTo(mStreamingFocusState); return HANDLED; case AUDIO_OPERATIONS_COMPLETE: Log.i(LOG_TAG, "Abandoning audio focus: now AUDIO_PROCESSING"); Log.i(LOG_TAG, "AudioManager#abandonAudioFocusRequest: now " + "AUDIO_PROCESSING"); if (mFeatureFlags.telecomResolveHiddenDependencies()) { if (mCurrentAudioFocusRequest != null) { mAudioManager.abandonAudioFocusRequest(mCurrentAudioFocusRequest); Loading Loading @@ -466,6 +473,7 @@ public class CallAudioModeStateMachine extends StateMachine { if (mCallAudioManager.startRinging()) { if (mFeatureFlags.telecomResolveHiddenDependencies()) { mCurrentAudioFocusRequest = RING_AUDIO_FOCUS_REQUEST; Log.i(this, "tryStartRinging: AudioManager#requestAudioFocus(RING)"); mAudioManager.requestAudioFocus(RING_AUDIO_FOCUS_REQUEST); } else { mAudioManager.requestAudioFocusForCall( Loading @@ -474,6 +482,7 @@ public class CallAudioModeStateMachine extends StateMachine { // Do not set MODE_RINGTONE if we were previously in the CALL_SCREENING mode -- // this trips up the audio system. if (mAudioManager.getMode() != AudioManager.MODE_CALL_SCREENING) { Log.i(this, "enter: AudioManager#setMode(MODE_RINGTONE)"); mAudioManager.setMode(AudioManager.MODE_RINGTONE); mLocalLog.log("Mode MODE_RINGTONE"); } Loading Loading @@ -569,11 +578,13 @@ public class CallAudioModeStateMachine extends StateMachine { mLocalLog.log("Enter SIM_CALL"); if (mFeatureFlags.telecomResolveHiddenDependencies()) { mCurrentAudioFocusRequest = CALL_AUDIO_FOCUS_REQUEST; Log.i(this, "enter: AudioManager#requestAudioFocus(CALL)"); mAudioManager.requestAudioFocus(CALL_AUDIO_FOCUS_REQUEST); } else { mAudioManager.requestAudioFocusForCall(AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); } Log.i(this, "enter: AudioManager#setMode(MODE_IN_CALL)"); mAudioManager.setMode(AudioManager.MODE_IN_CALL); mLocalLog.log("Mode MODE_IN_CALL"); mMostRecentMode = AudioManager.MODE_IN_CALL; Loading Loading @@ -657,11 +668,13 @@ public class CallAudioModeStateMachine extends StateMachine { mLocalLog.log("Enter VOIP_CALL"); if (mFeatureFlags.telecomResolveHiddenDependencies()) { mCurrentAudioFocusRequest = CALL_AUDIO_FOCUS_REQUEST; Log.i(this, "enter: AudioManager#requestAudioFocus(CALL)"); mAudioManager.requestAudioFocus(CALL_AUDIO_FOCUS_REQUEST); } else { mAudioManager.requestAudioFocusForCall(AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); } Log.i(this, "enter: AudioManager#setMode(MODE_IN_COMMUNICATION)"); mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); mLocalLog.log("Mode MODE_IN_COMMUNICATION"); mMostRecentMode = AudioManager.MODE_IN_COMMUNICATION; Loading Loading @@ -740,6 +753,7 @@ public class CallAudioModeStateMachine extends StateMachine { Log.i(LOG_TAG, "Audio focus entering streaming state"); mLocalLog.log("Enter Streaming"); mLocalLog.log("Mode MODE_COMMUNICATION_REDIRECT"); Log.i(this, "enter: AudioManager#setMode(MODE_COMMUNICATION_REDIRECT"); mAudioManager.setMode(AudioManager.MODE_COMMUNICATION_REDIRECT); mMostRecentMode = AudioManager.MODE_NORMAL; mCallAudioManager.setCallAudioRouteFocusState(CallAudioRouteStateMachine.ACTIVE_FOCUS); Loading Loading @@ -817,11 +831,13 @@ public class CallAudioModeStateMachine extends StateMachine { mLocalLog.log("Enter TONE/HOLDING"); if (mFeatureFlags.telecomResolveHiddenDependencies()) { mCurrentAudioFocusRequest = CALL_AUDIO_FOCUS_REQUEST; Log.i(this, "enter: AudioManager#requestAudioFocus(CALL)"); mAudioManager.requestAudioFocus(CALL_AUDIO_FOCUS_REQUEST); } else { mAudioManager.requestAudioFocusForCall(AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); } Log.i(this, "enter: AudioManager#setMode(%d)", mMostRecentMode); mAudioManager.setMode(mMostRecentMode); mLocalLog.log("Mode " + mMostRecentMode); mCallAudioManager.setCallAudioRouteFocusStateForEndTone(); Loading src/com/android/server/telecom/CallAudioRouteController.java +4 −0 Original line number Diff line number Diff line Loading @@ -799,6 +799,10 @@ public class CallAudioRouteController implements CallAudioRouteAdapter { switch (focus) { case NO_FOCUS -> { if (mIsActive) { // Notify the CallAudioModeStateMachine that audio operations are complete so // that we can relinquish audio focus. mCallAudioManager.notifyAudioOperationsComplete(); // Reset mute state after call ends. handleMuteChanged(false); // Route back to inactive route. Loading src/com/android/server/telecom/bluetooth/BluetoothDeviceManager.java +87 −55 File changed.Preview size limit exceeded, changes collapsed. Show changes tests/src/com/android/server/telecom/tests/CallAudioRouteControllerTest.java +9 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,7 @@ import android.content.BroadcastReceiver; import android.content.Intent; import android.content.IntentFilter; import android.media.AudioDeviceInfo; import android.media.AudioFocusRequest; import android.media.AudioManager; import android.media.IAudioService; import android.media.audiopolicy.AudioProductStrategy; Loading Loading @@ -376,6 +377,11 @@ public class CallAudioRouteControllerTest extends TelecomTestCase { assertTrue(mController.isActive()); mController.sendMessageWithSessionInfo(SWITCH_FOCUS, NO_FOCUS, 0); // Ensure we tell the CallAudioManager that audio operations are done so that we can ensure // audio focus is relinquished. verify(mCallAudioManager, timeout(TEST_TIMEOUT)).notifyAudioOperationsComplete(); // Ensure the BT device is disconnected. verify(mBluetoothDeviceManager, timeout(TEST_TIMEOUT).atLeastOnce()).disconnectSco(); assertFalse(mController.isActive()); } Loading Loading @@ -653,6 +659,9 @@ public class CallAudioRouteControllerTest extends TelecomTestCase { anyInt(), anyString()); verify(mCallsManager, timeout(TEST_TIMEOUT).atLeastOnce()).onCallAudioStateChanged( any(CallAudioState.class), eq(expectedState)); // Ensure we tell the CallAudioManager that audio operations are done so that we can ensure // audio focus is relinquished. verify(mCallAudioManager, timeout(TEST_TIMEOUT)).notifyAudioOperationsComplete(); } @SmallTest Loading Loading
src/com/android/server/telecom/AudioRoute.java +8 −7 Original line number Diff line number Diff line Loading @@ -70,7 +70,7 @@ public class AudioRoute { return; } Log.i(this, "creating AudioRoute with type %s and address %s, retry count %d", Log.i(this, "createRetry; type=%s, address=%s, retryCount=%d", DEVICE_TYPE_STRINGS.get(type), bluetoothAddress, retryCount); AudioDeviceInfo routeInfo = null; List<AudioDeviceInfo> infos = audioManager.getAvailableCommunicationDevices(); Loading Loading @@ -239,7 +239,8 @@ public class AudioRoute { void onDestRouteAsPendingRoute(boolean active, PendingAudioRoute pendingAudioRoute, BluetoothDevice device, AudioManager audioManager, BluetoothRouteManager bluetoothRouteManager, boolean isScoAudioConnected) { Log.i(this, "onDestRouteAsPendingRoute: active (%b), type (%d)", active, mAudioRouteType); Log.i(this, "onDestRouteAsPendingRoute: active (%b), type (%s)", active, DEVICE_TYPE_STRINGS.get(mAudioRouteType)); if (pendingAudioRoute.isActive() && !active) { clearCommunicationDevice(pendingAudioRoute, bluetoothRouteManager, audioManager); } else if (active) { Loading Loading @@ -281,8 +282,8 @@ public class AudioRoute { if (result) { pendingAudioRoute.setCommunicationDeviceType(mAudioRouteType); } Log.i(this, "Result of setting communication device for audio " + "route (%s) - %b", this, result); Log.i(this, "onDestRouteAsPendingRoute: route=%s, " + "AudioManager#setCommunicationDevice()=%b", this, result); break; } } Loading Loading @@ -380,11 +381,11 @@ public class AudioRoute { int result = BluetoothStatusCodes.SUCCESS; if (pendingAudioRoute.getCommunicationDeviceType() == TYPE_BLUETOOTH_SCO) { Log.i(this, "Disconnecting SCO device."); Log.i(this, "clearCommunicationDevice: Disconnecting SCO device."); result = bluetoothRouteManager.getDeviceManager().disconnectSco(); } else { Log.i(this, "Clearing communication device for audio type %d.", pendingAudioRoute.getCommunicationDeviceType()); Log.i(this, "clearCommunicationDevice: AudioManager#clearCommunicationDevice, type=%s", DEVICE_TYPE_STRINGS.get(pendingAudioRoute.getCommunicationDeviceType())); audioManager.clearCommunicationDevice(); } Loading
src/com/android/server/telecom/CallAudioModeStateMachine.java +18 −2 Original line number Diff line number Diff line Loading @@ -288,12 +288,14 @@ public class CallAudioModeStateMachine extends StateMachine { .getCurrentLocallyRequestedCommunicationDevice()); } if (mFeatureFlags.setAudioModeBeforeAbandonFocus()) { Log.i(this, "enter: AudioManager#setMode(MODE_NORMAL)"); mAudioManager.setMode(AudioManager.MODE_NORMAL); mCallAudioManager.setCallAudioRouteFocusState( CallAudioRouteStateMachine.NO_FOCUS); } else { mCallAudioManager.setCallAudioRouteFocusState( CallAudioRouteStateMachine.NO_FOCUS); Log.i(this, "enter: AudioManager#setMode(MODE_NORMAL)"); mAudioManager.setMode(AudioManager.MODE_NORMAL); } mLocalLog.log("Mode MODE_NORMAL"); Loading Loading @@ -347,11 +349,14 @@ public class CallAudioModeStateMachine extends StateMachine { + args.toString()); return HANDLED; case AUDIO_OPERATIONS_COMPLETE: Log.i(LOG_TAG, "Abandoning audio focus: now UNFOCUSED"); if (mFeatureFlags.telecomResolveHiddenDependencies()) { if (mCurrentAudioFocusRequest != null) { Log.i(this, "AudioOperationsComplete: " + "AudioManager#abandonAudioFocusRequest(); now unfocused"); mAudioManager.abandonAudioFocusRequest(mCurrentAudioFocusRequest); mCurrentAudioFocusRequest = null; } else { Log.i(this, "AudioOperationsComplete: already unfocused"); } } else { mAudioManager.abandonAudioFocusForCall(); Loading @@ -377,6 +382,7 @@ public class CallAudioModeStateMachine extends StateMachine { mLocalLog.log("Enter AUDIO_PROCESSING"); if (mIsInitialized) { mCallAudioManager.setCallAudioRouteFocusState(CallAudioRouteStateMachine.NO_FOCUS); Log.i(this, "enter: AudioManager#setMode(MODE_AUDIO_PROCESSING)"); mAudioManager.setMode(NEW_AUDIO_MODE_FOR_AUDIO_PROCESSING); mLocalLog.log("Mode MODE_CALL_SCREENING"); mMostRecentMode = NEW_AUDIO_MODE_FOR_AUDIO_PROCESSING; Loading Loading @@ -431,7 +437,8 @@ public class CallAudioModeStateMachine extends StateMachine { transitionTo(mStreamingFocusState); return HANDLED; case AUDIO_OPERATIONS_COMPLETE: Log.i(LOG_TAG, "Abandoning audio focus: now AUDIO_PROCESSING"); Log.i(LOG_TAG, "AudioManager#abandonAudioFocusRequest: now " + "AUDIO_PROCESSING"); if (mFeatureFlags.telecomResolveHiddenDependencies()) { if (mCurrentAudioFocusRequest != null) { mAudioManager.abandonAudioFocusRequest(mCurrentAudioFocusRequest); Loading Loading @@ -466,6 +473,7 @@ public class CallAudioModeStateMachine extends StateMachine { if (mCallAudioManager.startRinging()) { if (mFeatureFlags.telecomResolveHiddenDependencies()) { mCurrentAudioFocusRequest = RING_AUDIO_FOCUS_REQUEST; Log.i(this, "tryStartRinging: AudioManager#requestAudioFocus(RING)"); mAudioManager.requestAudioFocus(RING_AUDIO_FOCUS_REQUEST); } else { mAudioManager.requestAudioFocusForCall( Loading @@ -474,6 +482,7 @@ public class CallAudioModeStateMachine extends StateMachine { // Do not set MODE_RINGTONE if we were previously in the CALL_SCREENING mode -- // this trips up the audio system. if (mAudioManager.getMode() != AudioManager.MODE_CALL_SCREENING) { Log.i(this, "enter: AudioManager#setMode(MODE_RINGTONE)"); mAudioManager.setMode(AudioManager.MODE_RINGTONE); mLocalLog.log("Mode MODE_RINGTONE"); } Loading Loading @@ -569,11 +578,13 @@ public class CallAudioModeStateMachine extends StateMachine { mLocalLog.log("Enter SIM_CALL"); if (mFeatureFlags.telecomResolveHiddenDependencies()) { mCurrentAudioFocusRequest = CALL_AUDIO_FOCUS_REQUEST; Log.i(this, "enter: AudioManager#requestAudioFocus(CALL)"); mAudioManager.requestAudioFocus(CALL_AUDIO_FOCUS_REQUEST); } else { mAudioManager.requestAudioFocusForCall(AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); } Log.i(this, "enter: AudioManager#setMode(MODE_IN_CALL)"); mAudioManager.setMode(AudioManager.MODE_IN_CALL); mLocalLog.log("Mode MODE_IN_CALL"); mMostRecentMode = AudioManager.MODE_IN_CALL; Loading Loading @@ -657,11 +668,13 @@ public class CallAudioModeStateMachine extends StateMachine { mLocalLog.log("Enter VOIP_CALL"); if (mFeatureFlags.telecomResolveHiddenDependencies()) { mCurrentAudioFocusRequest = CALL_AUDIO_FOCUS_REQUEST; Log.i(this, "enter: AudioManager#requestAudioFocus(CALL)"); mAudioManager.requestAudioFocus(CALL_AUDIO_FOCUS_REQUEST); } else { mAudioManager.requestAudioFocusForCall(AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); } Log.i(this, "enter: AudioManager#setMode(MODE_IN_COMMUNICATION)"); mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); mLocalLog.log("Mode MODE_IN_COMMUNICATION"); mMostRecentMode = AudioManager.MODE_IN_COMMUNICATION; Loading Loading @@ -740,6 +753,7 @@ public class CallAudioModeStateMachine extends StateMachine { Log.i(LOG_TAG, "Audio focus entering streaming state"); mLocalLog.log("Enter Streaming"); mLocalLog.log("Mode MODE_COMMUNICATION_REDIRECT"); Log.i(this, "enter: AudioManager#setMode(MODE_COMMUNICATION_REDIRECT"); mAudioManager.setMode(AudioManager.MODE_COMMUNICATION_REDIRECT); mMostRecentMode = AudioManager.MODE_NORMAL; mCallAudioManager.setCallAudioRouteFocusState(CallAudioRouteStateMachine.ACTIVE_FOCUS); Loading Loading @@ -817,11 +831,13 @@ public class CallAudioModeStateMachine extends StateMachine { mLocalLog.log("Enter TONE/HOLDING"); if (mFeatureFlags.telecomResolveHiddenDependencies()) { mCurrentAudioFocusRequest = CALL_AUDIO_FOCUS_REQUEST; Log.i(this, "enter: AudioManager#requestAudioFocus(CALL)"); mAudioManager.requestAudioFocus(CALL_AUDIO_FOCUS_REQUEST); } else { mAudioManager.requestAudioFocusForCall(AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); } Log.i(this, "enter: AudioManager#setMode(%d)", mMostRecentMode); mAudioManager.setMode(mMostRecentMode); mLocalLog.log("Mode " + mMostRecentMode); mCallAudioManager.setCallAudioRouteFocusStateForEndTone(); Loading
src/com/android/server/telecom/CallAudioRouteController.java +4 −0 Original line number Diff line number Diff line Loading @@ -799,6 +799,10 @@ public class CallAudioRouteController implements CallAudioRouteAdapter { switch (focus) { case NO_FOCUS -> { if (mIsActive) { // Notify the CallAudioModeStateMachine that audio operations are complete so // that we can relinquish audio focus. mCallAudioManager.notifyAudioOperationsComplete(); // Reset mute state after call ends. handleMuteChanged(false); // Route back to inactive route. Loading
src/com/android/server/telecom/bluetooth/BluetoothDeviceManager.java +87 −55 File changed.Preview size limit exceeded, changes collapsed. Show changes
tests/src/com/android/server/telecom/tests/CallAudioRouteControllerTest.java +9 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,7 @@ import android.content.BroadcastReceiver; import android.content.Intent; import android.content.IntentFilter; import android.media.AudioDeviceInfo; import android.media.AudioFocusRequest; import android.media.AudioManager; import android.media.IAudioService; import android.media.audiopolicy.AudioProductStrategy; Loading Loading @@ -376,6 +377,11 @@ public class CallAudioRouteControllerTest extends TelecomTestCase { assertTrue(mController.isActive()); mController.sendMessageWithSessionInfo(SWITCH_FOCUS, NO_FOCUS, 0); // Ensure we tell the CallAudioManager that audio operations are done so that we can ensure // audio focus is relinquished. verify(mCallAudioManager, timeout(TEST_TIMEOUT)).notifyAudioOperationsComplete(); // Ensure the BT device is disconnected. verify(mBluetoothDeviceManager, timeout(TEST_TIMEOUT).atLeastOnce()).disconnectSco(); assertFalse(mController.isActive()); } Loading Loading @@ -653,6 +659,9 @@ public class CallAudioRouteControllerTest extends TelecomTestCase { anyInt(), anyString()); verify(mCallsManager, timeout(TEST_TIMEOUT).atLeastOnce()).onCallAudioStateChanged( any(CallAudioState.class), eq(expectedState)); // Ensure we tell the CallAudioManager that audio operations are done so that we can ensure // audio focus is relinquished. verify(mCallAudioManager, timeout(TEST_TIMEOUT)).notifyAudioOperationsComplete(); } @SmallTest Loading