mirror of
https://github.com/samsonjs/media.git
synced 2026-04-09 11:55:46 +00:00
Add unit tests for AudioFocusManager.
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=210714110
This commit is contained in:
parent
d308fff88d
commit
595b6b8fde
1 changed files with 323 additions and 0 deletions
|
|
@ -0,0 +1,323 @@
|
|||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.google.android.exoplayer2.audio;
|
||||
|
||||
import static com.google.android.exoplayer2.audio.AudioFocusManager.PLAYER_COMMAND_DO_NOT_PLAY;
|
||||
import static com.google.android.exoplayer2.audio.AudioFocusManager.PLAYER_COMMAND_PLAY_WHEN_READY;
|
||||
import static com.google.android.exoplayer2.audio.AudioFocusManager.PLAYER_COMMAND_WAIT_FOR_CALLBACK;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.AudioManager;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Player;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.Shadows;
|
||||
import org.robolectric.shadows.ShadowAudioManager;
|
||||
|
||||
/** Unit tests for {@link AudioFocusManager}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AudioFocusManagerTest {
|
||||
private static final int NO_COMMAND_RECEIVED = ~PLAYER_COMMAND_WAIT_FOR_CALLBACK;
|
||||
|
||||
private AudioFocusManager audioFocusManager;
|
||||
private TestPlayerControl testPlayerControl;
|
||||
|
||||
private AudioManager audioManager;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
audioManager =
|
||||
(AudioManager) RuntimeEnvironment.application.getSystemService(Context.AUDIO_SERVICE);
|
||||
|
||||
testPlayerControl = new TestPlayerControl();
|
||||
audioFocusManager = new AudioFocusManager(RuntimeEnvironment.application, testPlayerControl);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setAudioAttributes_withNullUsage_doesNotManageAudioFocus() {
|
||||
// Ensure that NULL audio attributes -> don't manage audio focus
|
||||
assertThat(
|
||||
audioFocusManager.setAudioAttributes(
|
||||
/* audioAttributes= */ null, /* playWhenReady= */ false, Player.STATE_IDLE))
|
||||
.isEqualTo(PLAYER_COMMAND_PLAY_WHEN_READY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setAudioAttributes_withUsageAlarm_throwsIllegalArgumentException() {
|
||||
// Ensure that audio attributes that map to AUDIOFOCUS_GAIN_TRANSIENT* throw
|
||||
AudioAttributes alarm = new AudioAttributes.Builder().setUsage(C.USAGE_ALARM).build();
|
||||
try {
|
||||
audioFocusManager.setAudioAttributes(alarm, /* playWhenReady= */ false, Player.STATE_IDLE);
|
||||
fail();
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setAudioAttributes_withUsageMedia_usesAudioFocusGain() {
|
||||
// Ensure setting media type audio attributes requests AUDIOFOCUS_GAIN.
|
||||
AudioAttributes media = new AudioAttributes.Builder().setUsage(C.USAGE_MEDIA).build();
|
||||
Shadows.shadowOf(audioManager)
|
||||
.setNextFocusRequestResponse(AudioManager.AUDIOFOCUS_REQUEST_GRANTED);
|
||||
|
||||
assertThat(
|
||||
audioFocusManager.setAudioAttributes(
|
||||
media, /* playWhenReady= */ true, Player.STATE_READY))
|
||||
.isEqualTo(PLAYER_COMMAND_PLAY_WHEN_READY);
|
||||
ShadowAudioManager.AudioFocusRequest request =
|
||||
Shadows.shadowOf(audioManager).getLastAudioFocusRequest();
|
||||
assertThat(request.durationHint).isEqualTo(AudioManager.AUDIOFOCUS_GAIN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setAudioAttributes_inStateEnded_requestsAudioFocus() {
|
||||
// Ensure setting audio attributes when player is in STATE_ENDED requests audio focus.
|
||||
AudioAttributes media = new AudioAttributes.Builder().setUsage(C.USAGE_MEDIA).build();
|
||||
Shadows.shadowOf(audioManager)
|
||||
.setNextFocusRequestResponse(AudioManager.AUDIOFOCUS_REQUEST_GRANTED);
|
||||
|
||||
assertThat(
|
||||
audioFocusManager.setAudioAttributes(
|
||||
media, /* playWhenReady= */ true, Player.STATE_ENDED))
|
||||
.isEqualTo(PLAYER_COMMAND_PLAY_WHEN_READY);
|
||||
ShadowAudioManager.AudioFocusRequest request =
|
||||
Shadows.shadowOf(audioManager).getLastAudioFocusRequest();
|
||||
assertThat(request.durationHint).isEqualTo(AudioManager.AUDIOFOCUS_GAIN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handlePrepare_afterSetAudioAttributes_setsPlayerCommandPlayWhenReady() {
|
||||
// Ensure that when playWhenReady is true while the player is IDLE, audio focus is only
|
||||
// requested after calling handlePrepare.
|
||||
AudioAttributes media = new AudioAttributes.Builder().setUsage(C.USAGE_MEDIA).build();
|
||||
|
||||
Shadows.shadowOf(audioManager)
|
||||
.setNextFocusRequestResponse(AudioManager.AUDIOFOCUS_REQUEST_GRANTED);
|
||||
|
||||
assertThat(
|
||||
audioFocusManager.setAudioAttributes(
|
||||
media, /* playWhenReady= */ true, Player.STATE_IDLE))
|
||||
.isEqualTo(PLAYER_COMMAND_WAIT_FOR_CALLBACK);
|
||||
assertThat(Shadows.shadowOf(audioManager).getLastAudioFocusRequest()).isNull();
|
||||
assertThat(audioFocusManager.handlePrepare(/* playWhenReady= */ true))
|
||||
.isEqualTo(PLAYER_COMMAND_PLAY_WHEN_READY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleSetPlayWhenReady_afterSetAudioAttributes_setsPlayerCommandPlayWhenReady() {
|
||||
// Ensure that audio focus is not requested until playWhenReady is true.
|
||||
AudioAttributes media = new AudioAttributes.Builder().setUsage(C.USAGE_MEDIA).build();
|
||||
|
||||
Shadows.shadowOf(audioManager)
|
||||
.setNextFocusRequestResponse(AudioManager.AUDIOFOCUS_REQUEST_GRANTED);
|
||||
|
||||
assertThat(audioFocusManager.handlePrepare(/* playWhenReady= */ false))
|
||||
.isEqualTo(PLAYER_COMMAND_DO_NOT_PLAY);
|
||||
assertThat(Shadows.shadowOf(audioManager).getLastAudioFocusRequest()).isNull();
|
||||
assertThat(
|
||||
audioFocusManager.setAudioAttributes(
|
||||
media, /* playWhenReady= */ false, Player.STATE_READY))
|
||||
.isEqualTo(PLAYER_COMMAND_DO_NOT_PLAY);
|
||||
assertThat(Shadows.shadowOf(audioManager).getLastAudioFocusRequest()).isNull();
|
||||
assertThat(
|
||||
audioFocusManager.handleSetPlayWhenReady(/* playWhenReady= */ true, Player.STATE_READY))
|
||||
.isEqualTo(PLAYER_COMMAND_PLAY_WHEN_READY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onAudioFocusChange_withDuckEnabled_volumeReducedAndRestored() {
|
||||
// Ensure that the volume multiplier is adjusted when audio focus is lost to
|
||||
// AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK, and returns to the default value after focus is
|
||||
// regained.
|
||||
AudioAttributes media = new AudioAttributes.Builder().setUsage(C.USAGE_MEDIA).build();
|
||||
|
||||
Shadows.shadowOf(audioManager)
|
||||
.setNextFocusRequestResponse(AudioManager.AUDIOFOCUS_REQUEST_GRANTED);
|
||||
assertThat(
|
||||
audioFocusManager.setAudioAttributes(
|
||||
media, /* playWhenReady= */ true, Player.STATE_READY))
|
||||
.isEqualTo(PLAYER_COMMAND_PLAY_WHEN_READY);
|
||||
|
||||
ShadowAudioManager.AudioFocusRequest request =
|
||||
Shadows.shadowOf(audioManager).getLastAudioFocusRequest();
|
||||
request.listener.onAudioFocusChange(AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK);
|
||||
assertThat(testPlayerControl.lastVolumeMultiplier).isLessThan(1.0f);
|
||||
assertThat(testPlayerControl.lastPlayerCommand).isEqualTo(NO_COMMAND_RECEIVED);
|
||||
request.listener.onAudioFocusChange(AudioManager.AUDIOFOCUS_GAIN);
|
||||
assertThat(testPlayerControl.lastVolumeMultiplier).isEqualTo(1.0f);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onAudioFocusChange_withPausedWhenDucked_sendsCommandWaitForCallback() {
|
||||
// Ensure that the player is commanded to pause when audio focus is lost with
|
||||
// AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK and the content type is CONTENT_TYPE_SPEECH.
|
||||
AudioAttributes media =
|
||||
new AudioAttributes.Builder()
|
||||
.setUsage(C.USAGE_MEDIA)
|
||||
.setContentType(C.CONTENT_TYPE_SPEECH)
|
||||
.build();
|
||||
|
||||
Shadows.shadowOf(audioManager)
|
||||
.setNextFocusRequestResponse(AudioManager.AUDIOFOCUS_REQUEST_GRANTED);
|
||||
assertThat(
|
||||
audioFocusManager.setAudioAttributes(
|
||||
media, /* playWhenReady= */ true, Player.STATE_READY))
|
||||
.isEqualTo(PLAYER_COMMAND_PLAY_WHEN_READY);
|
||||
|
||||
ShadowAudioManager.AudioFocusRequest request =
|
||||
Shadows.shadowOf(audioManager).getLastAudioFocusRequest();
|
||||
request.listener.onAudioFocusChange(AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK);
|
||||
assertThat(testPlayerControl.lastPlayerCommand).isEqualTo(PLAYER_COMMAND_WAIT_FOR_CALLBACK);
|
||||
assertThat(testPlayerControl.lastVolumeMultiplier).isEqualTo(1.0f);
|
||||
request.listener.onAudioFocusChange(AudioManager.AUDIOFOCUS_GAIN);
|
||||
assertThat(testPlayerControl.lastPlayerCommand).isEqualTo(PLAYER_COMMAND_PLAY_WHEN_READY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onAudioFocusChange_withTransientLost_sendsCommandWaitForCallback() {
|
||||
// Ensure that the player is commanded to pause when audio focus is lost with
|
||||
// AUDIOFOCUS_LOSS_TRANSIENT.
|
||||
AudioAttributes media = new AudioAttributes.Builder().setUsage(C.USAGE_MEDIA).build();
|
||||
|
||||
Shadows.shadowOf(audioManager)
|
||||
.setNextFocusRequestResponse(AudioManager.AUDIOFOCUS_REQUEST_GRANTED);
|
||||
assertThat(
|
||||
audioFocusManager.setAudioAttributes(
|
||||
media, /* playWhenReady= */ true, Player.STATE_READY))
|
||||
.isEqualTo(PLAYER_COMMAND_PLAY_WHEN_READY);
|
||||
|
||||
ShadowAudioManager.AudioFocusRequest request =
|
||||
Shadows.shadowOf(audioManager).getLastAudioFocusRequest();
|
||||
request.listener.onAudioFocusChange(AudioManager.AUDIOFOCUS_LOSS_TRANSIENT);
|
||||
assertThat(testPlayerControl.lastVolumeMultiplier).isEqualTo(1.0f);
|
||||
assertThat(testPlayerControl.lastPlayerCommand).isEqualTo(PLAYER_COMMAND_WAIT_FOR_CALLBACK);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onAudioFocusChange_withAudioFocusLost_sendsDoNotPlayAndAbandondsFocus() {
|
||||
// Ensure that AUDIOFOCUS_LOSS causes AudioFocusManager to pause playback and abandon audio
|
||||
// focus.
|
||||
AudioAttributes media =
|
||||
new AudioAttributes.Builder()
|
||||
.setUsage(C.USAGE_MEDIA)
|
||||
.setContentType(C.CONTENT_TYPE_SPEECH)
|
||||
.build();
|
||||
|
||||
Shadows.shadowOf(audioManager)
|
||||
.setNextFocusRequestResponse(AudioManager.AUDIOFOCUS_REQUEST_GRANTED);
|
||||
assertThat(
|
||||
audioFocusManager.setAudioAttributes(
|
||||
media, /* playWhenReady= */ true, Player.STATE_READY))
|
||||
.isEqualTo(PLAYER_COMMAND_PLAY_WHEN_READY);
|
||||
assertThat(Shadows.shadowOf(audioManager).getLastAbandonedAudioFocusListener()).isNull();
|
||||
|
||||
ShadowAudioManager.AudioFocusRequest request =
|
||||
Shadows.shadowOf(audioManager).getLastAudioFocusRequest();
|
||||
request.listener.onAudioFocusChange(AudioManager.AUDIOFOCUS_LOSS);
|
||||
assertThat(testPlayerControl.lastPlayerCommand).isEqualTo(PLAYER_COMMAND_DO_NOT_PLAY);
|
||||
assertThat(Shadows.shadowOf(audioManager).getLastAbandonedAudioFocusListener())
|
||||
.isEqualTo(request.listener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleStop_withAudioFocus_abandonsAudioFocus() {
|
||||
// Ensure that handleStop causes AudioFocusManager to abandon audio focus.
|
||||
AudioAttributes media =
|
||||
new AudioAttributes.Builder()
|
||||
.setUsage(C.USAGE_MEDIA)
|
||||
.setContentType(C.CONTENT_TYPE_SPEECH)
|
||||
.build();
|
||||
|
||||
Shadows.shadowOf(audioManager)
|
||||
.setNextFocusRequestResponse(AudioManager.AUDIOFOCUS_REQUEST_GRANTED);
|
||||
assertThat(
|
||||
audioFocusManager.setAudioAttributes(
|
||||
media, /* playWhenReady= */ true, Player.STATE_READY))
|
||||
.isEqualTo(PLAYER_COMMAND_PLAY_WHEN_READY);
|
||||
assertThat(Shadows.shadowOf(audioManager).getLastAbandonedAudioFocusListener()).isNull();
|
||||
|
||||
ShadowAudioManager.AudioFocusRequest request =
|
||||
Shadows.shadowOf(audioManager).getLastAudioFocusRequest();
|
||||
audioFocusManager.handleStop();
|
||||
assertThat(Shadows.shadowOf(audioManager).getLastAbandonedAudioFocusListener())
|
||||
.isEqualTo(request.listener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleStop_withoutAudioFocus_stillAbandonsFocus() {
|
||||
// Ensure that handleStop causes AudioFocusManager to call through to abandon audio focus
|
||||
// even if focus wasn't requested.
|
||||
AudioAttributes media =
|
||||
new AudioAttributes.Builder()
|
||||
.setUsage(C.USAGE_MEDIA)
|
||||
.setContentType(C.CONTENT_TYPE_SPEECH)
|
||||
.build();
|
||||
|
||||
Shadows.shadowOf(audioManager)
|
||||
.setNextFocusRequestResponse(AudioManager.AUDIOFOCUS_REQUEST_GRANTED);
|
||||
assertThat(
|
||||
audioFocusManager.setAudioAttributes(
|
||||
media, /* playWhenReady= */ false, Player.STATE_READY))
|
||||
.isEqualTo(PLAYER_COMMAND_DO_NOT_PLAY);
|
||||
assertThat(Shadows.shadowOf(audioManager).getLastAbandonedAudioFocusListener()).isNull();
|
||||
ShadowAudioManager.AudioFocusRequest request =
|
||||
Shadows.shadowOf(audioManager).getLastAudioFocusRequest();
|
||||
assertThat(request).isNull();
|
||||
|
||||
audioFocusManager.handleStop();
|
||||
assertThat(Shadows.shadowOf(audioManager).getLastAbandonedAudioFocusListener()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleStop_withoutHandlingAudioFocus_isNoOp() {
|
||||
// Ensure that handleStop is a no-op if audio focus isn't handled.
|
||||
Shadows.shadowOf(audioManager)
|
||||
.setNextFocusRequestResponse(AudioManager.AUDIOFOCUS_REQUEST_GRANTED);
|
||||
assertThat(
|
||||
audioFocusManager.setAudioAttributes(
|
||||
/* audioAttributes= */ null, /* playWhenReady= */ false, Player.STATE_READY))
|
||||
.isEqualTo(PLAYER_COMMAND_PLAY_WHEN_READY);
|
||||
assertThat(Shadows.shadowOf(audioManager).getLastAbandonedAudioFocusListener()).isNull();
|
||||
ShadowAudioManager.AudioFocusRequest request =
|
||||
Shadows.shadowOf(audioManager).getLastAudioFocusRequest();
|
||||
assertThat(request).isNull();
|
||||
|
||||
audioFocusManager.handleStop();
|
||||
assertThat(Shadows.shadowOf(audioManager).getLastAbandonedAudioFocusListener()).isNull();
|
||||
}
|
||||
|
||||
private static class TestPlayerControl implements AudioFocusManager.PlayerControl {
|
||||
private float lastVolumeMultiplier = 1.0f;
|
||||
private int lastPlayerCommand = NO_COMMAND_RECEIVED;
|
||||
|
||||
@Override
|
||||
public void setVolumeMultiplier(float volumeMultiplier) {
|
||||
lastVolumeMultiplier = volumeMultiplier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executePlayerCommand(int playerCommand) {
|
||||
lastPlayerCommand = playerCommand;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue