From bf01d9b7a3cd3b7ebc40c0264667c77e7ecd4330 Mon Sep 17 00:00:00 2001 From: Sungsoo Lim Date: Wed, 16 Dec 2020 14:29:20 +0900 Subject: [PATCH] Cache stream volumes to prevent ANR MediaRourter uses main thread for internal operations, and ANR could happens if AudioService is not running when MediaRouter tried to get stream volumes. This CL avoids such ANR by caching stream volumes. Bug: 170327593 Test: manually Change-Id: I2560eda6436a89c754224cc835e48fe4f5e36827 --- media/java/android/media/MediaRouter.java | 26 ++++++++++++++++------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java index 4940c7647dbc6..36f7bed03bcd9 100644 --- a/media/java/android/media/MediaRouter.java +++ b/media/java/android/media/MediaRouter.java @@ -43,6 +43,7 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; import android.text.TextUtils; +import android.util.ArrayMap; import android.util.Log; import android.view.Display; import android.view.DisplayAddress; @@ -54,6 +55,7 @@ import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.concurrent.CopyOnWriteArrayList; @@ -111,6 +113,8 @@ public class MediaRouter { IMediaRouterClient mClient; MediaRouterClientState mClientState; + Map mStreamVolume = new ArrayMap<>(); + final IAudioRoutesObserver.Stub mAudioRoutesObserver = new IAudioRoutesObserver.Stub() { @Override public void dispatchAudioRoutesChanged(final AudioRoutesInfo newRoutes) { @@ -262,6 +266,17 @@ public class MediaRouter { mCurAudioRoutesInfo.bluetoothName = newRoutes.bluetoothName; } + int getStreamVolume(int streamType) { + if (!mStreamVolume.containsKey(streamType)) { + try { + mStreamVolume.put(streamType, mAudioService.getStreamVolume(streamType)); + } catch (RemoteException e) { + Log.e(TAG, "Error getting local stream volume", e); + } + } + return mStreamVolume.get(streamType); + } + boolean isBluetoothA2dpOn() { try { return mBluetoothA2dpRoute != null && mAudioService.isBluetoothA2dpOn(); @@ -1976,13 +1991,7 @@ public class MediaRouter { */ public int getVolume() { if (mPlaybackType == PLAYBACK_TYPE_LOCAL) { - int vol = 0; - try { - vol = sStatic.mAudioService.getStreamVolume(mPlaybackStream); - } catch (RemoteException e) { - Log.e(TAG, "Error getting local stream volume", e); - } - return vol; + return sStatic.getStreamVolume(mPlaybackStream); } else { return mVolume; } @@ -3139,11 +3148,12 @@ public class MediaRouter { if (intent.getAction().equals(AudioManager.VOLUME_CHANGED_ACTION)) { final int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1); + final int newVolume = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, 0); + sStatic.mStreamVolume.put(streamType, newVolume); if (streamType != AudioManager.STREAM_MUSIC) { return; } - final int newVolume = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, 0); final int oldVolume = intent.getIntExtra( AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, 0); if (newVolume != oldVolume) {