From 37a4bb5ba8f130a6eae078beea15e4a2c386dac5 Mon Sep 17 00:00:00 2001 From: Manuel Martin Date: Thu, 4 Jun 2020 18:42:45 +0200 Subject: [PATCH] Update video projection based on current video --- .../ui/widgets/NavigationBarWidget.java | 68 ++++++++++++++++++- .../menus/VideoProjectionMenuWidget.java | 10 +++ .../web_extensions/webcompat_youtube/main.js | 2 + 3 files changed, 78 insertions(+), 2 deletions(-) diff --git a/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/NavigationBarWidget.java b/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/NavigationBarWidget.java index 272f2aa2b..46d9d64a2 100644 --- a/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/NavigationBarWidget.java +++ b/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/NavigationBarWidget.java @@ -15,7 +15,6 @@ import android.util.Log; import android.util.Pair; import android.view.LayoutInflater; -import android.view.MotionEvent; import android.view.View; import android.webkit.URLUtil; import android.widget.EditText; @@ -29,6 +28,7 @@ import org.mozilla.geckoview.GeckoSession; import org.mozilla.geckoview.GeckoSessionSettings; +import org.mozilla.geckoview.MediaElement; import org.mozilla.vrbrowser.R; import org.mozilla.vrbrowser.VRBrowserActivity; import org.mozilla.vrbrowser.VRBrowserApplication; @@ -36,6 +36,7 @@ import org.mozilla.vrbrowser.browser.Media; import org.mozilla.vrbrowser.browser.SessionChangeListener; import org.mozilla.vrbrowser.browser.SettingsStore; +import org.mozilla.vrbrowser.browser.VideoAvailabilityListener; import org.mozilla.vrbrowser.browser.content.TrackingProtectionStore; import org.mozilla.vrbrowser.browser.engine.Session; import org.mozilla.vrbrowser.browser.engine.SessionStore; @@ -74,7 +75,7 @@ public class NavigationBarWidget extends UIWidget implements GeckoSession.Naviga WidgetManagerDelegate.UpdateListener, SessionChangeListener, NavigationURLBar.NavigationURLBarDelegate, VoiceSearchWidget.VoiceSearchDelegate, SharedPreferences.OnSharedPreferenceChangeListener, SuggestionsWidget.URLBarPopupDelegate, - TrayListener, WindowWidget.WindowListener { + TrayListener, WindowWidget.WindowListener, VideoAvailabilityListener { private static final int TAB_ADDED_NOTIFICATION_ID = 0; private static final int TAB_SENT_NOTIFICATION_ID = 1; @@ -557,6 +558,7 @@ private void setUpSession(@NonNull Session aSession) { aSession.addSessionChangeListener(this); aSession.addNavigationListener(this); aSession.addContentListener(this); + aSession.addVideoAvailabilityListener(this); mBinding.navigationBarNavigation.urlBar.setSession(getSession()); } @@ -564,6 +566,7 @@ private void cleanSession(@NonNull Session aSession) { aSession.removeSessionChangeListener(this); aSession.removeNavigationListener(this); aSession.removeContentListener(this); + aSession.removeVideoAvailabilityListener(this); } @Override @@ -821,6 +824,7 @@ private void exitVRVideo() { mProjectionMenu.getPlacement().copyFrom(mProjectionMenuPlacement); mProjectionMenu.getPlacement().composited = composited; mProjectionMenu.setSelectedProjection(VIDEO_PROJECTION_NONE); + mProjectionMenu.resetProjectionOverride(); mWidgetManager.updateWidget(mProjectionMenu); closeFloatingMenus(); mWidgetManager.setControllersVisible(true); @@ -1336,4 +1340,64 @@ public void onAllow() { mQuickPermissionWidget.getPlacement().parentAnchorX = x / getWidth(); mQuickPermissionWidget.show(REQUEST_FOCUS); } + + // VideoAvailabilityListener + + @Override + public void onVideoAvailabilityChanged(@NonNull Media aMedia, boolean aVideoAvailable) { + if (getSession() != null) { + if (aVideoAvailable) { + aMedia.addMediaListener(mMediaDelegate); + + } else { + aMedia.removeMediaListener(mMediaDelegate); + } + } + } + + MediaElement.Delegate mMediaDelegate = new MediaElement.Delegate() { + @Override + public void onPlaybackStateChange(@NonNull MediaElement mediaElement, int state) { + // This should handle the case where a video is being played in full-screen mode and a new + // video is played. That could happen because the user clicks on the previous/next buttons + // of the video controls or because the current video ends an the next video plays in case + // auto-play is enabled. + if (mViewModel.getIsFullscreen().getValue().get()) { + if (state == MediaElement.MEDIA_STATE_PLAYING){ + AtomicBoolean autoEnter = new AtomicBoolean(false); + mAutoSelectedProjection = VideoProjectionMenuWidget.getAutomaticProjection(getSession().getCurrentUri(), autoEnter); + if (mViewModel.getIsInVRVideo().getValue().get()) { + if (mProjectionMenu.isIsProjectionOverridden()) { + // // Fullscreen && VRMode && ProjectionOverridden + mWidgetManager.showVRVideo(mAttachedWindow.getHandle(), mProjectionMenu.getSelectedProjection()); + + } else { + if (mAutoSelectedProjection == VIDEO_PROJECTION_NONE) { + // Fullscreen && VRMode && VIDEO_PROJECTION_NONE + // Exit VR video mode. + exitVRVideo(); + + } else { + // Fullscreen && VRMode && !VIDEO_PROJECTION_NONE + // Update the projection. + mProjectionMenu.setSelectedProjection(mAutoSelectedProjection); + mWidgetManager.showVRVideo(mAttachedWindow.getHandle(), mAutoSelectedProjection); + } + } + + } else { + // Fullscreen && VRMode && !VIDEO_PROJECTION_NONE + // Enter VR Video mode. + if (mAutoSelectedProjection != VIDEO_PROJECTION_NONE) { + enterVRVideo(mAutoSelectedProjection); + } + } + + } else if (state == MediaElement.MEDIA_STATE_ENDED) { + // Clear the menu override flag when the video ends + mProjectionMenu.resetProjectionOverride(); + } + } + } + }; } diff --git a/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/menus/VideoProjectionMenuWidget.java b/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/menus/VideoProjectionMenuWidget.java index 81f89b81a..a2f6f8a67 100644 --- a/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/menus/VideoProjectionMenuWidget.java +++ b/app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/menus/VideoProjectionMenuWidget.java @@ -47,6 +47,7 @@ public ProjectionMenuItem(@VideoProjectionFlags int aProjection, String aString, ArrayList mItems; Delegate mDelegate; @VideoProjectionFlags int mSelectedProjection = VIDEO_PROJECTION_3D_SIDE_BY_SIDE; + boolean mIsProjectionOverridden = false; public VideoProjectionMenuWidget(Context aContext) { super(aContext, R.layout.menu); @@ -118,6 +119,7 @@ private void createMenuItems() { private void handleClick(@VideoProjectionFlags int aVideoProjection) { mSelectedProjection = aVideoProjection; + mIsProjectionOverridden = true; if (mDelegate != null) { mDelegate.onVideoProjectionClick(aVideoProjection); } @@ -174,6 +176,14 @@ public void setSelectedProjection(@VideoProjectionFlags int aProjection) { return VIDEO_PROJECTION_NONE; } + public void resetProjectionOverride () { + mIsProjectionOverridden = false; + } + + public boolean isIsProjectionOverridden() { + return mIsProjectionOverridden; + } + @Override public void onGlobalFocusChanged(View oldFocus, View newFocus) { if (!ViewUtils.isEqualOrChildrenOf(this, newFocus) && isVisible()) { diff --git a/app/src/main/assets/web_extensions/webcompat_youtube/main.js b/app/src/main/assets/web_extensions/webcompat_youtube/main.js index 93622aaa2..6d0e5d15c 100644 --- a/app/src/main/assets/web_extensions/webcompat_youtube/main.js +++ b/app/src/main/assets/web_extensions/webcompat_youtube/main.js @@ -118,6 +118,8 @@ class YoutubeExtension { this.updateVideoStyle(); logDebug(`Video projection set to: ${qs.get(VIDEO_PROJECTION_PARAM)}`); } else { + qs.delete('mozVideoProjection'); + this.updateURL(qs); logDebug(`Video is flat, no projection selected`); } }