MediaController: Add missing event flags (2/2)

This is the follow-up commit where the onEvents callback
raised by MediaController contains the missing events, for the
case where MediaController is connected to a legacy MediaSession.

#minor-release

PiperOrigin-RevId: 487231996
This commit is contained in:
christosts 2022-11-09 14:58:49 +00:00 committed by microkatz
parent 95f37b4df8
commit c403b4ce7c
2 changed files with 170 additions and 8 deletions

View File

@ -1435,9 +1435,8 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED)); Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED));
} }
if (!Util.areEqual(oldLegacyPlayerInfo.queueTitle, newLegacyPlayerInfo.queueTitle)) { if (!Util.areEqual(oldLegacyPlayerInfo.queueTitle, newLegacyPlayerInfo.queueTitle)) {
// TODO(b/187152483): Set proper event code when available.
listeners.queueEvent( listeners.queueEvent(
C.INDEX_UNSET, Player.EVENT_PLAYLIST_METADATA_CHANGED,
(listener) -> (listener) ->
listener.onPlaylistMetadataChanged(newControllerInfo.playerInfo.playlistMetadata)); listener.onPlaylistMetadataChanged(newControllerInfo.playerInfo.playlistMetadata));
} }
@ -1515,23 +1514,20 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
} }
if (!oldControllerInfo.playerInfo.audioAttributes.equals( if (!oldControllerInfo.playerInfo.audioAttributes.equals(
newControllerInfo.playerInfo.audioAttributes)) { newControllerInfo.playerInfo.audioAttributes)) {
// TODO(b/187152483): Set proper event code when available.
listeners.queueEvent( listeners.queueEvent(
C.INDEX_UNSET, Player.EVENT_AUDIO_ATTRIBUTES_CHANGED,
(listener) -> (listener) ->
listener.onAudioAttributesChanged(newControllerInfo.playerInfo.audioAttributes)); listener.onAudioAttributesChanged(newControllerInfo.playerInfo.audioAttributes));
} }
if (!oldControllerInfo.playerInfo.deviceInfo.equals(newControllerInfo.playerInfo.deviceInfo)) { if (!oldControllerInfo.playerInfo.deviceInfo.equals(newControllerInfo.playerInfo.deviceInfo)) {
// TODO(b/187152483): Set proper event code when available.
listeners.queueEvent( listeners.queueEvent(
C.INDEX_UNSET, Player.EVENT_DEVICE_INFO_CHANGED,
(listener) -> listener.onDeviceInfoChanged(newControllerInfo.playerInfo.deviceInfo)); (listener) -> listener.onDeviceInfoChanged(newControllerInfo.playerInfo.deviceInfo));
} }
if (oldControllerInfo.playerInfo.deviceVolume != newControllerInfo.playerInfo.deviceVolume if (oldControllerInfo.playerInfo.deviceVolume != newControllerInfo.playerInfo.deviceVolume
|| oldControllerInfo.playerInfo.deviceMuted != newControllerInfo.playerInfo.deviceMuted) { || oldControllerInfo.playerInfo.deviceMuted != newControllerInfo.playerInfo.deviceMuted) {
// TODO(b/187152483): Set proper event code when available.
listeners.queueEvent( listeners.queueEvent(
C.INDEX_UNSET, Player.EVENT_DEVICE_VOLUME_CHANGED,
(listener) -> (listener) ->
listener.onDeviceVolumeChanged( listener.onDeviceVolumeChanged(
newControllerInfo.playerInfo.deviceVolume, newControllerInfo.playerInfo.deviceVolume,

View File

@ -16,17 +16,25 @@
package androidx.media3.session; package androidx.media3.session;
import static androidx.media3.test.session.common.TestUtils.TIMEOUT_MS; import static androidx.media3.test.session.common.TestUtils.TIMEOUT_MS;
import static androidx.media3.test.session.common.TestUtils.getEventsAsList;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.junit.Assume.assumeTrue;
import android.content.Context; import android.content.Context;
import android.media.AudioManager;
import android.os.Bundle; import android.os.Bundle;
import android.os.RemoteException; import android.os.RemoteException;
import android.support.v4.media.session.MediaSessionCompat; import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat; import android.support.v4.media.session.PlaybackStateCompat;
import androidx.media.VolumeProviderCompat;
import androidx.media3.common.AudioAttributes;
import androidx.media3.common.C; import androidx.media3.common.C;
import androidx.media3.common.DeviceInfo;
import androidx.media3.common.FlagSet; import androidx.media3.common.FlagSet;
import androidx.media3.common.MediaMetadata;
import androidx.media3.common.Player; import androidx.media3.common.Player;
import androidx.media3.common.util.Util;
import androidx.media3.test.session.common.CommonConstants; import androidx.media3.test.session.common.CommonConstants;
import androidx.media3.test.session.common.HandlerThreadTestRule; import androidx.media3.test.session.common.HandlerThreadTestRule;
import androidx.media3.test.session.common.MainLooperTestRule; import androidx.media3.test.session.common.MainLooperTestRule;
@ -40,6 +48,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
@ -190,4 +199,161 @@ public class MediaControllerListenerWithMediaSessionCompatTest {
assertThat(countDownLatch.await(1_000, MILLISECONDS)).isTrue(); assertThat(countDownLatch.await(1_000, MILLISECONDS)).isTrue();
assertThat(TestUtils.equals(receivedSessionExtras.get(0), sessionExtras)).isTrue(); assertThat(TestUtils.equals(receivedSessionExtras.get(0), sessionExtras)).isTrue();
} }
@Test
public void onPlaylistMetadataChanged() throws Exception {
MediaController controller = controllerTestRule.createController(session.getSessionToken());
CountDownLatch latch = new CountDownLatch(2);
AtomicReference<MediaMetadata> playlistMetadataParamRef = new AtomicReference<>();
AtomicReference<MediaMetadata> playlistMetadataGetterRef = new AtomicReference<>();
AtomicReference<MediaMetadata> playlistMetadataOnEventsRef = new AtomicReference<>();
AtomicReference<Player.Events> onEvents = new AtomicReference<>();
Player.Listener listener =
new Player.Listener() {
@Override
public void onPlaylistMetadataChanged(MediaMetadata mediaMetadata) {
playlistMetadataParamRef.set(mediaMetadata);
playlistMetadataGetterRef.set(controller.getPlaylistMetadata());
latch.countDown();
}
@Override
public void onEvents(Player player, Player.Events events) {
onEvents.set(events);
playlistMetadataOnEventsRef.set(player.getPlaylistMetadata());
latch.countDown();
}
};
threadTestRule.getHandler().postAndSync(() -> controller.addListener(listener));
session.setQueueTitle("queue-title");
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
assertThat(playlistMetadataParamRef.get().title).isEqualTo("queue-title");
assertThat(playlistMetadataGetterRef.get()).isEqualTo(playlistMetadataParamRef.get());
assertThat(playlistMetadataOnEventsRef.get()).isEqualTo(playlistMetadataParamRef.get());
assertThat(getEventsAsList(onEvents.get()))
.containsExactly(Player.EVENT_PLAYLIST_METADATA_CHANGED);
}
@Test
public void onAudioAttributesChanged() throws Exception {
// We need to trigger MediaControllerCompat.Callback.onAudioInfoChanged in order to raise the
// onAudioAttributesChanged() callback. In API 21 and 22, onAudioInfoChanged is not called when
// playback is changed to local.
assumeTrue(Util.SDK_INT != 21 && Util.SDK_INT != 22);
session.setPlaybackToRemote(
/* volumeControl= */ VolumeProviderCompat.VOLUME_CONTROL_ABSOLUTE,
/* maxVolume= */ 100,
/* currentVolume= */ 50);
MediaController controller = controllerTestRule.createController(session.getSessionToken());
CountDownLatch latch = new CountDownLatch(2);
AtomicReference<AudioAttributes> audioAttributesParamRef = new AtomicReference<>();
AtomicReference<AudioAttributes> audioAttributesGetterRef = new AtomicReference<>();
AtomicReference<AudioAttributes> audioAttributesOnEventsRef = new AtomicReference<>();
AtomicReference<Player.Events> onEvents = new AtomicReference<>();
Player.Listener listener =
new Player.Listener() {
@Override
public void onAudioAttributesChanged(AudioAttributes audioAttributes) {
audioAttributesParamRef.set(audioAttributes);
audioAttributesGetterRef.set(controller.getAudioAttributes());
latch.countDown();
}
@Override
public void onEvents(Player player, Player.Events events) {
onEvents.set(events);
audioAttributesOnEventsRef.set(player.getAudioAttributes());
latch.countDown();
}
};
threadTestRule.getHandler().postAndSync(() -> controller.addListener(listener));
session.setPlaybackToLocal(AudioManager.STREAM_ALARM);
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
assertThat(audioAttributesGetterRef.get().contentType).isEqualTo(AudioManager.STREAM_ALARM);
assertThat(audioAttributesGetterRef.get()).isEqualTo(audioAttributesParamRef.get());
assertThat(audioAttributesOnEventsRef.get()).isEqualTo(audioAttributesParamRef.get());
assertThat(getEventsAsList(onEvents.get())).contains(Player.EVENT_AUDIO_ATTRIBUTES_CHANGED);
}
@Test
public void onDeviceInfoChanged() throws Exception {
MediaController controller = controllerTestRule.createController(session.getSessionToken());
CountDownLatch latch = new CountDownLatch(2);
AtomicReference<DeviceInfo> deviceInfoParamRef = new AtomicReference<>();
AtomicReference<DeviceInfo> deviceInfoGetterRef = new AtomicReference<>();
AtomicReference<DeviceInfo> deviceInfoOnEventsRef = new AtomicReference<>();
AtomicReference<Player.Events> onEvents = new AtomicReference<>();
Player.Listener listener =
new Player.Listener() {
@Override
public void onDeviceInfoChanged(DeviceInfo deviceInfo) {
deviceInfoParamRef.set(deviceInfo);
deviceInfoGetterRef.set(controller.getDeviceInfo());
latch.countDown();
}
@Override
public void onEvents(Player player, Player.Events events) {
deviceInfoOnEventsRef.set(player.getDeviceInfo());
onEvents.set(events);
latch.countDown();
}
};
threadTestRule.getHandler().postAndSync(() -> controller.addListener(listener));
session.setPlaybackToRemote(
/* volumeControl= */ VolumeProviderCompat.VOLUME_CONTROL_ABSOLUTE,
/* maxVolume= */ 100,
/* currentVolume= */ 50);
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
assertThat(deviceInfoParamRef.get().playbackType).isEqualTo(DeviceInfo.PLAYBACK_TYPE_REMOTE);
assertThat(deviceInfoParamRef.get().maxVolume).isEqualTo(100);
assertThat(deviceInfoGetterRef.get()).isEqualTo(deviceInfoParamRef.get());
assertThat(deviceInfoOnEventsRef.get()).isEqualTo(deviceInfoGetterRef.get());
assertThat(getEventsAsList(onEvents.get())).contains(Player.EVENT_DEVICE_VOLUME_CHANGED);
}
@Test
public void onDeviceVolumeChanged() throws Exception {
MediaController controller = controllerTestRule.createController(session.getSessionToken());
CountDownLatch latch = new CountDownLatch(2);
AtomicInteger deviceVolumeParam = new AtomicInteger();
AtomicInteger deviceVolumeGetter = new AtomicInteger();
AtomicInteger deviceVolumeOnEvents = new AtomicInteger();
AtomicReference<Player.Events> onEvents = new AtomicReference<>();
Player.Listener listener =
new Player.Listener() {
@Override
public void onDeviceVolumeChanged(int volume, boolean muted) {
deviceVolumeParam.set(volume);
deviceVolumeGetter.set(controller.getDeviceVolume());
latch.countDown();
}
@Override
public void onEvents(Player player, Player.Events events) {
deviceVolumeOnEvents.set(player.getDeviceVolume());
onEvents.set(events);
latch.countDown();
}
};
threadTestRule.getHandler().postAndSync(() -> controller.addListener(listener));
session.setPlaybackToRemote(
/* volumeControl= */ VolumeProviderCompat.VOLUME_CONTROL_ABSOLUTE,
/* maxVolume= */ 100,
/* currentVolume= */ 50);
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
assertThat(deviceVolumeParam.get()).isEqualTo(50);
assertThat(deviceVolumeGetter.get()).isEqualTo(50);
assertThat(deviceVolumeOnEvents.get()).isEqualTo(50);
assertThat(getEventsAsList(onEvents.get())).contains(Player.EVENT_DEVICE_VOLUME_CHANGED);
}
} }