Enable MediaSession2Test.testSetPlayer_playbackInfo
Bug: 77241129
Test: ./gradlew media:check media:connectedCheck
Change-Id: I0c37bdbf8b61f6bd36f753dce6093f7ec71cd2df
diff --git a/media/src/androidTest/java/androidx/media/MediaSession2Test.java b/media/src/androidTest/java/androidx/media/MediaSession2Test.java
index 39764c6..d738c9f 100644
--- a/media/src/androidTest/java/androidx/media/MediaSession2Test.java
+++ b/media/src/androidTest/java/androidx/media/MediaSession2Test.java
@@ -18,6 +18,9 @@
import static android.media.AudioAttributes.CONTENT_TYPE_MUSIC;
+import static androidx.media.VolumeProviderCompat.VOLUME_CONTROL_ABSOLUTE;
+import static androidx.media.VolumeProviderCompat.VOLUME_CONTROL_FIXED;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
@@ -283,7 +286,6 @@
assertTrue(latch.await(WAIT_TIME_MS, TimeUnit.MILLISECONDS));
}
- @Ignore
@Test
public void testSetPlayer_playbackInfo() throws Exception {
prepareLooper();
@@ -295,10 +297,9 @@
final int maxVolume = 100;
final int currentVolume = 23;
- final int volumeControlType = VolumeProviderCompat.VOLUME_CONTROL_ABSOLUTE;
- VolumeProviderCompat volumeProvider =
- new VolumeProviderCompat(volumeControlType, maxVolume, currentVolume) {
- };
+ final int volumeControlType = VOLUME_CONTROL_ABSOLUTE;
+ VolumeProviderCompat volumeProvider = new VolumeProviderCompat(
+ volumeControlType, maxVolume, currentVolume) { };
final CountDownLatch latch = new CountDownLatch(1);
final ControllerCallback callback = new ControllerCallback() {
@@ -321,9 +322,11 @@
assertEquals(PlaybackInfo.PLAYBACK_TYPE_LOCAL, info.getPlaybackType());
assertEquals(attrs, info.getAudioAttributes());
AudioManager manager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
- int localVolumeControlType = manager.isVolumeFixed()
- ? VolumeProviderCompat.VOLUME_CONTROL_FIXED
- : VolumeProviderCompat.VOLUME_CONTROL_ABSOLUTE;
+
+ int localVolumeControlType = VOLUME_CONTROL_ABSOLUTE;
+ if (Build.VERSION.SDK_INT >= 21 && manager.isVolumeFixed()) {
+ localVolumeControlType = VOLUME_CONTROL_FIXED;
+ }
assertEquals(localVolumeControlType, info.getControlType());
assertEquals(manager.getStreamMaxVolume(AudioManager.STREAM_MUSIC), info.getMaxVolume());
assertEquals(manager.getStreamVolume(AudioManager.STREAM_MUSIC), info.getCurrentVolume());
diff --git a/media/src/main/java/androidx/media/MediaConstants2.java b/media/src/main/java/androidx/media/MediaConstants2.java
index 652776b..5de31c0 100644
--- a/media/src/main/java/androidx/media/MediaConstants2.java
+++ b/media/src/main/java/androidx/media/MediaConstants2.java
@@ -27,6 +27,8 @@
static final String SESSION_EVENT_ON_ERROR = "androidx.media.session.event.ON_ERROR";
static final String SESSION_EVENT_ON_ROUTES_INFO_CHANGED =
"androidx.media.session.event.ON_ROUTES_INFO_CHANGED";
+ static final String SESSION_EVENT_ON_PLAYBACK_INFO_CHANGED =
+ "androidx.media.session.event.ON_PLAYBACK_INFO_CHANGED";
static final String SESSION_EVENT_ON_REPEAT_MODE_CHANGED =
"androidx.media.session.event.ON_REPEAT_MODE_CHANGED";
static final String SESSION_EVENT_ON_SHUFFLE_MODE_CHANGED =
@@ -78,6 +80,7 @@
static final String ARGUMENT_RESULT_RECEIVER = "androidx.media.argument.RESULT_RECEIVER";
static final String ARGUMENT_COMMAND_BUTTONS = "androidx.media.argument.COMMAND_BUTTONS";
static final String ARGUMENT_ROUTE_BUNDLE = "androidx.media.argument.ROUTE_BUNDLE";
+ static final String ARGUMENT_PLAYBACK_INFO = "androidx.media.argument.PLAYBACK_INFO";
static final String ARGUMENT_ICONTROLLER_CALLBACK =
"androidx.media.argument.ICONTROLLER_CALLBACK";
diff --git a/media/src/main/java/androidx/media/MediaController2.java b/media/src/main/java/androidx/media/MediaController2.java
index 9822712..40c23ce 100644
--- a/media/src/main/java/androidx/media/MediaController2.java
+++ b/media/src/main/java/androidx/media/MediaController2.java
@@ -31,6 +31,7 @@
import static androidx.media.MediaConstants2.ARGUMENT_MEDIA_ITEM;
import static androidx.media.MediaConstants2.ARGUMENT_PACKAGE_NAME;
import static androidx.media.MediaConstants2.ARGUMENT_PID;
+import static androidx.media.MediaConstants2.ARGUMENT_PLAYBACK_INFO;
import static androidx.media.MediaConstants2.ARGUMENT_PLAYBACK_STATE_COMPAT;
import static androidx.media.MediaConstants2.ARGUMENT_PLAYER_STATE;
import static androidx.media.MediaConstants2.ARGUMENT_PLAYLIST;
@@ -56,6 +57,7 @@
import static androidx.media.MediaConstants2.CONTROLLER_COMMAND_DISCONNECT;
import static androidx.media.MediaConstants2.SESSION_EVENT_ON_ALLOWED_COMMANDS_CHANGED;
import static androidx.media.MediaConstants2.SESSION_EVENT_ON_ERROR;
+import static androidx.media.MediaConstants2.SESSION_EVENT_ON_PLAYBACK_INFO_CHANGED;
import static androidx.media.MediaConstants2.SESSION_EVENT_ON_PLAYER_STATE_CHANGED;
import static androidx.media.MediaConstants2.SESSION_EVENT_ON_PLAYLIST_CHANGED;
import static androidx.media.MediaConstants2.SESSION_EVENT_ON_PLAYLIST_METADATA_CHANGED;
@@ -378,8 +380,7 @@
PlaybackInfo(int playbackType, AudioAttributesCompat attrs, int controlType, int max,
int current) {
mPlaybackType = playbackType;
- // TODO: Use AudioAttributesCompat instead of AudioAttributes, and set the value
- mAudioAttrsCompat = null;
+ mAudioAttrsCompat = attrs;
mControlType = controlType;
mMaxVolume = max;
mCurrentVolume = current;
@@ -448,8 +449,10 @@
bundle.putInt(KEY_CONTROL_TYPE, mControlType);
bundle.putInt(KEY_MAX_VOLUME, mMaxVolume);
bundle.putInt(KEY_CURRENT_VOLUME, mCurrentVolume);
- bundle.putParcelable(KEY_AUDIO_ATTRIBUTES,
- MediaUtils2.toAudioAttributesBundle(mAudioAttrsCompat));
+ if (mAudioAttrsCompat != null) {
+ bundle.putParcelable(KEY_AUDIO_ATTRIBUTES,
+ MediaUtils2.toAudioAttributesBundle(mAudioAttrsCompat));
+ }
return bundle;
}
@@ -468,7 +471,6 @@
final int currentVolume = bundle.getInt(KEY_CURRENT_VOLUME);
final AudioAttributesCompat attrs = MediaUtils2.fromAudioAttributesBundle(
bundle.getBundle(KEY_AUDIO_ATTRIBUTES));
-
return createPlaybackInfo(volumeType, attrs, volumeControl, maxVolume,
currentVolume);
}
@@ -605,6 +607,17 @@
mCallback.onCustomLayoutChanged(MediaController2.this, layout);
break;
}
+ case SESSION_EVENT_ON_PLAYBACK_INFO_CHANGED: {
+ PlaybackInfo info = PlaybackInfo.fromBundle(
+ extras.getBundle(ARGUMENT_PLAYBACK_INFO));
+ if (info == null) {
+ return;
+ }
+ synchronized (mLock) {
+ mPlaybackInfo = info;
+ }
+ mCallback.onPlaybackInfoChanged(MediaController2.this, info);
+ }
}
}
}
@@ -1504,6 +1517,8 @@
// TODO: Set mMediaMetadataCompat from the data.
final List<MediaItem2> playlist = MediaUtils2.fromMediaItem2ParcelableArray(
data.getParcelableArray(ARGUMENT_PLAYLIST));
+ final PlaybackInfo playbackInfo =
+ PlaybackInfo.fromBundle(data.getBundle(ARGUMENT_PLAYBACK_INFO));
if (DEBUG) {
Log.d(TAG, "onConnectedNotLocked sessionCompatToken=" + mToken.getSessionCompatToken()
+ ", allowedCommands=" + allowedCommands);
@@ -1527,6 +1542,7 @@
mShuffleMode = shuffleMode;
mPlaylist = playlist;
mConnected = true;
+ mPlaybackInfo = playbackInfo;
}
// TODO(jaewan): Keep commands to prevents illegal API calls.
mCallbackExecutor.execute(new Runnable() {
diff --git a/media/src/main/java/androidx/media/MediaSession2.java b/media/src/main/java/androidx/media/MediaSession2.java
index 0093991..2ecb7ce 100644
--- a/media/src/main/java/androidx/media/MediaSession2.java
+++ b/media/src/main/java/androidx/media/MediaSession2.java
@@ -35,6 +35,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
+import androidx.media.MediaController2.PlaybackInfo;
import androidx.media.MediaPlayerBase.BuffState;
import androidx.media.MediaPlayerBase.PlayerState;
import androidx.media.MediaPlaylistAgent.PlaylistEventCallback;
@@ -1086,6 +1087,7 @@
abstract SessionCallback getCallback();
abstract boolean isClosed();
abstract PlaybackStateCompat getPlaybackStateCompat();
+ abstract PlaybackInfo getPlaybackInfo();
}
static final String TAG = "MediaSession2";
diff --git a/media/src/main/java/androidx/media/MediaSession2ImplBase.java b/media/src/main/java/androidx/media/MediaSession2ImplBase.java
index eb23de3..ccba2fc 100644
--- a/media/src/main/java/androidx/media/MediaSession2ImplBase.java
+++ b/media/src/main/java/androidx/media/MediaSession2ImplBase.java
@@ -47,6 +47,7 @@
import androidx.annotation.GuardedBy;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.media.MediaController2.PlaybackInfo;
import androidx.media.MediaPlayerBase.PlayerEventCallback;
import androidx.media.MediaPlaylistAgent.PlaylistEventCallback;
@@ -90,6 +91,8 @@
private OnDataSourceMissingHelper mDsmHelper;
@GuardedBy("mLock")
private PlaybackStateCompat mPlaybackStateCompat;
+ @GuardedBy("mLock")
+ private PlaybackInfo mPlaybackInfo;
MediaSession2ImplBase(Context context, MediaSessionCompat sessionCompat, String id,
MediaPlayerBase player, MediaPlaylistAgent playlistAgent,
@@ -142,6 +145,7 @@
}
final MediaPlayerBase oldPlayer;
final MediaPlaylistAgent oldAgent;
+ final PlaybackInfo info = createPlaybackInfo(volumeProvider, player.getAudioAttributes());
synchronized (mLock) {
oldPlayer = mPlayer;
oldAgent = mPlaylistAgent;
@@ -155,6 +159,7 @@
}
mPlaylistAgent = playlistAgent;
mVolumeProvider = volumeProvider;
+ mPlaybackInfo = info;
}
if (player != oldPlayer) {
player.registerPlayerEventCallback(mCallbackExecutor, mPlayerEventCallback);
@@ -172,13 +177,50 @@
}
if (oldPlayer != null) {
- // TODO: implement
- //mSession2Stub.notifyVolumeControlInfoChanged();
+ mSession2Stub.notifyPlaybackInfoChanged(info);
notifyPlayerUpdatedNotLocked(oldPlayer);
}
// TODO(jaewan): Repeat the same thing for the playlist agent.
}
+ private PlaybackInfo createPlaybackInfo(VolumeProviderCompat volumeProvider,
+ AudioAttributesCompat attrs) {
+ PlaybackInfo info;
+ if (volumeProvider == null) {
+ int stream;
+ if (attrs == null) {
+ stream = AudioManager.STREAM_MUSIC;
+ } else {
+ stream = attrs.getVolumeControlStream();
+ if (stream == AudioManager.USE_DEFAULT_STREAM_TYPE) {
+ // It may happen if the AudioAttributes doesn't have usage.
+ // Change it to the STREAM_MUSIC because it's not supported by audio manager
+ // for querying volume level.
+ stream = AudioManager.STREAM_MUSIC;
+ }
+ }
+
+ int controlType = VolumeProviderCompat.VOLUME_CONTROL_ABSOLUTE;
+ if (Build.VERSION.SDK_INT >= 21 && mAudioManager.isVolumeFixed()) {
+ controlType = VolumeProviderCompat.VOLUME_CONTROL_FIXED;
+ }
+ info = PlaybackInfo.createPlaybackInfo(
+ PlaybackInfo.PLAYBACK_TYPE_LOCAL,
+ attrs,
+ controlType,
+ mAudioManager.getStreamMaxVolume(stream),
+ mAudioManager.getStreamVolume(stream));
+ } else {
+ info = PlaybackInfo.createPlaybackInfo(
+ PlaybackInfo.PLAYBACK_TYPE_REMOTE,
+ attrs,
+ volumeProvider.getVolumeControl(),
+ volumeProvider.getMaxVolume(),
+ volumeProvider.getCurrentVolume());
+ }
+ return info;
+ }
+
@Override
public void close() {
synchronized (mLock) {
@@ -760,6 +802,13 @@
}
}
+ @Override
+ PlaybackInfo getPlaybackInfo() {
+ synchronized (mLock) {
+ return mPlaybackInfo;
+ }
+ }
+
MediaSession2StubImplBase getSession2Stub() {
return mSession2Stub;
}
diff --git a/media/src/main/java/androidx/media/MediaSession2StubImplBase.java b/media/src/main/java/androidx/media/MediaSession2StubImplBase.java
index b203255..1e3d3f3 100644
--- a/media/src/main/java/androidx/media/MediaSession2StubImplBase.java
+++ b/media/src/main/java/androidx/media/MediaSession2StubImplBase.java
@@ -28,6 +28,7 @@
import static androidx.media.MediaConstants2.ARGUMENT_MEDIA_ITEM;
import static androidx.media.MediaConstants2.ARGUMENT_PACKAGE_NAME;
import static androidx.media.MediaConstants2.ARGUMENT_PID;
+import static androidx.media.MediaConstants2.ARGUMENT_PLAYBACK_INFO;
import static androidx.media.MediaConstants2.ARGUMENT_PLAYBACK_STATE_COMPAT;
import static androidx.media.MediaConstants2.ARGUMENT_PLAYER_STATE;
import static androidx.media.MediaConstants2.ARGUMENT_PLAYLIST;
@@ -53,6 +54,7 @@
import static androidx.media.MediaConstants2.CONTROLLER_COMMAND_DISCONNECT;
import static androidx.media.MediaConstants2.SESSION_EVENT_ON_ALLOWED_COMMANDS_CHANGED;
import static androidx.media.MediaConstants2.SESSION_EVENT_ON_ERROR;
+import static androidx.media.MediaConstants2.SESSION_EVENT_ON_PLAYBACK_INFO_CHANGED;
import static androidx.media.MediaConstants2.SESSION_EVENT_ON_PLAYER_STATE_CHANGED;
import static androidx.media.MediaConstants2.SESSION_EVENT_ON_PLAYLIST_CHANGED;
import static androidx.media.MediaConstants2.SESSION_EVENT_ON_PLAYLIST_METADATA_CHANGED;
@@ -109,6 +111,7 @@
import androidx.annotation.GuardedBy;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.media.MediaController2.PlaybackInfo;
import androidx.media.MediaSession2.CommandButton;
import androidx.media.MediaSession2.ControllerInfo;
@@ -514,6 +517,18 @@
});
}
+ void notifyPlaybackInfoChanged(final PlaybackInfo info) {
+ notifyAll(new Session2Runnable() {
+ @Override
+ public void run(ControllerInfo controller) throws RemoteException {
+ Bundle bundle = new Bundle();
+ bundle.putBundle(ARGUMENT_PLAYBACK_INFO, info.toBundle());
+ controller.getControllerBinder().onEvent(
+ SESSION_EVENT_ON_PLAYBACK_INFO_CHANGED, bundle);
+ }
+ });
+ }
+
void notifyPlayerStateChanged(final int state) {
notifyAll(new Session2Runnable() {
@Override
@@ -813,6 +828,8 @@
resultData.putParcelableArray(ARGUMENT_PLAYLIST,
MediaUtils2.toMediaItem2ParcelableArray(playlist));
}
+ resultData.putBundle(ARGUMENT_PLAYBACK_INFO,
+ mSession.getPlaybackInfo().toBundle());
// Double check if session is still there, because close() can be
// called in another thread.
diff --git a/media/src/main/java/androidx/media/MediaUtils2.java b/media/src/main/java/androidx/media/MediaUtils2.java
index 1707f9c..e1149bd 100644
--- a/media/src/main/java/androidx/media/MediaUtils2.java
+++ b/media/src/main/java/androidx/media/MediaUtils2.java
@@ -16,6 +16,8 @@
package androidx.media;
+import static androidx.media.AudioAttributesCompat.CONTENT_TYPE_UNKNOWN;
+import static androidx.media.AudioAttributesCompat.USAGE_UNKNOWN;
import static androidx.media.MediaMetadata2.METADATA_KEY_DISPLAY_DESCRIPTION;
import static androidx.media.MediaMetadata2.METADATA_KEY_DISPLAY_ICON;
import static androidx.media.MediaMetadata2.METADATA_KEY_DISPLAY_ICON_URI;
@@ -286,12 +288,6 @@
}
}
- static MediaController2.PlaybackInfo createPlaybackInfo(int playbackType,
- AudioAttributesCompat attrs, VolumeProviderCompat vp) {
- return new MediaController2.PlaybackInfo(playbackType, attrs, vp.getVolumeControl(),
- vp.getMaxVolume(), vp.getCurrentVolume());
- }
-
static Parcelable[] toMediaItem2ParcelableArray(List<MediaItem2> playlist) {
if (playlist == null) {
return null;
@@ -356,6 +352,9 @@
}
static Bundle toAudioAttributesBundle(AudioAttributesCompat attrs) {
+ if (attrs == null) {
+ return null;
+ }
Bundle bundle = new Bundle();
bundle.putInt(AUDIO_ATTRIBUTES_USAGE, attrs.getUsage());
bundle.putInt(AUDIO_ATTRIBUTES_CONTENT_TYPE, attrs.getContentType());
@@ -364,10 +363,13 @@
}
static AudioAttributesCompat fromAudioAttributesBundle(Bundle bundle) {
+ if (bundle == null) {
+ return null;
+ }
return new AudioAttributesCompat.Builder()
- .setUsage(bundle.getInt(AUDIO_ATTRIBUTES_USAGE))
- .setContentType(bundle.getInt(AUDIO_ATTRIBUTES_CONTENT_TYPE))
- .setFlags(bundle.getInt(AUDIO_ATTRIBUTES_FLAGS))
+ .setUsage(bundle.getInt(AUDIO_ATTRIBUTES_USAGE, USAGE_UNKNOWN))
+ .setContentType(bundle.getInt(AUDIO_ATTRIBUTES_CONTENT_TYPE, CONTENT_TYPE_UNKNOWN))
+ .setFlags(bundle.getInt(AUDIO_ATTRIBUTES_FLAGS, 0))
.build();
}