diff --git a/CHANGELOG.md b/CHANGELOG.md index d069ee07..246dbd66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,13 +1,14 @@ ## Changelog - +### Version 6.0.0-alpha.7 +- Android: Fix memory leaks from AudioManager [#3123](https://github.com/react-native-video/react-native-video/pull/3123) +- Android: Fixed syntax error [#3182](https://github.com/react-native-video/react-native-video/issues/3182) ### Version 6.0.0-alpha.6 - Feature: Video range support [#3030](https://github.com/react-native-video/react-native-video/pull/3030) - iOS: remove undocumented `currentTime` property [#3064](https://github.com/react-native-video/react-native-video/pull/3064) - iOS: make sure that the audio in ads is muted when the player is muted. [#3068](https://github.com/react-native-video/react-native-video/pull/3077) - iOS: make IMA build optionnal -- Android: Fixed syntax error [#3182](https://github.com/react-native-video/react-native-video/issues/3182) ### Version 6.0.0-alpha.5 diff --git a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index ebecbdde..8029a348 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -119,7 +119,6 @@ class ReactExoplayerView extends FrameLayout implements Player.Listener, BandwidthMeter.EventListener, BecomingNoisyListener, - AudioManager.OnAudioFocusChangeListener, DrmSessionEventListener, AdEvent.AdEventListener { @@ -215,6 +214,7 @@ class ReactExoplayerView extends FrameLayout implements private final ThemedReactContext themedReactContext; private final AudioManager audioManager; private final AudioBecomingNoisyReceiver audioBecomingNoisyReceiver; + private final AudioManager.OnAudioFocusChangeListener audioFocusChangeListener; // store last progress event values to avoid sending unnecessary messages private long lastPos = -1; @@ -270,6 +270,7 @@ class ReactExoplayerView extends FrameLayout implements audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); themedReactContext.addLifecycleEventListener(this); audioBecomingNoisyReceiver = new AudioBecomingNoisyReceiver(themedReactContext); + audioFocusChangeListener = new OnAudioFocusChangedListener(this); } private boolean isPlayingAd() { @@ -903,11 +904,54 @@ class ReactExoplayerView extends FrameLayout implements bandwidthMeter.removeEventListener(this); } + private static class OnAudioFocusChangedListener implements AudioManager.OnAudioFocusChangeListener { + private final ReactExoplayerView view; + + private OnAudioFocusChangedListener(ReactExoplayerView view) { + this.view = view; + } + + @Override + public void onAudioFocusChange(int focusChange) { + switch (focusChange) { + case AudioManager.AUDIOFOCUS_LOSS: + view.hasAudioFocus = false; + view.eventEmitter.audioFocusChanged(false); + view.pausePlayback(); + view.audioManager.abandonAudioFocus(this); + break; + case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: + view.eventEmitter.audioFocusChanged(false); + break; + case AudioManager.AUDIOFOCUS_GAIN: + view.hasAudioFocus = true; + view.eventEmitter.audioFocusChanged(true); + break; + default: + break; + } + + if (view.player != null) { + if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) { + // Lower the volume + if (!view.muted) { + view.player.setVolume(view.audioVolume * 0.8f); + } + } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) { + // Raise it back to normal + if (!view.muted) { + view.player.setVolume(view.audioVolume * 1); + } + } + } + } + } + private boolean requestAudioFocus() { if (disableFocus || srcUri == null || this.hasAudioFocus) { return true; } - int result = audioManager.requestAudioFocus(this, + int result = audioManager.requestAudioFocus(audioFocusChangeListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN); return result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED; @@ -973,7 +1017,7 @@ class ReactExoplayerView extends FrameLayout implements if (isFullscreen) { setFullscreen(false); } - audioManager.abandonAudioFocus(this); + audioManager.abandonAudioFocus(audioFocusChangeListener); } private void updateResumePosition() { @@ -1011,43 +1055,6 @@ class ReactExoplayerView extends FrameLayout implements } - // AudioManager.OnAudioFocusChangeListener implementation - - @Override - public void onAudioFocusChange(int focusChange) { - switch (focusChange) { - case AudioManager.AUDIOFOCUS_LOSS: - this.hasAudioFocus = false; - eventEmitter.audioFocusChanged(false); - pausePlayback(); - audioManager.abandonAudioFocus(this); - break; - case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: - eventEmitter.audioFocusChanged(false); - break; - case AudioManager.AUDIOFOCUS_GAIN: - this.hasAudioFocus = true; - eventEmitter.audioFocusChanged(true); - break; - default: - break; - } - - if (player != null) { - if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) { - // Lower the volume - if (!muted) { - player.setVolume(audioVolume * 0.8f); - } - } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) { - // Raise it back to normal - if (!muted) { - player.setVolume(audioVolume * 1); - } - } - } - } - // AudioBecomingNoisyListener implementation @Override