summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/volume/MediaSessions.kt64
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java33
3 files changed, 65 insertions, 39 deletions
diff --git a/packages/SettingsLib/src/com/android/settingslib/volume/MediaSessions.kt b/packages/SettingsLib/src/com/android/settingslib/volume/MediaSessions.kt
index 10156c404ebf..bac564c7d0f4 100644
--- a/packages/SettingsLib/src/com/android/settingslib/volume/MediaSessions.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/volume/MediaSessions.kt
@@ -20,6 +20,7 @@ import android.content.Intent
import android.content.pm.PackageManager
import android.media.MediaMetadata
import android.media.session.MediaController
+import android.media.session.MediaController.PlaybackInfo
import android.media.session.MediaSession
import android.media.session.MediaSessionManager
import android.media.session.PlaybackState
@@ -98,16 +99,22 @@ class MediaSessions(context: Context, looper: Looper, callbacks: Callbacks) {
}
/** Set volume `level` to remote media `token` */
- fun setVolume(token: MediaSession.Token, level: Int) {
+ fun setVolume(sessionId: SessionId, volumeLevel: Int) {
+ when (sessionId) {
+ is SessionId.Media -> setMediaSessionVolume(sessionId.token, volumeLevel)
+ }
+ }
+
+ private fun setMediaSessionVolume(token: MediaSession.Token, volumeLevel: Int) {
val record = mRecords[token]
if (record == null) {
Log.w(TAG, "setVolume: No record found for token $token")
return
}
if (D.BUG) {
- Log.d(TAG, "Setting level to $level")
+ Log.d(TAG, "Setting level to $volumeLevel")
}
- record.controller.setVolumeTo(level, 0)
+ record.controller.setVolumeTo(volumeLevel, 0)
}
private fun onRemoteVolumeChangedH(sessionToken: MediaSession.Token, flags: Int) {
@@ -122,7 +129,7 @@ class MediaSessions(context: Context, looper: Looper, callbacks: Callbacks) {
)
}
val token = controller.sessionToken
- mCallbacks.onRemoteVolumeChanged(token, flags)
+ mCallbacks.onRemoteVolumeChanged(SessionId.from(token), flags)
}
private fun onUpdateRemoteSessionListH(sessionToken: MediaSession.Token?) {
@@ -158,7 +165,7 @@ class MediaSessions(context: Context, looper: Looper, callbacks: Callbacks) {
controller.registerCallback(record, mHandler)
}
val record = mRecords[token]
- val remote = isRemote(playbackInfo)
+ val remote = playbackInfo.isRemote()
if (remote) {
updateRemoteH(token, record!!.name, playbackInfo)
record.sentRemote = true
@@ -172,7 +179,7 @@ class MediaSessions(context: Context, looper: Looper, callbacks: Callbacks) {
Log.d(TAG, "Removing " + record.name + " sentRemote=" + record.sentRemote)
}
if (record.sentRemote) {
- mCallbacks.onRemoteRemoved(token)
+ mCallbacks.onRemoteRemoved(SessionId.from(token))
record.sentRemote = false
}
}
@@ -213,8 +220,8 @@ class MediaSessions(context: Context, looper: Looper, callbacks: Callbacks) {
private fun updateRemoteH(
token: MediaSession.Token,
name: String?,
- pi: MediaController.PlaybackInfo,
- ) = mCallbacks.onRemoteUpdate(token, name, pi)
+ playbackInfo: PlaybackInfo,
+ ) = mCallbacks.onRemoteUpdate(SessionId.from(token), name, VolumeInfo.from(playbackInfo))
private inner class MediaControllerRecord(val controller: MediaController) :
MediaController.Callback() {
@@ -225,7 +232,7 @@ class MediaSessions(context: Context, looper: Looper, callbacks: Callbacks) {
return method + " " + controller.packageName + " "
}
- override fun onAudioInfoChanged(info: MediaController.PlaybackInfo) {
+ override fun onAudioInfoChanged(info: PlaybackInfo) {
if (D.BUG) {
Log.d(
TAG,
@@ -235,9 +242,9 @@ class MediaSessions(context: Context, looper: Looper, callbacks: Callbacks) {
sentRemote),
)
}
- val remote = isRemote(info)
+ val remote = info.isRemote()
if (!remote && sentRemote) {
- mCallbacks.onRemoteRemoved(controller.sessionToken)
+ mCallbacks.onRemoteRemoved(SessionId.from(controller.sessionToken))
sentRemote = false
} else if (remote) {
updateRemoteH(controller.sessionToken, name, info)
@@ -301,20 +308,36 @@ class MediaSessions(context: Context, looper: Looper, callbacks: Callbacks) {
}
}
+ /** Opaque id for ongoing sessions that support volume adjustment. */
+ sealed interface SessionId {
+
+ companion object {
+ fun from(token: MediaSession.Token) = Media(token)
+ }
+
+ data class Media(val token: MediaSession.Token) : SessionId
+ }
+
+ /** Holds session volume information. */
+ data class VolumeInfo(val currentVolume: Int, val maxVolume: Int) {
+
+ companion object {
+
+ fun from(playbackInfo: PlaybackInfo) =
+ VolumeInfo(playbackInfo.currentVolume, playbackInfo.maxVolume)
+ }
+ }
+
/** Callback for remote media sessions */
interface Callbacks {
/** Invoked when remote media session is updated */
- fun onRemoteUpdate(
- token: MediaSession.Token?,
- name: String?,
- pi: MediaController.PlaybackInfo?,
- )
+ fun onRemoteUpdate(token: SessionId?, name: String?, volumeInfo: VolumeInfo?)
/** Invoked when remote media session is removed */
- fun onRemoteRemoved(token: MediaSession.Token?)
+ fun onRemoteRemoved(token: SessionId?)
/** Invoked when remote volume is changed */
- fun onRemoteVolumeChanged(token: MediaSession.Token?, flags: Int)
+ fun onRemoteVolumeChanged(token: SessionId?, flags: Int)
}
companion object {
@@ -325,12 +348,11 @@ class MediaSessions(context: Context, looper: Looper, callbacks: Callbacks) {
const val UPDATE_REMOTE_SESSION_LIST: Int = 3
private const val USE_SERVICE_LABEL = false
-
- private fun isRemote(pi: MediaController.PlaybackInfo?): Boolean =
- pi != null && pi.playbackType == MediaController.PlaybackInfo.PLAYBACK_TYPE_REMOTE
}
}
+private fun PlaybackInfo?.isRemote() = this?.playbackType == PlaybackInfo.PLAYBACK_TYPE_REMOTE
+
private fun MediaController.dump(n: Int, writer: PrintWriter) {
writer.println(" Controller $n: $packageName")
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java
index 75f3386ed695..b8e19248b2de 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java
@@ -47,6 +47,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import com.android.keyguard.TestScopeProvider;
+import com.android.settingslib.volume.MediaSessions;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.SysuiTestCaseExtKt;
import com.android.systemui.broadcast.BroadcastDispatcher;
@@ -268,13 +269,15 @@ public class VolumeDialogControllerImplTest extends SysuiTestCase {
@Test
public void testOnRemoteVolumeChanged_newStream_noNullPointer() {
MediaSession.Token token = new MediaSession.Token(Process.myUid(), null);
- mVolumeController.mMediaSessionsCallbacksW.onRemoteVolumeChanged(token, 0);
+ var sessionId = MediaSessions.SessionId.Companion.from(token);
+ mVolumeController.mMediaSessionsCallbacksW.onRemoteVolumeChanged(sessionId, 0);
}
@Test
public void testOnRemoteRemove_newStream_noNullPointer() {
MediaSession.Token token = new MediaSession.Token(Process.myUid(), null);
- mVolumeController.mMediaSessionsCallbacksW.onRemoteRemoved(token);
+ var sessionId = MediaSessions.SessionId.Companion.from(token);
+ mVolumeController.mMediaSessionsCallbacksW.onRemoteRemoved(sessionId);
}
@Test
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
index 68bffeefb0f0..4d5477052388 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
@@ -37,8 +37,6 @@ import android.media.IAudioService;
import android.media.IVolumeController;
import android.media.MediaRouter2Manager;
import android.media.VolumePolicy;
-import android.media.session.MediaController.PlaybackInfo;
-import android.media.session.MediaSession.Token;
import android.net.Uri;
import android.os.Handler;
import android.os.HandlerExecutor;
@@ -61,6 +59,7 @@ import androidx.lifecycle.Observer;
import com.android.internal.annotations.GuardedBy;
import com.android.settingslib.volume.MediaSessions;
+import com.android.settingslib.volume.MediaSessions.SessionId;
import com.android.systemui.Dumpable;
import com.android.systemui.Flags;
import com.android.systemui.broadcast.BroadcastDispatcher;
@@ -1402,12 +1401,13 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
}
protected final class MediaSessionsCallbacks implements MediaSessions.Callbacks {
- private final HashMap<Token, Integer> mRemoteStreams = new HashMap<>();
+ private final HashMap<SessionId, Integer> mRemoteStreams = new HashMap<>();
private int mNextStream = DYNAMIC_STREAM_REMOTE_START_INDEX;
@Override
- public void onRemoteUpdate(Token token, String name, PlaybackInfo pi) {
+ public void onRemoteUpdate(
+ SessionId token, String name, MediaSessions.VolumeInfo volumeInfo) {
addStream(token, "onRemoteUpdate");
int stream = 0;
@@ -1415,14 +1415,15 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
stream = mRemoteStreams.get(token);
}
Slog.d(TAG,
- "onRemoteUpdate: stream: " + stream + " volume: " + pi.getCurrentVolume());
+ "onRemoteUpdate: stream: "
+ + stream + " volume: " + volumeInfo.getCurrentVolume());
boolean changed = mState.states.indexOfKey(stream) < 0;
final StreamState ss = streamStateW(stream);
ss.dynamic = true;
ss.levelMin = 0;
- ss.levelMax = pi.getMaxVolume();
- if (ss.level != pi.getCurrentVolume()) {
- ss.level = pi.getCurrentVolume();
+ ss.levelMax = volumeInfo.getMaxVolume();
+ if (ss.level != volumeInfo.getCurrentVolume()) {
+ ss.level = volumeInfo.getCurrentVolume();
changed = true;
}
if (!Objects.equals(ss.remoteLabel, name)) {
@@ -1437,11 +1438,11 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
}
@Override
- public void onRemoteVolumeChanged(Token token, int flags) {
- addStream(token, "onRemoteVolumeChanged");
+ public void onRemoteVolumeChanged(SessionId sessionId, int flags) {
+ addStream(sessionId, "onRemoteVolumeChanged");
int stream = 0;
synchronized (mRemoteStreams) {
- stream = mRemoteStreams.get(token);
+ stream = mRemoteStreams.get(sessionId);
}
final boolean showUI = shouldShowUI(flags);
Slog.d(TAG, "onRemoteVolumeChanged: stream: " + stream + " showui? " + showUI);
@@ -1459,7 +1460,7 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
}
@Override
- public void onRemoteRemoved(Token token) {
+ public void onRemoteRemoved(SessionId token) {
int stream;
synchronized (mRemoteStreams) {
if (!mRemoteStreams.containsKey(token)) {
@@ -1480,7 +1481,7 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
}
public void setStreamVolume(int stream, int level) {
- final Token token = findToken(stream);
+ final SessionId token = findToken(stream);
if (token == null) {
Log.w(TAG, "setStreamVolume: No token found for stream: " + stream);
return;
@@ -1488,9 +1489,9 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
mMediaSessions.setVolume(token, level);
}
- private Token findToken(int stream) {
+ private SessionId findToken(int stream) {
synchronized (mRemoteStreams) {
- for (Map.Entry<Token, Integer> entry : mRemoteStreams.entrySet()) {
+ for (Map.Entry<SessionId, Integer> entry : mRemoteStreams.entrySet()) {
if (entry.getValue().equals(stream)) {
return entry.getKey();
}
@@ -1499,7 +1500,7 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
return null;
}
- private void addStream(Token token, String triggeringMethod) {
+ private void addStream(SessionId token, String triggeringMethod) {
synchronized (mRemoteStreams) {
if (!mRemoteStreams.containsKey(token)) {
mRemoteStreams.put(token, mNextStream);