Loading services/core/java/com/android/server/audio/AudioDeviceBroker.java +4 −0 Original line number Diff line number Diff line Loading @@ -3110,6 +3110,10 @@ public class AudioDeviceBroker { return mDeviceInventory.findBtDeviceStateForAddress(address, deviceType); } boolean hasAlwaysRingDevice() { return mDeviceInventory.hasAlwaysRingDevice(); } void addAudioDeviceWithCategoryInInventoryIfNeeded(@NonNull String address, @AudioDeviceCategory int btAudioDeviceCategory) { mDeviceInventory.addAudioDeviceWithCategoryInInventoryIfNeeded(address, Loading services/core/java/com/android/server/audio/AudioDeviceInventory.java +54 −0 Original line number Diff line number Diff line Loading @@ -533,6 +533,39 @@ public class AudioDeviceInventory { } } /** * Whether there's a connected device that should always ring (outside of silent mode) * Writes are protected by mDevicesLock, reads are atomic in {@link #hasAlwaysRingDevice()} */ private final AtomicBoolean mAlwaysRingDeviceConnected = new AtomicBoolean(false); /** * @return whether there's a connected device that should always ring (outside of silent mode) */ boolean hasAlwaysRingDevice() { return mAlwaysRingDeviceConnected.get(); } /** * Holds the list of native device types that are candidates for "always ring" */ private static final Set<Integer> ALWAYS_RING_DEVICE_CANDIDATES; /** * Holds the list of device categories that are "always ring" */ private static final Set<Integer> ALWAYS_RING_CATEGORIES; static { ALWAYS_RING_DEVICE_CANDIDATES = new HashSet<>(); ALWAYS_RING_DEVICE_CANDIDATES.addAll(DEVICE_OUT_ALL_SCO_SET); ALWAYS_RING_DEVICE_CANDIDATES.add(DEVICE_OUT_BLE_HEADSET); ALWAYS_RING_CATEGORIES = new HashSet<>(); ALWAYS_RING_CATEGORIES.add(AudioManager.AUDIO_DEVICE_CATEGORY_HEADPHONES); ALWAYS_RING_CATEGORIES.add(AudioManager.AUDIO_DEVICE_CATEGORY_CARKIT); } /** * List of devices actually connected to AudioPolicy (through AudioSystem). * Each entry is a String, generated from {@link DeviceInfo#getKey()}. Loading Loading @@ -863,6 +896,7 @@ public class AudioDeviceInventory { mDeviceBroker.onSetBtScoActiveDevice(null, false /*deviceSwitch*/); } } updateAlwaysRingDeviceConnected(); mAppliedStrategyRolesInt.clear(); mAppliedPresetRolesInt.clear(); Loading Loading @@ -3247,6 +3281,25 @@ public class AudioDeviceInventory { new Exception()); } } updateAlwaysRingDeviceConnected(); } @GuardedBy("mDevicesLock") private void updateAlwaysRingDeviceConnected() { boolean foundAlwaysRingDevice = false; for (DeviceInfo devInfo : mConnectedDevices.values()) { // device type is candidate? if (ALWAYS_RING_DEVICE_CANDIDATES.contains(devInfo.mDeviceType)) { AdiDeviceState ads = findBtDeviceStateForAddress( devInfo.mDeviceAddress, devInfo.mDeviceType); // device category is a match? if (ads != null && ALWAYS_RING_CATEGORIES.contains(ads.getAudioDeviceCategory())) { foundAlwaysRingDevice = true; break; } } } mAlwaysRingDeviceConnected.set(foundAlwaysRingDevice); } /** Loading @@ -3271,6 +3324,7 @@ public class AudioDeviceInventory { new Exception()); } } updateAlwaysRingDeviceConnected(); } //---------------------------------------------------------- Loading services/core/java/com/android/server/audio/AudioService.java +28 −11 Original line number Diff line number Diff line Loading @@ -6696,12 +6696,12 @@ public class AudioService extends IAudioService.Stub /* package */ void updateRingerModeMutedStreams() { synchronized (mSettingsLock) { muteRingerModeStreams(); updateStreamMuteFromRingerMode(); } } @GuardedBy("mSettingsLock") private void muteRingerModeStreams() { private void updateStreamMuteFromRingerMode() { // Mute stream if not previously muted by ringer mode and (ringer mode // is not RINGER_MODE_NORMAL OR stream is zen muted) and stream is affected by ringer mode. // Unmute stream if previously muted by ringer/zen mode and ringer mode Loading @@ -6722,7 +6722,7 @@ public class AudioService extends IAudioService.Stub || mBtCommDeviceActive.get() == BT_COMM_DEVICE_ACTIVE_BLE_SPEAKER); // Ask audio policy engine to force use Bluetooth SCO/BLE channel if needed final String eventSource = "muteRingerModeStreams() from u/pid:" + Binder.getCallingUid() "updateStreamMuteFromRingerMode() from u/pid:" + Binder.getCallingUid() + "/" + Binder.getCallingPid(); int forceUse = AudioSystem.FORCE_NONE; if (shouldRingSco) { Loading Loading @@ -6773,15 +6773,15 @@ public class AudioService extends IAudioService.Stub } } sRingerAndZenModeMutedStreams &= ~(1 << streamType); vss.mute(false, "muteRingerModeStreams"); vss.mute(false, "updateStreamMuteFromRingerMode"); } else { // mute sRingerAndZenModeMutedStreams |= (1 << streamType); vss.mute(true, "muteRingerModeStreams"); vss.mute(true, "updateStreamMuteFromRingerMode"); } } sMuteLogger.enqueue(new AudioServiceEvents.RingerZenMutedStreamsEvent( sRingerAndZenModeMutedStreams, "muteRingerModeStreams")); sRingerAndZenModeMutedStreams, "updateStreamMuteFromRingerMode")); } private boolean isAlarm(int streamType) { Loading @@ -6807,7 +6807,7 @@ public class AudioService extends IAudioService.Stub synchronized(mSettingsLock) { change = mRingerMode != ringerMode; mRingerMode = ringerMode; muteRingerModeStreams(); updateStreamMuteFromRingerMode(); } // Post a persist ringer mode msg Loading Loading @@ -15494,8 +15494,25 @@ public class AudioService extends IAudioService.Stub // AudioAttributes of the notification record is 0 (non-zero volume implies // not silenced by SILENT or VIBRATE ringer mode) final int stream = AudioAttributes.toLegacyStreamType(aa); final boolean mutingFromVolume = getStreamVolume(stream) == 0; if (mutingFromVolume) { boolean maybeMutingFromVolume = getStreamVolume(stream) == 0; // Exception with ringMyCar // if in vibrate mode, // and if an HFP device is available and is of type carkit // or headphones, // then ringtones should play even when the stream is muted. if (ringMyCar() && maybeMutingFromVolume && (getRingerModeExternal() == RINGER_MODE_VIBRATE) && (stream == AudioSystem.STREAM_RING)) { final boolean hasAlwaysRingDevice = mDeviceBroker.hasAlwaysRingDevice(); if (hasAlwaysRingDevice) { Slog.i(TAG, "shouldNotificationSoundPlay found always ring device"); } maybeMutingFromVolume = !hasAlwaysRingDevice; } if (maybeMutingFromVolume) { Slog.i(TAG, "shouldNotificationSoundPlay false: muted stream:" + stream + " attr:" + aa); return false; Loading
services/core/java/com/android/server/audio/AudioDeviceBroker.java +4 −0 Original line number Diff line number Diff line Loading @@ -3110,6 +3110,10 @@ public class AudioDeviceBroker { return mDeviceInventory.findBtDeviceStateForAddress(address, deviceType); } boolean hasAlwaysRingDevice() { return mDeviceInventory.hasAlwaysRingDevice(); } void addAudioDeviceWithCategoryInInventoryIfNeeded(@NonNull String address, @AudioDeviceCategory int btAudioDeviceCategory) { mDeviceInventory.addAudioDeviceWithCategoryInInventoryIfNeeded(address, Loading
services/core/java/com/android/server/audio/AudioDeviceInventory.java +54 −0 Original line number Diff line number Diff line Loading @@ -533,6 +533,39 @@ public class AudioDeviceInventory { } } /** * Whether there's a connected device that should always ring (outside of silent mode) * Writes are protected by mDevicesLock, reads are atomic in {@link #hasAlwaysRingDevice()} */ private final AtomicBoolean mAlwaysRingDeviceConnected = new AtomicBoolean(false); /** * @return whether there's a connected device that should always ring (outside of silent mode) */ boolean hasAlwaysRingDevice() { return mAlwaysRingDeviceConnected.get(); } /** * Holds the list of native device types that are candidates for "always ring" */ private static final Set<Integer> ALWAYS_RING_DEVICE_CANDIDATES; /** * Holds the list of device categories that are "always ring" */ private static final Set<Integer> ALWAYS_RING_CATEGORIES; static { ALWAYS_RING_DEVICE_CANDIDATES = new HashSet<>(); ALWAYS_RING_DEVICE_CANDIDATES.addAll(DEVICE_OUT_ALL_SCO_SET); ALWAYS_RING_DEVICE_CANDIDATES.add(DEVICE_OUT_BLE_HEADSET); ALWAYS_RING_CATEGORIES = new HashSet<>(); ALWAYS_RING_CATEGORIES.add(AudioManager.AUDIO_DEVICE_CATEGORY_HEADPHONES); ALWAYS_RING_CATEGORIES.add(AudioManager.AUDIO_DEVICE_CATEGORY_CARKIT); } /** * List of devices actually connected to AudioPolicy (through AudioSystem). * Each entry is a String, generated from {@link DeviceInfo#getKey()}. Loading Loading @@ -863,6 +896,7 @@ public class AudioDeviceInventory { mDeviceBroker.onSetBtScoActiveDevice(null, false /*deviceSwitch*/); } } updateAlwaysRingDeviceConnected(); mAppliedStrategyRolesInt.clear(); mAppliedPresetRolesInt.clear(); Loading Loading @@ -3247,6 +3281,25 @@ public class AudioDeviceInventory { new Exception()); } } updateAlwaysRingDeviceConnected(); } @GuardedBy("mDevicesLock") private void updateAlwaysRingDeviceConnected() { boolean foundAlwaysRingDevice = false; for (DeviceInfo devInfo : mConnectedDevices.values()) { // device type is candidate? if (ALWAYS_RING_DEVICE_CANDIDATES.contains(devInfo.mDeviceType)) { AdiDeviceState ads = findBtDeviceStateForAddress( devInfo.mDeviceAddress, devInfo.mDeviceType); // device category is a match? if (ads != null && ALWAYS_RING_CATEGORIES.contains(ads.getAudioDeviceCategory())) { foundAlwaysRingDevice = true; break; } } } mAlwaysRingDeviceConnected.set(foundAlwaysRingDevice); } /** Loading @@ -3271,6 +3324,7 @@ public class AudioDeviceInventory { new Exception()); } } updateAlwaysRingDeviceConnected(); } //---------------------------------------------------------- Loading
services/core/java/com/android/server/audio/AudioService.java +28 −11 Original line number Diff line number Diff line Loading @@ -6696,12 +6696,12 @@ public class AudioService extends IAudioService.Stub /* package */ void updateRingerModeMutedStreams() { synchronized (mSettingsLock) { muteRingerModeStreams(); updateStreamMuteFromRingerMode(); } } @GuardedBy("mSettingsLock") private void muteRingerModeStreams() { private void updateStreamMuteFromRingerMode() { // Mute stream if not previously muted by ringer mode and (ringer mode // is not RINGER_MODE_NORMAL OR stream is zen muted) and stream is affected by ringer mode. // Unmute stream if previously muted by ringer/zen mode and ringer mode Loading @@ -6722,7 +6722,7 @@ public class AudioService extends IAudioService.Stub || mBtCommDeviceActive.get() == BT_COMM_DEVICE_ACTIVE_BLE_SPEAKER); // Ask audio policy engine to force use Bluetooth SCO/BLE channel if needed final String eventSource = "muteRingerModeStreams() from u/pid:" + Binder.getCallingUid() "updateStreamMuteFromRingerMode() from u/pid:" + Binder.getCallingUid() + "/" + Binder.getCallingPid(); int forceUse = AudioSystem.FORCE_NONE; if (shouldRingSco) { Loading Loading @@ -6773,15 +6773,15 @@ public class AudioService extends IAudioService.Stub } } sRingerAndZenModeMutedStreams &= ~(1 << streamType); vss.mute(false, "muteRingerModeStreams"); vss.mute(false, "updateStreamMuteFromRingerMode"); } else { // mute sRingerAndZenModeMutedStreams |= (1 << streamType); vss.mute(true, "muteRingerModeStreams"); vss.mute(true, "updateStreamMuteFromRingerMode"); } } sMuteLogger.enqueue(new AudioServiceEvents.RingerZenMutedStreamsEvent( sRingerAndZenModeMutedStreams, "muteRingerModeStreams")); sRingerAndZenModeMutedStreams, "updateStreamMuteFromRingerMode")); } private boolean isAlarm(int streamType) { Loading @@ -6807,7 +6807,7 @@ public class AudioService extends IAudioService.Stub synchronized(mSettingsLock) { change = mRingerMode != ringerMode; mRingerMode = ringerMode; muteRingerModeStreams(); updateStreamMuteFromRingerMode(); } // Post a persist ringer mode msg Loading Loading @@ -15494,8 +15494,25 @@ public class AudioService extends IAudioService.Stub // AudioAttributes of the notification record is 0 (non-zero volume implies // not silenced by SILENT or VIBRATE ringer mode) final int stream = AudioAttributes.toLegacyStreamType(aa); final boolean mutingFromVolume = getStreamVolume(stream) == 0; if (mutingFromVolume) { boolean maybeMutingFromVolume = getStreamVolume(stream) == 0; // Exception with ringMyCar // if in vibrate mode, // and if an HFP device is available and is of type carkit // or headphones, // then ringtones should play even when the stream is muted. if (ringMyCar() && maybeMutingFromVolume && (getRingerModeExternal() == RINGER_MODE_VIBRATE) && (stream == AudioSystem.STREAM_RING)) { final boolean hasAlwaysRingDevice = mDeviceBroker.hasAlwaysRingDevice(); if (hasAlwaysRingDevice) { Slog.i(TAG, "shouldNotificationSoundPlay found always ring device"); } maybeMutingFromVolume = !hasAlwaysRingDevice; } if (maybeMutingFromVolume) { Slog.i(TAG, "shouldNotificationSoundPlay false: muted stream:" + stream + " attr:" + aa); return false;