@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); }
@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 { @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 { @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, PlayerControl playerControl); }
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, 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(); }
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, 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; }