mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Add suitable output checker tests relevant for API 35+ in media3-ui
PiperOrigin-RevId: 675678257
This commit is contained in:
parent
acb8e71c6e
commit
087e75850e
@ -37,7 +37,9 @@ import androidx.media3.common.FlagSet;
|
|||||||
import androidx.media3.common.MediaItem;
|
import androidx.media3.common.MediaItem;
|
||||||
import androidx.media3.common.Player;
|
import androidx.media3.common.Player;
|
||||||
import androidx.media3.common.Player.PlayWhenReadyChangeReason;
|
import androidx.media3.common.Player.PlayWhenReadyChangeReason;
|
||||||
|
import androidx.media3.common.util.Util;
|
||||||
import androidx.media3.test.utils.FakeClock;
|
import androidx.media3.test.utils.FakeClock;
|
||||||
|
import androidx.media3.test.utils.FakeSuitableOutputChecker;
|
||||||
import androidx.media3.test.utils.TestExoPlayerBuilder;
|
import androidx.media3.test.utils.TestExoPlayerBuilder;
|
||||||
import androidx.test.core.app.ApplicationProvider;
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
@ -51,6 +53,7 @@ import org.junit.After;
|
|||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.robolectric.annotation.Config;
|
||||||
import org.robolectric.shadows.AudioDeviceInfoBuilder;
|
import org.robolectric.shadows.AudioDeviceInfoBuilder;
|
||||||
import org.robolectric.shadows.ShadowApplication;
|
import org.robolectric.shadows.ShadowApplication;
|
||||||
import org.robolectric.shadows.ShadowAudioManager;
|
import org.robolectric.shadows.ShadowAudioManager;
|
||||||
@ -74,13 +77,23 @@ public class WearUnsuitableOutputPlaybackSuppressionResolverListenerTest {
|
|||||||
private ShadowPackageManager shadowPackageManager;
|
private ShadowPackageManager shadowPackageManager;
|
||||||
private ShadowApplication shadowApplication;
|
private ShadowApplication shadowApplication;
|
||||||
private Player testPlayer;
|
private Player testPlayer;
|
||||||
|
private FakeSuitableOutputChecker suitableMediaOutputChecker;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
testPlayer =
|
TestExoPlayerBuilder builder =
|
||||||
new TestExoPlayerBuilder(ApplicationProvider.getApplicationContext())
|
new TestExoPlayerBuilder(ApplicationProvider.getApplicationContext())
|
||||||
.setSuppressPlaybackOnUnsuitableOutput(true)
|
.setSuppressPlaybackOnUnsuitableOutput(true);
|
||||||
.build();
|
|
||||||
|
if (Util.SDK_INT >= 35) {
|
||||||
|
suitableMediaOutputChecker =
|
||||||
|
new FakeSuitableOutputChecker.Builder()
|
||||||
|
.setIsSuitableExternalOutputAvailable(/* isSuitableOutputAvailable= */ false)
|
||||||
|
.build();
|
||||||
|
builder.setSuitableOutputChecker(suitableMediaOutputChecker);
|
||||||
|
}
|
||||||
|
|
||||||
|
testPlayer = builder.build();
|
||||||
shadowApplication = shadowOf((Application) ApplicationProvider.getApplicationContext());
|
shadowApplication = shadowOf((Application) ApplicationProvider.getApplicationContext());
|
||||||
shadowPackageManager =
|
shadowPackageManager =
|
||||||
shadowOf(ApplicationProvider.getApplicationContext().getPackageManager());
|
shadowOf(ApplicationProvider.getApplicationContext().getPackageManager());
|
||||||
@ -96,7 +109,7 @@ public class WearUnsuitableOutputPlaybackSuppressionResolverListenerTest {
|
|||||||
* playback is suppressed and then unsuppressed.
|
* playback is suppressed and then unsuppressed.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void playbackSuppressionFollowedByResolution_shouldLaunchOSwAndChangePlayerStateToPlaying()
|
public void playbackSuppressionFollowedByResolution_shouldLaunchOutputSwitcherAndStartPlayback()
|
||||||
throws TimeoutException {
|
throws TimeoutException {
|
||||||
shadowPackageManager.setSystemFeature(PackageManager.FEATURE_WATCH, /* supported= */ true);
|
shadowPackageManager.setSystemFeature(PackageManager.FEATURE_WATCH, /* supported= */ true);
|
||||||
registerFakeActivity(
|
registerFakeActivity(
|
||||||
@ -133,8 +146,7 @@ public class WearUnsuitableOutputPlaybackSuppressionResolverListenerTest {
|
|||||||
assertThat(intentTriggered)
|
assertThat(intentTriggered)
|
||||||
.hasComponent(
|
.hasComponent(
|
||||||
FAKE_SYSTEM_OUTPUT_SWITCHER_PACKAGE_NAME, FAKE_SYSTEM_OUTPUT_SWITCHER_CLASS_NAME);
|
FAKE_SYSTEM_OUTPUT_SWITCHER_PACKAGE_NAME, FAKE_SYSTEM_OUTPUT_SWITCHER_CLASS_NAME);
|
||||||
assertThat(playWhenReadyChangeSequence).containsExactly(true, false, true);
|
assertThat(playWhenReadyChangeSequence).containsExactly(true, false, true).inOrder();
|
||||||
assertThat(testPlayer.isPlaying()).isTrue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -142,7 +154,7 @@ public class WearUnsuitableOutputPlaybackSuppressionResolverListenerTest {
|
|||||||
* unsuitable output and the system updated Output Switcher is present on the device.
|
* unsuitable output and the system updated Output Switcher is present on the device.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void playEventWithPlaybackSuppressionWhenUpdatedSystemOSwPresent_shouldLaunchOSw()
|
public void playEventWithPlaybackSuppression_shouldLaunchOutputSwitcher()
|
||||||
throws TimeoutException {
|
throws TimeoutException {
|
||||||
shadowPackageManager.setSystemFeature(PackageManager.FEATURE_WATCH, /* supported= */ true);
|
shadowPackageManager.setSystemFeature(PackageManager.FEATURE_WATCH, /* supported= */ true);
|
||||||
registerFakeActivity(
|
registerFakeActivity(
|
||||||
@ -175,7 +187,7 @@ public class WearUnsuitableOutputPlaybackSuppressionResolverListenerTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void
|
public void
|
||||||
playbackSuppressionWhenBothSystemAndUserInstalledOutputSwitcherPresent_shouldLaunchSystemOSw()
|
playbackSuppressionWithSystemAndUserInstalledComponentsPresent_shouldLaunchSystemComponent()
|
||||||
throws TimeoutException {
|
throws TimeoutException {
|
||||||
shadowPackageManager.setSystemFeature(PackageManager.FEATURE_WATCH, /* supported= */ true);
|
shadowPackageManager.setSystemFeature(PackageManager.FEATURE_WATCH, /* supported= */ true);
|
||||||
registerFakeActivity(
|
registerFakeActivity(
|
||||||
@ -319,7 +331,7 @@ public class WearUnsuitableOutputPlaybackSuppressionResolverListenerTest {
|
|||||||
* and both Output Switcher as well as the Bluetooth settings are present on the device.
|
* and both Output Switcher as well as the Bluetooth settings are present on the device.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void playEventWithPlaybackSuppressionWhenOSwAndBTSettingsBothPresent_shouldLaunchOSw()
|
public void playbackSuppressionWhenMultipleSystemComponentsPresent_shouldLaunchOutputSwitcher()
|
||||||
throws TimeoutException {
|
throws TimeoutException {
|
||||||
shadowPackageManager.setSystemFeature(PackageManager.FEATURE_WATCH, /* supported= */ true);
|
shadowPackageManager.setSystemFeature(PackageManager.FEATURE_WATCH, /* supported= */ true);
|
||||||
registerFakeActivity(
|
registerFakeActivity(
|
||||||
@ -356,9 +368,8 @@ public class WearUnsuitableOutputPlaybackSuppressionResolverListenerTest {
|
|||||||
* is suppressed due to unsuitable output.
|
* is suppressed due to unsuitable output.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void
|
public void playbackSuppressionWhenOnlyUserInstalledComponentsPresent_shouldNotLaunchAnyApp()
|
||||||
playbackSuppressionWhenOnlyUserInstalledOSwAndBTSettingsPresent_shouldNotLaunchAnyApp()
|
throws TimeoutException {
|
||||||
throws TimeoutException {
|
|
||||||
shadowPackageManager.setSystemFeature(PackageManager.FEATURE_WATCH, /* supported= */ true);
|
shadowPackageManager.setSystemFeature(PackageManager.FEATURE_WATCH, /* supported= */ true);
|
||||||
registerFakeActivity(
|
registerFakeActivity(
|
||||||
OUTPUT_SWITCHER_INTENT_ACTION_NAME,
|
OUTPUT_SWITCHER_INTENT_ACTION_NAME,
|
||||||
@ -390,7 +401,7 @@ public class WearUnsuitableOutputPlaybackSuppressionResolverListenerTest {
|
|||||||
* suppressed due to unsuitable output.
|
* suppressed due to unsuitable output.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void playEventWithoutPlaybackSuppression_shouldNotLaunchEitherOSwOrBTSettings()
|
public void playEventWithoutPlaybackSuppression_shouldNotLaunchOutputSwitcherOrBTSettings()
|
||||||
throws TimeoutException {
|
throws TimeoutException {
|
||||||
shadowPackageManager.setSystemFeature(PackageManager.FEATURE_WATCH, /* supported= */ true);
|
shadowPackageManager.setSystemFeature(PackageManager.FEATURE_WATCH, /* supported= */ true);
|
||||||
registerFakeActivity(
|
registerFakeActivity(
|
||||||
@ -423,9 +434,8 @@ public class WearUnsuitableOutputPlaybackSuppressionResolverListenerTest {
|
|||||||
* due to removal of all suitable audio outputs in mid of an ongoing playback.
|
* due to removal of all suitable audio outputs in mid of an ongoing playback.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void
|
public void playbackSuppressionDuringOngoingPlayback_shouldOnlyPauseButNotLaunchSystemComponent()
|
||||||
playbackSuppressionDuringOngoingPlayback_shouldOnlyPauseButNotLaunchEitherOSwOrBTSettings()
|
throws TimeoutException {
|
||||||
throws TimeoutException {
|
|
||||||
shadowPackageManager.setSystemFeature(PackageManager.FEATURE_WATCH, /* supported= */ true);
|
shadowPackageManager.setSystemFeature(PackageManager.FEATURE_WATCH, /* supported= */ true);
|
||||||
registerFakeActivity(
|
registerFakeActivity(
|
||||||
OUTPUT_SWITCHER_INTENT_ACTION_NAME,
|
OUTPUT_SWITCHER_INTENT_ACTION_NAME,
|
||||||
@ -442,6 +452,15 @@ public class WearUnsuitableOutputPlaybackSuppressionResolverListenerTest {
|
|||||||
testPlayer.addListener(
|
testPlayer.addListener(
|
||||||
new WearUnsuitableOutputPlaybackSuppressionResolverListener(
|
new WearUnsuitableOutputPlaybackSuppressionResolverListener(
|
||||||
ApplicationProvider.getApplicationContext()));
|
ApplicationProvider.getApplicationContext()));
|
||||||
|
AtomicBoolean lastPlayWhenReady = new AtomicBoolean();
|
||||||
|
testPlayer.addListener(
|
||||||
|
new Player.Listener() {
|
||||||
|
@Override
|
||||||
|
public void onPlayWhenReadyChanged(
|
||||||
|
boolean playWhenReady, @PlayWhenReadyChangeReason int reason) {
|
||||||
|
lastPlayWhenReady.set(playWhenReady);
|
||||||
|
}
|
||||||
|
});
|
||||||
testPlayer.setMediaItem(
|
testPlayer.setMediaItem(
|
||||||
MediaItem.fromUri("asset:///media/mp4/sample_with_increasing_timestamps_360p.mp4"));
|
MediaItem.fromUri("asset:///media/mp4/sample_with_increasing_timestamps_360p.mp4"));
|
||||||
testPlayer.prepare();
|
testPlayer.prepare();
|
||||||
@ -452,7 +471,7 @@ public class WearUnsuitableOutputPlaybackSuppressionResolverListenerTest {
|
|||||||
runUntilPlayWhenReady(testPlayer, /* expectedPlayWhenReady= */ false);
|
runUntilPlayWhenReady(testPlayer, /* expectedPlayWhenReady= */ false);
|
||||||
|
|
||||||
assertThat(shadowApplication.getNextStartedActivity()).isNull();
|
assertThat(shadowApplication.getNextStartedActivity()).isNull();
|
||||||
assertThat(testPlayer.isPlaying()).isFalse();
|
assertThat(lastPlayWhenReady.get()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Test for pause on the Player when the playback is suppressed due to unsuitable output. */
|
/** Test for pause on the Player when the playback is suppressed due to unsuitable output. */
|
||||||
@ -472,21 +491,20 @@ public class WearUnsuitableOutputPlaybackSuppressionResolverListenerTest {
|
|||||||
testPlayer.setMediaItem(
|
testPlayer.setMediaItem(
|
||||||
MediaItem.fromUri("asset:///media/mp4/sample_with_increasing_timestamps_360p.mp4"));
|
MediaItem.fromUri("asset:///media/mp4/sample_with_increasing_timestamps_360p.mp4"));
|
||||||
testPlayer.prepare();
|
testPlayer.prepare();
|
||||||
AtomicBoolean isPlaybackPaused = new AtomicBoolean(false);
|
AtomicBoolean lastPlayWhenReady = new AtomicBoolean();
|
||||||
testPlayer.addListener(
|
testPlayer.addListener(
|
||||||
new Player.Listener() {
|
new Player.Listener() {
|
||||||
@Override
|
@Override
|
||||||
public void onPlayWhenReadyChanged(boolean playWhenReady, int reason) {
|
public void onPlayWhenReadyChanged(
|
||||||
if (!playWhenReady) {
|
boolean playWhenReady, @PlayWhenReadyChangeReason int reason) {
|
||||||
isPlaybackPaused.set(true);
|
lastPlayWhenReady.set(playWhenReady);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
testPlayer.play();
|
testPlayer.play();
|
||||||
runUntilPlaybackState(testPlayer, Player.STATE_READY);
|
runUntilPlaybackState(testPlayer, Player.STATE_READY);
|
||||||
|
|
||||||
assertThat(isPlaybackPaused.get()).isTrue();
|
assertThat(lastPlayWhenReady.get()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -537,12 +555,20 @@ public class WearUnsuitableOutputPlaybackSuppressionResolverListenerTest {
|
|||||||
WearUnsuitableOutputPlaybackSuppressionResolverListener
|
WearUnsuitableOutputPlaybackSuppressionResolverListener
|
||||||
.DEFAULT_PLAYBACK_SUPPRESSION_AUTO_RESUME_TIMEOUT_MS,
|
.DEFAULT_PLAYBACK_SUPPRESSION_AUTO_RESUME_TIMEOUT_MS,
|
||||||
fakeClock));
|
fakeClock));
|
||||||
|
AtomicBoolean lastPlayWhenReady = new AtomicBoolean();
|
||||||
|
testPlayer.addListener(
|
||||||
|
new Player.Listener() {
|
||||||
|
@Override
|
||||||
|
public void onPlayWhenReadyChanged(
|
||||||
|
boolean playWhenReady, @PlayWhenReadyChangeReason int reason) {
|
||||||
|
lastPlayWhenReady.set(playWhenReady);
|
||||||
|
}
|
||||||
|
});
|
||||||
testPlayer.setMediaItem(
|
testPlayer.setMediaItem(
|
||||||
MediaItem.fromUri("asset:///media/mp4/sample_with_increasing_timestamps_360p.mp4"));
|
MediaItem.fromUri("asset:///media/mp4/sample_with_increasing_timestamps_360p.mp4"));
|
||||||
testPlayer.prepare();
|
testPlayer.prepare();
|
||||||
testPlayer.play();
|
testPlayer.play();
|
||||||
runUntilPlaybackState(testPlayer, Player.STATE_READY);
|
runUntilPlaybackState(testPlayer, Player.STATE_READY);
|
||||||
|
|
||||||
removeConnectedAudioOutput(AudioDeviceInfo.TYPE_BLUETOOTH_A2DP);
|
removeConnectedAudioOutput(AudioDeviceInfo.TYPE_BLUETOOTH_A2DP);
|
||||||
runUntilPlayWhenReady(testPlayer, /* expectedPlayWhenReady= */ false);
|
runUntilPlayWhenReady(testPlayer, /* expectedPlayWhenReady= */ false);
|
||||||
|
|
||||||
@ -555,7 +581,7 @@ public class WearUnsuitableOutputPlaybackSuppressionResolverListenerTest {
|
|||||||
AudioDeviceInfo.TYPE_BLUETOOTH_A2DP, /* notifyAudioDeviceCallbacks= */ true);
|
AudioDeviceInfo.TYPE_BLUETOOTH_A2DP, /* notifyAudioDeviceCallbacks= */ true);
|
||||||
runUntilPlayWhenReady(testPlayer, /* expectedPlayWhenReady= */ false);
|
runUntilPlayWhenReady(testPlayer, /* expectedPlayWhenReady= */ false);
|
||||||
|
|
||||||
assertThat(testPlayer.isPlaying()).isFalse();
|
assertThat(lastPlayWhenReady.get()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -578,21 +604,20 @@ public class WearUnsuitableOutputPlaybackSuppressionResolverListenerTest {
|
|||||||
testPlayer.setMediaItem(
|
testPlayer.setMediaItem(
|
||||||
MediaItem.fromUri("asset:///media/mp4/sample_with_increasing_timestamps_360p.mp4"));
|
MediaItem.fromUri("asset:///media/mp4/sample_with_increasing_timestamps_360p.mp4"));
|
||||||
testPlayer.prepare();
|
testPlayer.prepare();
|
||||||
AtomicBoolean isPlaybackPaused = new AtomicBoolean(false);
|
AtomicBoolean lastPlayWhenReady = new AtomicBoolean();
|
||||||
testPlayer.addListener(
|
testPlayer.addListener(
|
||||||
new Player.Listener() {
|
new Player.Listener() {
|
||||||
@Override
|
@Override
|
||||||
public void onPlayWhenReadyChanged(boolean playWhenReady, int reason) {
|
public void onPlayWhenReadyChanged(
|
||||||
if (!playWhenReady) {
|
boolean playWhenReady, @PlayWhenReadyChangeReason int reason) {
|
||||||
isPlaybackPaused.set(true);
|
lastPlayWhenReady.set(playWhenReady);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
testPlayer.play();
|
testPlayer.play();
|
||||||
runUntilPlaybackState(testPlayer, Player.STATE_READY);
|
runUntilPlaybackState(testPlayer, Player.STATE_READY);
|
||||||
|
|
||||||
assertThat(isPlaybackPaused.get()).isFalse();
|
assertThat(lastPlayWhenReady.get()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -612,6 +637,15 @@ public class WearUnsuitableOutputPlaybackSuppressionResolverListenerTest {
|
|||||||
WearUnsuitableOutputPlaybackSuppressionResolverListener
|
WearUnsuitableOutputPlaybackSuppressionResolverListener
|
||||||
.DEFAULT_PLAYBACK_SUPPRESSION_AUTO_RESUME_TIMEOUT_MS,
|
.DEFAULT_PLAYBACK_SUPPRESSION_AUTO_RESUME_TIMEOUT_MS,
|
||||||
fakeClock));
|
fakeClock));
|
||||||
|
AtomicBoolean lastPlayWhenReady = new AtomicBoolean();
|
||||||
|
testPlayer.addListener(
|
||||||
|
new Player.Listener() {
|
||||||
|
@Override
|
||||||
|
public void onPlayWhenReadyChanged(
|
||||||
|
boolean playWhenReady, @PlayWhenReadyChangeReason int reason) {
|
||||||
|
lastPlayWhenReady.set(playWhenReady);
|
||||||
|
}
|
||||||
|
});
|
||||||
testPlayer.setMediaItem(
|
testPlayer.setMediaItem(
|
||||||
MediaItem.fromUri("asset:///media/mp4/sample_with_increasing_timestamps_360p.mp4"));
|
MediaItem.fromUri("asset:///media/mp4/sample_with_increasing_timestamps_360p.mp4"));
|
||||||
testPlayer.prepare();
|
testPlayer.prepare();
|
||||||
@ -626,7 +660,7 @@ public class WearUnsuitableOutputPlaybackSuppressionResolverListenerTest {
|
|||||||
AudioDeviceInfo.TYPE_BLUETOOTH_A2DP, /* notifyAudioDeviceCallbacks= */ true);
|
AudioDeviceInfo.TYPE_BLUETOOTH_A2DP, /* notifyAudioDeviceCallbacks= */ true);
|
||||||
runUntilPlayWhenReady(testPlayer, /* expectedPlayWhenReady= */ false);
|
runUntilPlayWhenReady(testPlayer, /* expectedPlayWhenReady= */ false);
|
||||||
|
|
||||||
assertThat(testPlayer.isPlaying()).isFalse();
|
assertThat(lastPlayWhenReady.get()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -670,6 +704,15 @@ public class WearUnsuitableOutputPlaybackSuppressionResolverListenerTest {
|
|||||||
testPlayer.addListener(
|
testPlayer.addListener(
|
||||||
new WearUnsuitableOutputPlaybackSuppressionResolverListener(
|
new WearUnsuitableOutputPlaybackSuppressionResolverListener(
|
||||||
ApplicationProvider.getApplicationContext(), TEST_TIME_OUT_MS, fakeClock));
|
ApplicationProvider.getApplicationContext(), TEST_TIME_OUT_MS, fakeClock));
|
||||||
|
AtomicBoolean lastPlayWhenReady = new AtomicBoolean();
|
||||||
|
testPlayer.addListener(
|
||||||
|
new Player.Listener() {
|
||||||
|
@Override
|
||||||
|
public void onPlayWhenReadyChanged(
|
||||||
|
boolean playWhenReady, @PlayWhenReadyChangeReason int reason) {
|
||||||
|
lastPlayWhenReady.set(playWhenReady);
|
||||||
|
}
|
||||||
|
});
|
||||||
testPlayer.setMediaItem(
|
testPlayer.setMediaItem(
|
||||||
MediaItem.fromUri("asset:///media/mp4/sample_with_increasing_timestamps_360p.mp4"));
|
MediaItem.fromUri("asset:///media/mp4/sample_with_increasing_timestamps_360p.mp4"));
|
||||||
testPlayer.prepare();
|
testPlayer.prepare();
|
||||||
@ -681,7 +724,7 @@ public class WearUnsuitableOutputPlaybackSuppressionResolverListenerTest {
|
|||||||
AudioDeviceInfo.TYPE_BLUETOOTH_A2DP, /* notifyAudioDeviceCallbacks= */ true);
|
AudioDeviceInfo.TYPE_BLUETOOTH_A2DP, /* notifyAudioDeviceCallbacks= */ true);
|
||||||
runUntilPlayWhenReady(testPlayer, /* expectedPlayWhenReady= */ false);
|
runUntilPlayWhenReady(testPlayer, /* expectedPlayWhenReady= */ false);
|
||||||
|
|
||||||
assertThat(testPlayer.isPlaying()).isFalse();
|
assertThat(lastPlayWhenReady.get()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Test to ensure wake lock is acquired when playback is suppressed due to unsuitable output. */
|
/** Test to ensure wake lock is acquired when playback is suppressed due to unsuitable output. */
|
||||||
@ -760,6 +803,128 @@ public class WearUnsuitableOutputPlaybackSuppressionResolverListenerTest {
|
|||||||
assertThat(ShadowPowerManager.getLatestWakeLock().isHeld()).isFalse();
|
assertThat(ShadowPowerManager.getLatestWakeLock().isHeld()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Test to verify that attempted playback is paused when the suitable output is not present. */
|
||||||
|
@Test
|
||||||
|
@Config(minSdk = 35)
|
||||||
|
public void playEvent_withSuitableOutputNotPresent_shouldPausePlaybackAndLaunchOutputSwitcher()
|
||||||
|
throws TimeoutException {
|
||||||
|
shadowPackageManager.setSystemFeature(PackageManager.FEATURE_WATCH, /* supported= */ true);
|
||||||
|
suitableMediaOutputChecker.updateIsSelectedSuitableOutputAvailableAndNotify(
|
||||||
|
/* isSelectedOutputSuitableForPlayback= */ false);
|
||||||
|
registerFakeActivity(
|
||||||
|
OUTPUT_SWITCHER_INTENT_ACTION_NAME,
|
||||||
|
FAKE_SYSTEM_OUTPUT_SWITCHER_PACKAGE_NAME,
|
||||||
|
FAKE_SYSTEM_OUTPUT_SWITCHER_CLASS_NAME,
|
||||||
|
ApplicationInfo.FLAG_SYSTEM);
|
||||||
|
testPlayer.addListener(
|
||||||
|
new WearUnsuitableOutputPlaybackSuppressionResolverListener(
|
||||||
|
ApplicationProvider.getApplicationContext()));
|
||||||
|
testPlayer.setMediaItem(
|
||||||
|
MediaItem.fromUri("asset:///media/mp4/sample_with_increasing_timestamps_360p.mp4"));
|
||||||
|
testPlayer.prepare();
|
||||||
|
AtomicBoolean lastPlayWhenReady = new AtomicBoolean();
|
||||||
|
testPlayer.addListener(
|
||||||
|
new Player.Listener() {
|
||||||
|
@Override
|
||||||
|
public void onPlayWhenReadyChanged(
|
||||||
|
boolean playWhenReady, @PlayWhenReadyChangeReason int reason) {
|
||||||
|
lastPlayWhenReady.set(playWhenReady);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
testPlayer.play();
|
||||||
|
runUntilPlaybackState(testPlayer, Player.STATE_READY);
|
||||||
|
shadowOf(Looper.getMainLooper()).idle();
|
||||||
|
|
||||||
|
assertThat(lastPlayWhenReady.get()).isFalse();
|
||||||
|
Intent intentTriggered = shadowApplication.getNextStartedActivity();
|
||||||
|
assertThat(intentTriggered).isNotNull();
|
||||||
|
assertThat(intentTriggered).hasAction(OUTPUT_SWITCHER_INTENT_ACTION_NAME);
|
||||||
|
assertThat(intentTriggered)
|
||||||
|
.hasComponent(
|
||||||
|
FAKE_SYSTEM_OUTPUT_SWITCHER_PACKAGE_NAME, FAKE_SYSTEM_OUTPUT_SWITCHER_CLASS_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test to verify that attempted playback is not paused when the suitable output is already
|
||||||
|
* present.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Config(minSdk = 35)
|
||||||
|
public void playEvent_withSuitableOutputPresent_shouldNotPausePlaybackOrLaunchOutputSwitcher()
|
||||||
|
throws TimeoutException {
|
||||||
|
shadowPackageManager.setSystemFeature(PackageManager.FEATURE_WATCH, /* supported= */ true);
|
||||||
|
suitableMediaOutputChecker.updateIsSelectedSuitableOutputAvailableAndNotify(
|
||||||
|
/* isSelectedOutputSuitableForPlayback= */ false);
|
||||||
|
registerFakeActivity(
|
||||||
|
OUTPUT_SWITCHER_INTENT_ACTION_NAME,
|
||||||
|
FAKE_SYSTEM_OUTPUT_SWITCHER_PACKAGE_NAME,
|
||||||
|
FAKE_SYSTEM_OUTPUT_SWITCHER_CLASS_NAME,
|
||||||
|
ApplicationInfo.FLAG_SYSTEM);
|
||||||
|
suitableMediaOutputChecker.updateIsSelectedSuitableOutputAvailableAndNotify(
|
||||||
|
/* isSelectedOutputSuitableForPlayback= */ true);
|
||||||
|
testPlayer.addListener(
|
||||||
|
new WearUnsuitableOutputPlaybackSuppressionResolverListener(
|
||||||
|
ApplicationProvider.getApplicationContext()));
|
||||||
|
testPlayer.setMediaItem(
|
||||||
|
MediaItem.fromUri("asset:///media/mp4/sample_with_increasing_timestamps_360p.mp4"));
|
||||||
|
testPlayer.prepare();
|
||||||
|
AtomicBoolean lastPlayWhenReady = new AtomicBoolean();
|
||||||
|
testPlayer.addListener(
|
||||||
|
new Player.Listener() {
|
||||||
|
@Override
|
||||||
|
public void onPlayWhenReadyChanged(
|
||||||
|
boolean playWhenReady, @PlayWhenReadyChangeReason int reason) {
|
||||||
|
lastPlayWhenReady.set(playWhenReady);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
testPlayer.play();
|
||||||
|
runUntilPlaybackState(testPlayer, Player.STATE_READY);
|
||||||
|
shadowOf(Looper.getMainLooper()).idle();
|
||||||
|
|
||||||
|
assertThat(lastPlayWhenReady.get()).isTrue();
|
||||||
|
assertThat(shadowApplication.getNextStartedActivity()).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test to verify that playback is not resumed when the suitable output is added after the tested
|
||||||
|
* time out.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Config(minSdk = 35)
|
||||||
|
public void playEvent_suitableOutputAddedAfterTimeOut_shouldNotResumePlayback()
|
||||||
|
throws TimeoutException {
|
||||||
|
shadowPackageManager.setSystemFeature(PackageManager.FEATURE_WATCH, /* supported= */ true);
|
||||||
|
suitableMediaOutputChecker.updateIsSelectedSuitableOutputAvailableAndNotify(
|
||||||
|
/* isSelectedOutputSuitableForPlayback= */ false);
|
||||||
|
testPlayer.setMediaItem(
|
||||||
|
MediaItem.fromUri("asset:///media/mp4/sample_with_increasing_timestamps_360p.mp4"));
|
||||||
|
FakeClock fakeClock = new FakeClock(/* isAutoAdvancing= */ true);
|
||||||
|
testPlayer.addListener(
|
||||||
|
new WearUnsuitableOutputPlaybackSuppressionResolverListener(
|
||||||
|
ApplicationProvider.getApplicationContext(), TEST_TIME_OUT_MS, fakeClock));
|
||||||
|
AtomicBoolean lastPlayWhenReady = new AtomicBoolean();
|
||||||
|
testPlayer.addListener(
|
||||||
|
new Player.Listener() {
|
||||||
|
@Override
|
||||||
|
public void onPlayWhenReadyChanged(
|
||||||
|
boolean playWhenReady, @PlayWhenReadyChangeReason int reason) {
|
||||||
|
lastPlayWhenReady.set(playWhenReady);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
testPlayer.prepare();
|
||||||
|
testPlayer.play();
|
||||||
|
runUntilPlaybackState(testPlayer, Player.STATE_READY);
|
||||||
|
|
||||||
|
fakeClock.advanceTime(TEST_TIME_OUT_MS * 2);
|
||||||
|
suitableMediaOutputChecker.updateIsSelectedSuitableOutputAvailableAndNotify(
|
||||||
|
/* isSelectedOutputSuitableForPlayback= */ true);
|
||||||
|
shadowOf(Looper.getMainLooper()).idle();
|
||||||
|
|
||||||
|
assertThat(lastPlayWhenReady.get()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
private void registerFakeActivity(
|
private void registerFakeActivity(
|
||||||
String fakeActionName, String fakePackageName, String fakeClassName, int applicationFlags) {
|
String fakeActionName, String fakePackageName, String fakeClassName, int applicationFlags) {
|
||||||
ComponentName fakeComponentName = new ComponentName(fakePackageName, fakeClassName);
|
ComponentName fakeComponentName = new ComponentName(fakePackageName, fakeClassName);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user