MediaSessionRecord: fix volume stream query
Use the correct AudioAttributes method to query which volume stream
is associated with audio attributes.
Prevent AudioProductStrategy from returning invalid volume stream
types / stream types unknown for volume control
Bug: 148263626
Test: see bug
Change-Id: I64d01286815474d5e23fbe7e57c58bfdf57ebd3e
(cherry picked from commit 84d483e1e2b5728703802bc7c014242432b935f3)
diff --git a/media/java/android/media/audiopolicy/AudioProductStrategy.java b/media/java/android/media/audiopolicy/AudioProductStrategy.java
index 612f83a..60b3fc6 100644
--- a/media/java/android/media/audiopolicy/AudioProductStrategy.java
+++ b/media/java/android/media/audiopolicy/AudioProductStrategy.java
@@ -134,7 +134,9 @@
+ "DO NOT USE STREAM TO CONTROL THE VOLUME");
return AudioSystem.STREAM_MUSIC;
}
- return streamType;
+ if (streamType < AudioSystem.getNumStreamTypes()) {
+ return streamType;
+ }
}
}
return AudioSystem.STREAM_MUSIC;
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 1905571..46fb240 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -16,6 +16,7 @@
package com.android.server.media;
+import android.annotation.Nullable;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
@@ -92,6 +93,20 @@
PlaybackState.STATE_CONNECTING,
PlaybackState.STATE_PLAYING);
+ private static final AudioAttributes DEFAULT_ATTRIBUTES =
+ new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build();
+
+ private static int getVolumeStream(@Nullable AudioAttributes attr) {
+ if (attr == null) {
+ return DEFAULT_ATTRIBUTES.getVolumeControlStream();
+ }
+ final int stream = attr.getVolumeControlStream();
+ if (stream == AudioManager.USE_DEFAULT_STREAM_TYPE) {
+ return DEFAULT_ATTRIBUTES.getVolumeControlStream();
+ }
+ return stream;
+ }
+
private final MessageHandler mHandler;
private final int mOwnerPid;
@@ -162,7 +177,7 @@
mHandler = new MessageHandler(handlerLooper);
mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class);
- mAudioAttrs = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build();
+ mAudioAttrs = DEFAULT_ATTRIBUTES;
// May throw RemoteException if the session app is killed.
mSessionCb.mCb.asBinder().linkToDeath(this, 0);
@@ -262,7 +277,7 @@
}
if (mVolumeType == PlaybackInfo.PLAYBACK_TYPE_LOCAL) {
// Adjust the volume with a handler not to be blocked by other system service.
- int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs);
+ int stream = getVolumeStream(mAudioAttrs);
postAdjustLocalVolume(stream, direction, flags, opPackageName, pid, uid,
asSystemService, useSuggested, previousFlagPlaySound);
} else {
@@ -302,7 +317,7 @@
private void setVolumeTo(String packageName, String opPackageName, int pid, int uid, int value,
int flags) {
if (mVolumeType == PlaybackInfo.PLAYBACK_TYPE_LOCAL) {
- int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs);
+ int stream = getVolumeStream(mAudioAttrs);
final int volumeValue = value;
mHandler.post(new Runnable() {
@Override
@@ -720,7 +735,7 @@
volumeType = mVolumeType;
attributes = mAudioAttrs;
}
- int stream = AudioAttributes.toLegacyStreamType(attributes);
+ int stream = getVolumeStream(attributes);
int max = mAudioManager.getStreamMaxVolume(stream);
int current = mAudioManager.getStreamVolume(stream);
return new PlaybackInfo(volumeType, VolumeProvider.VOLUME_CONTROL_ABSOLUTE, max,