AudioFocusManager { @PlayerCommand public int setAudioAttributes( @Nullable AudioAttributes audioAttributes, boolean playWhenReady, int playerState) { if (!Util.areEqual(this.audioAttributes, audioAttributes)) { this.audioAttributes = audioAttributes; focusGain = convertAudioAttributesToFocusGain(audioAttributes); Assertions.checkArgument( focusGain == C.AUDIOFOCUS_GAIN || focusGain == C.AUDIOFOCUS_NONE, "Automatic handling of audio focus is only available for USAGE_MEDIA and USAGE_GAME."); if (playWhenReady && (playerState == Player.STATE_BUFFERING || playerState == Player.STATE_READY)) { return requestAudioFocus(); } } return playerState == Player.STATE_IDLE ? handleIdle(playWhenReady) : handlePrepare(playWhenReady); } AudioFocusManager(Context context, Handler eventHandler, PlayerControl playerControl); float getVolumeMultiplier(); @PlayerCommand int setAudioAttributes(
      @Nullable AudioAttributes audioAttributes, boolean playWhenReady, int playerState); @PlayerCommand int handlePrepare(boolean playWhenReady); @PlayerCommand int handleSetPlayWhenReady(boolean playWhenReady, int playerState); void handleStop(); static final int PLAYER_COMMAND_DO_NOT_PLAY; static final int PLAYER_COMMAND_WAIT_FOR_CALLBACK; static final int PLAYER_COMMAND_PLAY_WHEN_READY; }
@Test public void setAudioAttributes_withNullUsage_doesNotManageAudioFocus() { assertThat( audioFocusManager.setAudioAttributes( null, false, Player.STATE_IDLE)) .isEqualTo(PLAYER_COMMAND_DO_NOT_PLAY); assertThat( audioFocusManager.setAudioAttributes( null, true, Player.STATE_READY)) .isEqualTo(PLAYER_COMMAND_PLAY_WHEN_READY); ShadowAudioManager.AudioFocusRequest request = Shadows.shadowOf(audioManager).getLastAudioFocusRequest(); assertThat(request).isNull(); }
@Test @Config(maxSdk = 25) public void setAudioAttributes_withNullUsage_releasesAudioFocus() { AudioAttributes media = new AudioAttributes.Builder().setUsage(C.USAGE_MEDIA).build(); Shadows.shadowOf(audioManager) .setNextFocusRequestResponse(AudioManager.AUDIOFOCUS_REQUEST_GRANTED); assertThat( audioFocusManager.setAudioAttributes( media, true, Player.STATE_READY)) .isEqualTo(PLAYER_COMMAND_PLAY_WHEN_READY); ShadowAudioManager.AudioFocusRequest request = Shadows.shadowOf(audioManager).getLastAudioFocusRequest(); assertThat(request.durationHint).isEqualTo(AudioManager.AUDIOFOCUS_GAIN); assertThat( audioFocusManager.setAudioAttributes( null, true, Player.STATE_READY)) .isEqualTo(PLAYER_COMMAND_PLAY_WHEN_READY); AudioManager.OnAudioFocusChangeListener lastRequest = Shadows.shadowOf(audioManager).getLastAbandonedAudioFocusListener(); assertThat(lastRequest).isNotNull(); }
@Test @Config(minSdk = 26, maxSdk = TARGET_SDK) public void setAudioAttributes_withNullUsage_releasesAudioFocus_v26() { AudioAttributes media = new AudioAttributes.Builder().setUsage(C.USAGE_MEDIA).build(); Shadows.shadowOf(audioManager) .setNextFocusRequestResponse(AudioManager.AUDIOFOCUS_REQUEST_GRANTED); assertThat( audioFocusManager.setAudioAttributes( media, true, Player.STATE_READY)) .isEqualTo(PLAYER_COMMAND_PLAY_WHEN_READY); ShadowAudioManager.AudioFocusRequest request = Shadows.shadowOf(audioManager).getLastAudioFocusRequest(); assertThat(getAudioFocusGainFromRequest(request)).isEqualTo(AudioManager.AUDIOFOCUS_GAIN); assertThat( audioFocusManager.setAudioAttributes( null, true, Player.STATE_READY)) .isEqualTo(PLAYER_COMMAND_PLAY_WHEN_READY); AudioFocusRequest lastRequest = Shadows.shadowOf(audioManager).getLastAbandonedAudioFocusRequest(); assertThat(lastRequest).isNotNull(); }
@Test public void setAudioAttributes_withUsageAlarm_throwsIllegalArgumentException() { AudioAttributes alarm = new AudioAttributes.Builder().setUsage(C.USAGE_ALARM).build(); try { audioFocusManager.setAudioAttributes(alarm, false, Player.STATE_IDLE); fail(); } catch (IllegalArgumentException e) { } }
@Test public void setAudioAttributes_withUsageMedia_usesAudioFocusGain() { AudioAttributes media = new AudioAttributes.Builder().setUsage(C.USAGE_MEDIA).build(); Shadows.shadowOf(audioManager) .setNextFocusRequestResponse(AudioManager.AUDIOFOCUS_REQUEST_GRANTED); assertThat( audioFocusManager.setAudioAttributes( media, true, Player.STATE_READY)) .isEqualTo(PLAYER_COMMAND_PLAY_WHEN_READY); ShadowAudioManager.AudioFocusRequest request = Shadows.shadowOf(audioManager).getLastAudioFocusRequest(); assertThat(getAudioFocusGainFromRequest(request)).isEqualTo(AudioManager.AUDIOFOCUS_GAIN); }
@Test public void setAudioAttributes_inStateEnded_requestsAudioFocus() { AudioAttributes media = new AudioAttributes.Builder().setUsage(C.USAGE_MEDIA).build(); Shadows.shadowOf(audioManager) .setNextFocusRequestResponse(AudioManager.AUDIOFOCUS_REQUEST_GRANTED); assertThat( audioFocusManager.setAudioAttributes( media, true, Player.STATE_ENDED)) .isEqualTo(PLAYER_COMMAND_PLAY_WHEN_READY); ShadowAudioManager.AudioFocusRequest request = Shadows.shadowOf(audioManager).getLastAudioFocusRequest(); assertThat(getAudioFocusGainFromRequest(request)).isEqualTo(AudioManager.AUDIOFOCUS_GAIN); }
@Test @Config(maxSdk = 25) public void onAudioFocusChange_withAudioFocusLost_sendsDoNotPlayAndAbandondsFocus() { 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, 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); }