From 769fbae59ff673cc3ef9a55caa0f108814191e46 Mon Sep 17 00:00:00 2001 From: Jason Chiu Date: Wed, 8 Nov 2023 18:10:00 +0800 Subject: [PATCH] Prevent ANR while receiving volume broadcasts to update slices Use ConcurrentHashMap for registering Uri to the audio stream, and remove synchronized blocks from the receiver. Fix: 302234235 Fix: 301777614 Test: manual, robotest Change-Id: I5cca209baf9756aebb8ff44b7e8e9671d2c7aaad --- .../settings/slices/VolumeSliceHelper.java | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/com/android/settings/slices/VolumeSliceHelper.java b/src/com/android/settings/slices/VolumeSliceHelper.java index 1ba177823cc..8947cc48b46 100644 --- a/src/com/android/settings/slices/VolumeSliceHelper.java +++ b/src/com/android/settings/slices/VolumeSliceHelper.java @@ -24,7 +24,6 @@ import android.content.Intent; import android.content.IntentFilter; import android.media.AudioManager; import android.net.Uri; -import android.util.ArrayMap; import android.util.Log; import androidx.annotation.VisibleForTesting; @@ -32,6 +31,7 @@ import androidx.annotation.VisibleForTesting; import com.android.settingslib.SliceBroadcastRelay; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; /** * This helper is to handle the broadcasts of volume slices @@ -41,7 +41,7 @@ public class VolumeSliceHelper { private static final String TAG = "VolumeSliceHelper"; @VisibleForTesting - static Map sRegisteredUri = new ArrayMap<>(); + static Map sRegisteredUri = new ConcurrentHashMap<>(); @VisibleForTesting static IntentFilter sIntentFilter; @@ -133,23 +133,19 @@ public class VolumeSliceHelper { } private static void handleStreamChanged(Context context, int inputType) { - synchronized (sRegisteredUri) { - for (Map.Entry entry : sRegisteredUri.entrySet()) { - if (entry.getValue() == inputType) { - context.getContentResolver().notifyChange(entry.getKey(), null /* observer */); - if (inputType != AudioManager.STREAM_RING) { // Two URIs are mapped to ring - break; - } + for (Map.Entry entry : sRegisteredUri.entrySet()) { + if (entry.getValue() == inputType) { + context.getContentResolver().notifyChange(entry.getKey(), null /* observer */); + if (inputType != AudioManager.STREAM_RING) { // Two URIs are mapped to ring + break; } } } } private static void notifyAllStreamsChanged(Context context) { - synchronized (sRegisteredUri) { - sRegisteredUri.forEach((uri, audioStream) -> { - context.getContentResolver().notifyChange(uri, null /* observer */); - }); - } + sRegisteredUri.keySet().forEach(uri -> { + context.getContentResolver().notifyChange(uri, null /* observer */); + }); } }