fix(android): fix bugs related Android PIP listeners (#4441)
* fix(android): fixed bug where listeners were not removed properly * fix(android): fixes a bug that causes PIP to work when player is null * refactor(android): call pipUnsubscriber without handler * chore(android): apply lint
This commit is contained in:
@@ -17,6 +17,7 @@ import androidx.annotation.ChecksSdkIntAtLeast
|
|||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.core.app.AppOpsManagerCompat
|
import androidx.core.app.AppOpsManagerCompat
|
||||||
import androidx.core.app.PictureInPictureModeChangedInfo
|
import androidx.core.app.PictureInPictureModeChangedInfo
|
||||||
|
import androidx.core.util.Consumer
|
||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.media3.exoplayer.ExoPlayer
|
import androidx.media3.exoplayer.ExoPlayer
|
||||||
import com.brentvatne.common.toolbox.DebugLog
|
import com.brentvatne.common.toolbox.DebugLog
|
||||||
@@ -40,7 +41,7 @@ object PictureInPictureUtil {
|
|||||||
fun addLifecycleEventListener(context: ThemedReactContext, view: ReactExoplayerView): Runnable {
|
fun addLifecycleEventListener(context: ThemedReactContext, view: ReactExoplayerView): Runnable {
|
||||||
val activity = context.findActivity()
|
val activity = context.findActivity()
|
||||||
|
|
||||||
val onPictureInPictureModeChanged: (info: PictureInPictureModeChangedInfo) -> Unit = { info: PictureInPictureModeChangedInfo ->
|
val onPictureInPictureModeChanged = Consumer<PictureInPictureModeChangedInfo> { info ->
|
||||||
view.setIsInPictureInPicture(info.isInPictureInPictureMode)
|
view.setIsInPictureInPicture(info.isInPictureInPictureMode)
|
||||||
if (!info.isInPictureInPictureMode && activity.lifecycle.currentState == Lifecycle.State.CREATED) {
|
if (!info.isInPictureInPictureMode && activity.lifecycle.currentState == Lifecycle.State.CREATED) {
|
||||||
// when user click close button of PIP
|
// when user click close button of PIP
|
||||||
@@ -48,7 +49,7 @@ object PictureInPictureUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val onUserLeaveHintCallback = {
|
val onUserLeaveHintCallback = Runnable {
|
||||||
if (view.enterPictureInPictureOnLeave) {
|
if (view.enterPictureInPictureOnLeave) {
|
||||||
view.enterPictureInPictureMode()
|
view.enterPictureInPictureMode()
|
||||||
}
|
}
|
||||||
@@ -61,10 +62,10 @@ object PictureInPictureUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @TODO convert to lambda when ReactExoplayerView migrated
|
// @TODO convert to lambda when ReactExoplayerView migrated
|
||||||
return object : Runnable {
|
return Runnable {
|
||||||
override fun run() {
|
with(activity) {
|
||||||
context.findActivity().removeOnPictureInPictureModeChangedListener(onPictureInPictureModeChanged)
|
removeOnPictureInPictureModeChangedListener(onPictureInPictureModeChanged)
|
||||||
context.findActivity().removeOnUserLeaveHintListener(onUserLeaveHintCallback)
|
removeOnUserLeaveHintListener(onUserLeaveHintCallback)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -224,9 +224,9 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||||||
private ArrayList<Integer> rootViewChildrenOriginalVisibility = new ArrayList<Integer>();
|
private ArrayList<Integer> rootViewChildrenOriginalVisibility = new ArrayList<Integer>();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When user is seeking first called is on onPositionDiscontinuity -> DISCONTINUITY_REASON_SEEK
|
* When user is seeking first called is on onPositionDiscontinuity -> DISCONTINUITY_REASON_SEEK
|
||||||
* Then we set if to false when playback is back in onIsPlayingChanged -> true
|
* Then we set if to false when playback is back in onIsPlayingChanged -> true
|
||||||
*/
|
*/
|
||||||
private boolean isSeeking = false;
|
private boolean isSeeking = false;
|
||||||
private long seekPosition = -1;
|
private long seekPosition = -1;
|
||||||
|
|
||||||
@@ -332,7 +332,6 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||||||
|
|
||||||
audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
||||||
themedReactContext.addLifecycleEventListener(this);
|
themedReactContext.addLifecycleEventListener(this);
|
||||||
pipListenerUnsubscribe = PictureInPictureUtil.addLifecycleEventListener(context, this);
|
|
||||||
audioBecomingNoisyReceiver = new AudioBecomingNoisyReceiver(themedReactContext);
|
audioBecomingNoisyReceiver = new AudioBecomingNoisyReceiver(themedReactContext);
|
||||||
audioFocusChangeListener = new OnAudioFocusChangedListener(this, themedReactContext);
|
audioFocusChangeListener = new OnAudioFocusChangedListener(this, themedReactContext);
|
||||||
pictureInPictureReceiver = new PictureInPictureReceiver(this, themedReactContext);
|
pictureInPictureReceiver = new PictureInPictureReceiver(this, themedReactContext);
|
||||||
@@ -767,6 +766,8 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||||||
if (player == null) {
|
if (player == null) {
|
||||||
// Initialize core configuration and listeners
|
// Initialize core configuration and listeners
|
||||||
initializePlayerCore(self);
|
initializePlayerCore(self);
|
||||||
|
pipListenerUnsubscribe = PictureInPictureUtil.addLifecycleEventListener(themedReactContext, this);
|
||||||
|
PictureInPictureUtil.applyAutoEnterEnabled(themedReactContext, pictureInPictureParamsBuilder, this.enterPictureInPictureOnLeave);
|
||||||
}
|
}
|
||||||
if (!source.isLocalAssetFile() && !source.isAsset() && source.getBufferConfig().getCacheSize() > 0) {
|
if (!source.isLocalAssetFile() && !source.isAsset() && source.getBufferConfig().getCacheSize() > 0) {
|
||||||
RNVSimpleCache.INSTANCE.setSimpleCache(
|
RNVSimpleCache.INSTANCE.setSimpleCache(
|
||||||
@@ -935,7 +936,7 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||||||
: (e.reason == UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME
|
: (e.reason == UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME
|
||||||
? R.string.error_drm_unsupported_scheme : R.string.error_drm_unknown);
|
? R.string.error_drm_unsupported_scheme : R.string.error_drm_unknown);
|
||||||
eventEmitter.onVideoError.invoke(getResources().getString(errorStringId), e, "3003");
|
eventEmitter.onVideoError.invoke(getResources().getString(errorStringId), e, "3003");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return drmSessionManager;
|
return drmSessionManager;
|
||||||
@@ -1270,12 +1271,12 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||||||
|
|
||||||
for (SideLoadedTextTrack track : source.getSideLoadedTextTracks().getTracks()) {
|
for (SideLoadedTextTrack track : source.getSideLoadedTextTracks().getTracks()) {
|
||||||
MediaItem.SubtitleConfiguration subtitleConfiguration = new MediaItem.SubtitleConfiguration.Builder(track.getUri())
|
MediaItem.SubtitleConfiguration subtitleConfiguration = new MediaItem.SubtitleConfiguration.Builder(track.getUri())
|
||||||
.setMimeType(track.getType())
|
.setMimeType(track.getType())
|
||||||
.setLanguage(track.getLanguage())
|
.setLanguage(track.getLanguage())
|
||||||
.setSelectionFlags(C.SELECTION_FLAG_DEFAULT)
|
.setSelectionFlags(C.SELECTION_FLAG_DEFAULT)
|
||||||
.setRoleFlags(C.ROLE_FLAG_SUBTITLE)
|
.setRoleFlags(C.ROLE_FLAG_SUBTITLE)
|
||||||
.setLabel(track.getTitle())
|
.setLabel(track.getTitle())
|
||||||
.build();
|
.build();
|
||||||
subtitleConfigurations.add(subtitleConfiguration);
|
subtitleConfigurations.add(subtitleConfiguration);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1298,7 +1299,7 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||||||
player.removeListener(this);
|
player.removeListener(this);
|
||||||
PictureInPictureUtil.applyAutoEnterEnabled(themedReactContext, pictureInPictureParamsBuilder, false);
|
PictureInPictureUtil.applyAutoEnterEnabled(themedReactContext, pictureInPictureParamsBuilder, false);
|
||||||
if (pipListenerUnsubscribe != null) {
|
if (pipListenerUnsubscribe != null) {
|
||||||
new Handler().post(pipListenerUnsubscribe);
|
pipListenerUnsubscribe.run();
|
||||||
}
|
}
|
||||||
trackSelector = null;
|
trackSelector = null;
|
||||||
|
|
||||||
@@ -2245,7 +2246,9 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||||||
|
|
||||||
public void setEnterPictureInPictureOnLeave(boolean enterPictureInPictureOnLeave) {
|
public void setEnterPictureInPictureOnLeave(boolean enterPictureInPictureOnLeave) {
|
||||||
this.enterPictureInPictureOnLeave = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && enterPictureInPictureOnLeave;
|
this.enterPictureInPictureOnLeave = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && enterPictureInPictureOnLeave;
|
||||||
PictureInPictureUtil.applyAutoEnterEnabled(themedReactContext, pictureInPictureParamsBuilder, this.enterPictureInPictureOnLeave);
|
if (player != null) {
|
||||||
|
PictureInPictureUtil.applyAutoEnterEnabled(themedReactContext, pictureInPictureParamsBuilder, this.enterPictureInPictureOnLeave);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setIsInPictureInPicture(boolean isInPictureInPicture) {
|
protected void setIsInPictureInPicture(boolean isInPictureInPicture) {
|
||||||
|
|||||||
Reference in New Issue
Block a user