Skip to content
This repository has been archived by the owner on Jul 22, 2024. It is now read-only.

Fixes #2545 Multiple media elements handling #3201

Merged
merged 2 commits into from
Apr 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ public class Media implements MediaElement.Delegate {
private MediaElement mMedia;
private CopyOnWriteArrayList<MediaElement.Delegate> mMediaListeners;
private ResizeDelegate mResizeDelegate;
private long mLastStateUpdate;

public Media(@NonNull MediaElement aMediaElement) {
mMedia = aMediaElement;
mMediaListeners = new CopyOnWriteArrayList<>();
aMediaElement.setDelegate(this);
mLastStateUpdate = 0;
}

public void addMediaListener(MediaElement.Delegate aListener) {
Expand Down Expand Up @@ -113,6 +115,10 @@ public void setMuted(boolean aIsMuted) {
mMedia.setMuted(aIsMuted);
}

public long getLastStateUpdate() {
return mLastStateUpdate;
}

public void unload() {
mIsUnloaded = true;
mMediaListeners.clear();
Expand Down Expand Up @@ -149,6 +155,7 @@ public void onPlaybackStateChange(MediaElement mediaElement, int playbackState)
mPlaying = false;
mIsUnloaded = true;
}
mLastStateUpdate = System.currentTimeMillis();
mMediaListeners.forEach(listener -> listener.onPlaybackStateChange(mediaElement, playbackState));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.mozilla.vrbrowser.browser;

import androidx.annotation.NonNull;

public interface VideoAvailabilityListener {
default void onVideoAvailabilityChanged(boolean aVideosAvailable) {}
default void onVideoAvailabilityChanged(@NonNull Media media, boolean aVideoAvailable) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,12 @@

import java.net.URI;
import java.net.URISyntaxException;
import java.util.Comparator;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Predicate;

import static java.util.Objects.requireNonNull;
import static org.mozilla.vrbrowser.utils.ServoUtils.createServoSession;
Expand Down Expand Up @@ -247,7 +249,9 @@ private void dumpState(GeckoSession.ContentDelegate aListener) {
}

private void dumpState(VideoAvailabilityListener aListener) {
aListener.onVideoAvailabilityChanged(mState.mMediaElements != null && mState.mMediaElements.size() > 0);
mState.mMediaElements.forEach(element -> {
aListener.onVideoAvailabilityChanged(element,true);
});
}

private void dumpState(WebXRStateChangedListener aListener) {
Expand Down Expand Up @@ -690,6 +694,7 @@ public boolean isFirstContentfulPaint() {
return mFirstContentfulPaint;
}

@Nullable
public Media getFullScreenVideo() {
for (Media media: mState.mMediaElements) {
if (media.isFullscreen()) {
Expand All @@ -703,6 +708,19 @@ public Media getFullScreenVideo() {
return null;
}

@Nullable
public Media getActiveVideo() {
for (Media media: mState.mMediaElements) {
if (media.isFullscreen()) {
return media;
}
}
return mState.mMediaElements.stream()
.sorted((o1, o2) -> (int)o2.getLastStateUpdate() - (int)o1.getLastStateUpdate())
.filter(Media::isPlayed)
.findFirst().orElse(null);
}

public boolean isInputActive() {
return mState.mIsInputActive;
}
Expand Down Expand Up @@ -1448,7 +1466,7 @@ public void onMediaAdd(@NonNull GeckoSession aSession, @NonNull MediaElement ele
mState.mMediaElements.add(media);

for (VideoAvailabilityListener listener: mVideoAvailabilityListeners) {
listener.onVideoAvailabilityChanged(true);
listener.onVideoAvailabilityChanged(media, true);
}
}

Expand All @@ -1462,10 +1480,8 @@ public void onMediaRemove(@NonNull GeckoSession aSession, @NonNull MediaElement
if (media.getMediaElement() == element) {
media.unload();
mState.mMediaElements.remove(i);
if (mState.mMediaElements.size() == 0) {
for (VideoAvailabilityListener listener: mVideoAvailabilityListeners) {
listener.onVideoAvailabilityChanged(false);
}
for (VideoAvailabilityListener listener: mVideoAvailabilityListeners) {
listener.onVideoAvailabilityChanged(media, false);
}
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1668,37 +1668,29 @@ public void onExternalResponse(@NonNull GeckoSession geckoSession, @NonNull Geck

// VideoAvailabilityListener

private Media mMedia;

@Override
public void onVideoAvailabilityChanged(boolean aVideosAvailable) {
public void onVideoAvailabilityChanged(@NonNull Media aMedia, boolean aVideoAvailable) {
boolean mediaAvailable;
if (mSession != null) {
if (mMedia != null) {
mMedia.removeMediaListener(mMediaDelegate);
}

mMedia = mSession.getFullScreenVideo();
if (aVideosAvailable && mMedia != null) {
mMedia.addMediaListener(mMediaDelegate);
mediaAvailable = true;
if (aVideoAvailable) {
aMedia.addMediaListener(mMediaDelegate);

} else {
mediaAvailable = false;
aMedia.removeMediaListener(mMediaDelegate);
}
mediaAvailable = mSession.getActiveVideo() != null;

} else {
mediaAvailable = false;
}

if (mediaAvailable) {
if (mSession.getFullScreenVideo().isPlayed()) {
mViewModel.setIsMediaAvailable(true);
if (mSession.getActiveVideo().isPlayed()) {
mViewModel.setIsMediaPlaying(true);
}
mViewModel.setIsMediaAvailable(true);

} else {
mMedia = null;
mViewModel.setIsMediaAvailable(false);
mViewModel.setIsMediaPlaying(false);
}
Expand Down Expand Up @@ -1754,6 +1746,8 @@ public void captureImage() {
public void onLocationChange(@NonNull GeckoSession session, @Nullable String url) {
mViewModel.setUrl(url);
mViewModel.setIsDrmUsed(false);
mViewModel.setIsMediaAvailable(false);
mViewModel.setIsMediaPlaying(false);

if (StringUtils.isEmpty(url)) {
mViewModel.setIsBookmarked(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1085,17 +1085,21 @@ public void onTitleClicked(@NonNull TitleBarWidget titleBar) {
@Override
public void onMediaPlayClicked(@NonNull TitleBarWidget titleBar) {
for (WindowWidget window : getCurrentWindows()) {
if (window.getTitleBar() == titleBar) {
window.getSession().getFullScreenVideo().play();
if (window.getTitleBar() == titleBar &&
window.getSession() != null &&
window.getSession().getActiveVideo() != null) {
window.getSession().getActiveVideo().play();
}
}
}

@Override
public void onMediaPauseClicked(@NonNull TitleBarWidget titleBar) {
for (WindowWidget window : getCurrentWindows()) {
if (window.getTitleBar() == titleBar) {
window.getSession().getFullScreenVideo().pause();
if (window.getTitleBar() == titleBar &&
window.getSession() != null &&
window.getSession().getActiveVideo() != null) {
window.getSession().getActiveVideo().pause();
}
}
}
Expand Down