From 6dd78c1759e8b1bc95fbae2ffe87eaecad5a2041 Mon Sep 17 00:00:00 2001 From: Jack He Date: Mon, 12 Feb 2018 21:00:24 -0800 Subject: [PATCH] Bluetooth: Enable in-band ringing in vibration mode (1/4) * Add AudioSystem.FOR_VIBRATE_RINGING mode to match the native layer AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING force mode * Switch to this mode when Bluetooth SCO is connected * Modify AudioService.muteRingerModeStreams() method to not mute ringer volume when Bluetooth SCO is ON. Also, when ringer is unmuted, mirror speaker ringtone volume on Bluetooth SCO ringer Bug: 72647074 Test: Call phone in vibration mode and hear ringtone on HFP enabled headset, verify that ringtone is only played through headset. Then disconnect headset and call again to verify that ringtone does not play through phone speaker in vibration mode. Change-Id: I7d642020710c085f0e1f27c750c74b0e2fb57398 --- media/java/android/media/AudioSystem.java | 3 +- .../android/server/audio/AudioService.java | 34 +++++++++++++++---- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index 3885f90176559..acab8bbb2e0b3 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -747,7 +747,8 @@ public class AudioSystem public static final int FOR_SYSTEM = 4; public static final int FOR_HDMI_SYSTEM_AUDIO = 5; public static final int FOR_ENCODED_SURROUND = 6; - private static final int NUM_FORCE_USE = 7; + public static final int FOR_VIBRATE_RINGING = 7; + private static final int NUM_FORCE_USE = 8; public static String forceUseUsageToString(int usage) { switch (usage) { diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 3a23f18b2f48a..5021ec3eb604e 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -2543,14 +2543,24 @@ public class AudioService extends IAudioService.Stub mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); } - final boolean ringerModeMute = mRingerMode == AudioManager.RINGER_MODE_VIBRATE - || mRingerMode == AudioManager.RINGER_MODE_SILENT; + final int ringerMode = mRingerMode; // Read ringer mode as reading primitives is atomic + final boolean ringerModeMute = ringerMode == AudioManager.RINGER_MODE_VIBRATE + || ringerMode == AudioManager.RINGER_MODE_SILENT; + final boolean shouldRingSco = ringerMode == AudioManager.RINGER_MODE_VIBRATE + && isBluetoothScoOn(); + // Ask audio policy engine to force use Bluetooth SCO channel if needed + final String eventSource = "muteRingerModeStreams() from u/pid:" + Binder.getCallingUid() + + "/" + Binder.getCallingPid(); + sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE, AudioSystem.FOR_VIBRATE_RINGING, + shouldRingSco ? AudioSystem.FORCE_BT_SCO : AudioSystem.FORCE_NONE, eventSource, 0); for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { final boolean isMuted = isStreamMutedByRingerOrZenMode(streamType); + final boolean muteAllowedBySco = + !(shouldRingSco && streamType == AudioSystem.STREAM_RING); final boolean shouldZenMute = shouldZenMuteStream(streamType); final boolean shouldMute = shouldZenMute || (ringerModeMute - && isStreamAffectedByRingerMode(streamType)); + && isStreamAffectedByRingerMode(streamType) && muteAllowedBySco); if (isMuted == shouldMute) continue; if (!shouldMute) { // unmute @@ -3191,6 +3201,8 @@ public class AudioService extends IAudioService.Stub AudioSystem.FOR_COMMUNICATION, mForcedUseForComm, eventSource, 0); sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE, AudioSystem.FOR_RECORD, mForcedUseForComm, eventSource, 0); + // Un-mute ringtone stream volume + setRingerModeInt(getRingerModeInternal(), false); } /** @see AudioManager#isBluetoothScoOn() */ @@ -4783,7 +4795,7 @@ public class AudioService extends IAudioService.Stub } public boolean setIndex(int index, int device, String caller) { - boolean changed = false; + boolean changed; int oldIndex; synchronized (mSettingsLock) { synchronized (VolumeStreamState.class) { @@ -4800,7 +4812,7 @@ public class AudioService extends IAudioService.Stub // - there is no volume index stored for this device on alias stream. // If changing volume of current device, also change volume of current // device on aliased stream - final boolean currentDevice = (device == getDeviceForStream(mStreamType)); + final boolean isCurrentDevice = (device == getDeviceForStream(mStreamType)); final int numStreamTypes = AudioSystem.getNumStreamTypes(); for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) { final VolumeStreamState aliasStreamState = mStreamStates[streamType]; @@ -4809,12 +4821,22 @@ public class AudioService extends IAudioService.Stub (changed || !aliasStreamState.hasIndexForDevice(device))) { final int scaledIndex = rescaleIndex(index, mStreamType, streamType); aliasStreamState.setIndex(scaledIndex, device, caller); - if (currentDevice) { + if (isCurrentDevice) { aliasStreamState.setIndex(scaledIndex, getDeviceForStream(streamType), caller); } } } + // Mirror changes in SPEAKER ringtone volume on SCO when + if (changed && mStreamType == AudioSystem.STREAM_RING + && device == AudioSystem.DEVICE_OUT_SPEAKER) { + for (int i = 0; i < mIndexMap.size(); i++) { + int otherDevice = mIndexMap.keyAt(i); + if ((otherDevice & AudioSystem.DEVICE_OUT_ALL_SCO) != 0) { + mIndexMap.put(otherDevice, index); + } + } + } } } if (changed) {