From ad37c2c40695793159df87aaf159f404105869c6 Mon Sep 17 00:00:00 2001 From: Jean-Michel Trivi Date: Fri, 19 Jan 2018 09:40:36 -0800 Subject: [PATCH] AudioService: fix deadlock between readSettings() and VSS.setAllIndexes() Locking order is mSettingsLock -> VolumeStreamState.class Missing sync on mSettingsLock was causing deadlock between VolumeStreamState.setAllIndexes() and readSettings(). Mark that setAllIndexesToMax() is properly sync'd on mSettingsLock. Bug: 72122435 Test: chance Change-Id: I4bd4037fec290dd6ba586c7090e1b377543041ab --- .../com/android/server/audio/AudioService.java | 35 ++++++++++++---------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 799f2a92bc33..aacee268b556 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -4503,27 +4503,30 @@ public class AudioService extends IAudioService.Stub if (mStreamType == srcStream.mStreamType) { return; } - synchronized (VolumeStreamState.class) { - int srcStreamType = srcStream.getStreamType(); - // apply default device volume from source stream to all devices first in case - // some devices are present in this stream state but not in source stream state - int index = srcStream.getIndex(AudioSystem.DEVICE_OUT_DEFAULT); - index = rescaleIndex(index, srcStreamType, mStreamType); - for (int i = 0; i < mIndexMap.size(); i++) { - mIndexMap.put(mIndexMap.keyAt(i), index); - } - // Now apply actual volume for devices in source stream state - SparseIntArray srcMap = srcStream.mIndexMap; - for (int i = 0; i < srcMap.size(); i++) { - int device = srcMap.keyAt(i); - index = srcMap.valueAt(i); + synchronized (mSettingsLock) { + synchronized (VolumeStreamState.class) { + int srcStreamType = srcStream.getStreamType(); + // apply default device volume from source stream to all devices first in case + // some devices are present in this stream state but not in source stream state + int index = srcStream.getIndex(AudioSystem.DEVICE_OUT_DEFAULT); index = rescaleIndex(index, srcStreamType, mStreamType); - - setIndex(index, device, caller); + for (int i = 0; i < mIndexMap.size(); i++) { + mIndexMap.put(mIndexMap.keyAt(i), index); + } + // Now apply actual volume for devices in source stream state + SparseIntArray srcMap = srcStream.mIndexMap; + for (int i = 0; i < srcMap.size(); i++) { + int device = srcMap.keyAt(i); + index = srcMap.valueAt(i); + index = rescaleIndex(index, srcStreamType, mStreamType); + + setIndex(index, device, caller); + } } } } + @GuardedBy("mSettingsLock") public void setAllIndexesToMax() { synchronized (VolumeStreamState.class) { for (int i = 0; i < mIndexMap.size(); i++) { -- 2.11.0