PIP20: add a new DocumentOverlayWindowViews subtype
This is part of a series for the new picture-in-picture v2 feature
that allows always-on-top windows with arbitrary content. This CL
adds new subclasses of OverlayWindowViews and
PictureInPictureWindowController that manage this content.
Currently the UI elements are still the same as for video PiP, they
still need to be adjusted in followup CLs depending on the intended UX.
Explainer: https://github.com/steimelchrome/document-pip-explainer/blob/main/explainer.md
This is based on François Beaufort's earlier experiment:
https://chromium-review.googlesource.com/c/chromium/src/+/2797191
Requires command line flags:
--enable-features=PictureInPictureV2
--enable-blink-features=PictureInPictureV2
Optional command line flag (to activate reusable media player as used
by liberato@'s experimental extension):
--enable-features=PictureInPictureV2,ReuseMediaPlayer
Change-Id: I28fe921d62eaa6366e7a3fa1a1b9dc1df7c759f2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3252789
Reviewed-by: Fr <[email protected]>
Reviewed-by: Mark Foltz <[email protected]>
Reviewed-by: Tommy Steimel <[email protected]>
Reviewed-by: danakj <[email protected]>
Reviewed-by: Wez <[email protected]>
Reviewed-by: Robert Flack <[email protected]>
Reviewed-by: Avi Drissman <[email protected]>
Commit-Queue: Klaus Weidner <[email protected]>
Cr-Commit-Position: refs/heads/main@{#968570}
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn
index 11749db..15a9166 100644
--- a/content/public/browser/BUILD.gn
+++ b/content/public/browser/BUILD.gn
@@ -142,6 +142,7 @@
"devtools_permission_overrides.h",
"devtools_socket_factory.h",
"disallow_activation_reason.h",
+ "document_picture_in_picture_window_controller.h",
"document_ref.cc",
"document_ref.h",
"document_service.h",
@@ -391,6 +392,7 @@
"video_capture_device_launcher.cc",
"video_capture_device_launcher.h",
"video_capture_service.h",
+ "video_picture_in_picture_window_controller.h",
"visibility.h",
"vpn_service_proxy.h",
"weak_document_ptr.cc",
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index b771204..2de50e2 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -1013,9 +1013,15 @@
return true;
}
-std::unique_ptr<OverlayWindow>
-ContentBrowserClient::CreateWindowForPictureInPicture(
- PictureInPictureWindowController* controller) {
+std::unique_ptr<VideoOverlayWindow>
+ContentBrowserClient::CreateWindowForVideoPictureInPicture(
+ VideoPictureInPictureWindowController* controller) {
+ return nullptr;
+}
+
+std::unique_ptr<DocumentOverlayWindow>
+ContentBrowserClient::CreateWindowForDocumentPictureInPicture(
+ DocumentPictureInPictureWindowController* controller) {
return nullptr;
}
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index 44bd446..68017b5 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -209,6 +209,8 @@
class ClientCertificateDelegate;
class ControllerPresentationServiceDelegate;
class DevToolsManagerDelegate;
+class DocumentOverlayWindow;
+class DocumentPictureInPictureWindowController;
class FeatureObserverClient;
class FontAccessDelegate;
class HidDelegate;
@@ -218,8 +220,6 @@
class NavigationHandle;
class NavigationThrottle;
class NavigationUIData;
-class OverlayWindow;
-class PictureInPictureWindowController;
class QuotaPermissionContext;
class ReceiverPresentationServiceDelegate;
class RenderFrameHost;
@@ -232,6 +232,8 @@
class TracingDelegate;
class TtsPlatform;
class URLLoaderRequestInterceptor;
+class VideoOverlayWindow;
+class VideoPictureInPictureWindowController;
class VpnServiceProxy;
class WebAuthenticationDelegate;
class WebContents;
@@ -1823,13 +1825,18 @@
RenderFrameHost* initiator_document,
mojo::PendingRemote<network::mojom::URLLoaderFactory>* out_factory);
- // Creates an OverlayWindow to be used for Picture-in-Picture. This window
- // will house the content shown when in Picture-in-Picture mode. This will
- // return a new OverlayWindow.
+ // Creates an OverlayWindow to be used for video or document
+ // Picture-in-Picture respectively. This window will house the content shown
+ // when in Picture-in-Picture mode. This will return a new OverlayWindow.
+ //
// May return nullptr if embedder does not support this functionality. The
// default implementation provides nullptr OverlayWindow.
- virtual std::unique_ptr<OverlayWindow> CreateWindowForPictureInPicture(
- PictureInPictureWindowController* controller);
+ virtual std::unique_ptr<VideoOverlayWindow>
+ CreateWindowForVideoPictureInPicture(
+ VideoPictureInPictureWindowController* controller);
+ virtual std::unique_ptr<DocumentOverlayWindow>
+ CreateWindowForDocumentPictureInPicture(
+ DocumentPictureInPictureWindowController* controller);
// Registers the watcher to observe updates in RendererPreferences.
virtual void RegisterRendererPreferenceWatcher(
diff --git a/content/public/browser/document_picture_in_picture_window_controller.h b/content/public/browser/document_picture_in_picture_window_controller.h
new file mode 100644
index 0000000..9846e94
--- /dev/null
+++ b/content/public/browser/document_picture_in_picture_window_controller.h
@@ -0,0 +1,32 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_BROWSER_DOCUMENT_PICTURE_IN_PICTURE_WINDOW_CONTROLLER_H_
+#define CONTENT_PUBLIC_BROWSER_DOCUMENT_PICTURE_IN_PICTURE_WINDOW_CONTROLLER_H_
+
+#include "content/common/content_export.h"
+#include "content/public/browser/picture_in_picture_window_controller.h"
+
+namespace content {
+class WebContents;
+
+class DocumentPictureInPictureWindowController
+ : public PictureInPictureWindowController {
+ public:
+ // Takes ownership of the WebContents for Document Picture-in-Picture.
+ virtual void SetChildWebContents(
+ std::unique_ptr<WebContents> child_contents) = 0;
+
+ // Returns the child WebContents for DocumentPip
+ virtual WebContents* GetChildWebContents() = 0;
+
+ protected:
+ // Use PictureInPictureWindowController::GetOrCreateForWebContents() to
+ // create an instance.
+ DocumentPictureInPictureWindowController() = default;
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_BROWSER_DOCUMENT_PICTURE_IN_PICTURE_WINDOW_CONTROLLER_H_
diff --git a/content/public/browser/overlay_window.h b/content/public/browser/overlay_window.h
index adb62a4e..be255528 100644
--- a/content/public/browser/overlay_window.h
+++ b/content/public/browser/overlay_window.h
@@ -24,19 +24,14 @@
namespace content {
-class PictureInPictureWindowController;
+class DocumentPictureInPictureWindowController;
+class VideoPictureInPictureWindowController;
// This window will always float above other windows. The intention is to show
// content perpetually while the user is still interacting with the other
// browser windows.
class OverlayWindow {
public:
- enum PlaybackState {
- kPlaying = 0,
- kPaused,
- kEndOfVideo,
- };
-
OverlayWindow() = default;
OverlayWindow(const OverlayWindow&) = delete;
@@ -44,11 +39,6 @@
virtual ~OverlayWindow() = default;
- // Returns a created OverlayWindow. This is defined in the platform-specific
- // implementation for the class.
- static std::unique_ptr<OverlayWindow> Create(
- PictureInPictureWindowController* controller);
-
virtual bool IsActive() = 0;
virtual void Close() = 0;
virtual void ShowInactive() = 0;
@@ -57,7 +47,25 @@
virtual bool IsAlwaysOnTop() = 0;
// Retrieves the window's current bounds, including its window.
virtual gfx::Rect GetBounds() = 0;
- virtual void UpdateVideoSize(const gfx::Size& natural_size) = 0;
+ // Updates the content (video or document) size.
+ virtual void UpdateNaturalSize(const gfx::Size& natural_size) = 0;
+};
+
+class VideoOverlayWindow : public OverlayWindow {
+ public:
+ enum PlaybackState {
+ kPlaying = 0,
+ kPaused,
+ kEndOfVideo,
+ };
+
+ VideoOverlayWindow() = default;
+
+ // Returns a created VideoOverlayWindow. This is defined in the
+ // platform-specific implementation for the class.
+ static std::unique_ptr<VideoOverlayWindow> Create(
+ VideoPictureInPictureWindowController* controller);
+
virtual void SetPlaybackState(PlaybackState playback_state) = 0;
virtual void SetPlayPauseButtonVisibility(bool is_visible) = 0;
virtual void SetSkipAdButtonVisibility(bool is_visible) = 0;
@@ -72,6 +80,16 @@
virtual cc::Layer* GetLayerForTesting() = 0;
};
+class DocumentOverlayWindow : public OverlayWindow {
+ public:
+ DocumentOverlayWindow() = default;
+
+ // Returns a created DocumentOverlayWindow. This is defined in the
+ // platform-specific implementation for the class.
+ static std::unique_ptr<DocumentOverlayWindow> Create(
+ DocumentPictureInPictureWindowController* controller);
+};
+
} // namespace content
#endif // CONTENT_PUBLIC_BROWSER_OVERLAY_WINDOW_H_
diff --git a/content/public/browser/picture_in_picture_window_controller.h b/content/public/browser/picture_in_picture_window_controller.h
index d894047..03a3a1b 100644
--- a/content/public/browser/picture_in_picture_window_controller.h
+++ b/content/public/browser/picture_in_picture_window_controller.h
@@ -8,8 +8,9 @@
#include "content/common/content_export.h"
namespace content {
-class OverlayWindow;
class WebContents;
+class DocumentPictureInPictureWindowController;
+class VideoPictureInPictureWindowController;
// Interface for Picture in Picture window controllers. This is currently tied
// to a WebContents |web_contents| and created when a Picture in Picture window
@@ -17,11 +18,15 @@
// WebContents.
class PictureInPictureWindowController {
public:
- // Gets a reference to the controller associated with |web_contents| and
- // creates one if it does not exist. The returned pointer is guaranteed to be
- // non-null.
- CONTENT_EXPORT static PictureInPictureWindowController*
- GetOrCreateForWebContents(WebContents* web_contents);
+ // Gets a reference to the controller of the appropriate type associated with
+ // |web_contents| and creates one if it does not exist. If there is an
+ // existing controller, it is reused if it's of the correct type, but is
+ // recreated if the existing instance was for a different type. The returned
+ // pointer is guaranteed to be non-null.
+ CONTENT_EXPORT static VideoPictureInPictureWindowController*
+ GetOrCreateVideoPictureInPictureController(WebContents* web_contents);
+ CONTENT_EXPORT static DocumentPictureInPictureWindowController*
+ GetOrCreateDocumentPictureInPictureController(WebContents* web_contents);
virtual ~PictureInPictureWindowController() = default;
@@ -43,34 +48,8 @@
// window was requested to be closed and destroyed by the system.
virtual void OnWindowDestroyed(bool should_pause_video) = 0;
- virtual OverlayWindow* GetWindowForTesting() = 0;
- virtual void UpdateLayerBounds() = 0;
- virtual bool IsPlayerActive() = 0;
virtual WebContents* GetWebContents() = 0;
- // Called when the user interacts with the "Skip Ad" control.
- virtual void SkipAd() = 0;
-
- // Called when the user interacts with the "Next Track" control.
- virtual void NextTrack() = 0;
-
- // Called when the user interacts with the "Previous Track" control.
- virtual void PreviousTrack() = 0;
-
- // Commands.
- // Returns true if the player is active (i.e. currently playing) after this
- // call.
- virtual bool TogglePlayPause() = 0;
-
- // Called when the user interacts with the "Toggle Microphone" control.
- virtual void ToggleMicrophone() = 0;
-
- // Called when the user interacts with the "Toggle Camera" control.
- virtual void ToggleCamera() = 0;
-
- // Called when the user interacts with the "Hang Up" control.
- virtual void HangUp() = 0;
-
protected:
// Use PictureInPictureWindowController::GetOrCreateForWebContents() to
// create an instance.
diff --git a/content/public/browser/video_picture_in_picture_window_controller.h b/content/public/browser/video_picture_in_picture_window_controller.h
new file mode 100644
index 0000000..3d592a1
--- /dev/null
+++ b/content/public/browser/video_picture_in_picture_window_controller.h
@@ -0,0 +1,52 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_BROWSER_VIDEO_PICTURE_IN_PICTURE_WINDOW_CONTROLLER_H_
+#define CONTENT_PUBLIC_BROWSER_VIDEO_PICTURE_IN_PICTURE_WINDOW_CONTROLLER_H_
+
+#include "content/common/content_export.h"
+#include "content/public/browser/picture_in_picture_window_controller.h"
+
+namespace content {
+class VideoOverlayWindow;
+
+class VideoPictureInPictureWindowController
+ : public PictureInPictureWindowController {
+ public:
+ virtual VideoOverlayWindow* GetWindowForTesting() = 0;
+ virtual void UpdateLayerBounds() = 0;
+ virtual bool IsPlayerActive() = 0;
+
+ // Called when the user interacts with the "Skip Ad" control.
+ virtual void SkipAd() = 0;
+
+ // Called when the user interacts with the "Next Track" control.
+ virtual void NextTrack() = 0;
+
+ // Called when the user interacts with the "Previous Track" control.
+ virtual void PreviousTrack() = 0;
+
+ // Commands.
+ // Returns true if the player is active (i.e. currently playing) after this
+ // call.
+ virtual bool TogglePlayPause() = 0;
+
+ // Called when the user interacts with the "Toggle Microphone" control.
+ virtual void ToggleMicrophone() = 0;
+
+ // Called when the user interacts with the "Toggle Camera" control.
+ virtual void ToggleCamera() = 0;
+
+ // Called when the user interacts with the "Hang Up" control.
+ virtual void HangUp() = 0;
+
+ protected:
+ // Use PictureInPictureWindowController::GetOrCreateForWebContents() to
+ // create an instance.
+ VideoPictureInPictureWindowController() = default;
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_BROWSER_VIDEO_PICTURE_IN_PICTURE_WINDOW_CONTROLLER_H_
diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h
index 0a81d401..ad5c139 100644
--- a/content/public/browser/web_contents.h
+++ b/content/public/browser/web_contents.h
@@ -710,6 +710,9 @@
// Indicates whether a video is in Picture-in-Picture for |this|.
virtual bool HasPictureInPictureVideo() = 0;
+ // Indicates whether a document is in Picture-in-Picture for |this|.
+ virtual bool HasPictureInPictureDocument() = 0;
+
// Indicates whether this tab should be considered crashed. This becomes false
// again when the renderer process is recreated after a crash in order to
// recreate the main frame.