Add picture-in-picture support for video (fixes issue #2776)

This commit is contained in:
Marshall Greenblatt 2019-10-15 11:11:59 +00:00
parent 1a661a2d15
commit 066762217f
8 changed files with 95 additions and 11 deletions

View File

@ -949,6 +949,12 @@ static_library("libcef_static") {
deps += [ "//tools/v8_context_snapshot" ] deps += [ "//tools/v8_context_snapshot" ]
} }
if (toolkit_views) {
deps += [
"//ui/views",
]
}
if (use_aura) { if (use_aura) {
sources += [ sources += [
"libcef/browser/native/window_delegate_view.cc", "libcef/browser/native/window_delegate_view.cc",
@ -1039,7 +1045,6 @@ static_library("libcef_static") {
if (toolkit_views) { if (toolkit_views) {
deps += [ deps += [
"//ui/views",
"//ui/views/controls/webview", "//ui/views/controls/webview",
] ]
} }

View File

@ -42,6 +42,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/bind_helpers.h" #include "base/bind_helpers.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "chrome/browser/picture_in_picture/picture_in_picture_window_manager.h"
#include "chrome/browser/printing/print_view_manager.h" #include "chrome/browser/printing/print_view_manager.h"
#include "chrome/browser/spellchecker/spellcheck_factory.h" #include "chrome/browser/spellchecker/spellcheck_factory.h"
#include "chrome/browser/spellchecker/spellcheck_service.h" #include "chrome/browser/spellchecker/spellcheck_service.h"
@ -1503,6 +1504,11 @@ bool CefBrowserHostImpl::IsPrintPreviewSupported() const {
return !IsWindowless(); return !IsWindowless();
} }
bool CefBrowserHostImpl::IsPictureInPictureSupported() const {
// Not currently supported with OSR.
return !IsWindowless();
}
void CefBrowserHostImpl::WindowDestroyed() { void CefBrowserHostImpl::WindowDestroyed() {
CEF_REQUIRE_UIT(); CEF_REQUIRE_UIT();
DCHECK(!window_destroyed_); DCHECK(!window_destroyed_);
@ -2501,6 +2507,23 @@ bool CefBrowserHostImpl::IsNeverVisible(content::WebContents* web_contents) {
return false; return false;
} }
content::PictureInPictureResult CefBrowserHostImpl::EnterPictureInPicture(
content::WebContents* web_contents,
const viz::SurfaceId& surface_id,
const gfx::Size& natural_size) {
if (!IsPictureInPictureSupported()) {
return content::PictureInPictureResult::kNotSupported;
}
return PictureInPictureWindowManager::GetInstance()->EnterPictureInPicture(
web_contents, surface_id, natural_size);
}
void CefBrowserHostImpl::ExitPictureInPicture() {
DCHECK(IsPictureInPictureSupported());
PictureInPictureWindowManager::GetInstance()->ExitPictureInPicture();
}
// content::WebContentsObserver methods. // content::WebContentsObserver methods.
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@ -277,6 +277,9 @@ class CefBrowserHostImpl : public CefBrowserHost,
// Returns true if this browser supports print preview. // Returns true if this browser supports print preview.
bool IsPrintPreviewSupported() const; bool IsPrintPreviewSupported() const;
// Returns true if this browser supports picture-in-picture.
bool IsPictureInPictureSupported() const;
// Called when the OS window hosting the browser is destroyed. // Called when the OS window hosting the browser is destroyed.
void WindowDestroyed(); void WindowDestroyed();
@ -458,6 +461,11 @@ class CefBrowserHostImpl : public CefBrowserHost,
const GURL& security_origin, const GURL& security_origin,
blink::mojom::MediaStreamType type) override; blink::mojom::MediaStreamType type) override;
bool IsNeverVisible(content::WebContents* web_contents) override; bool IsNeverVisible(content::WebContents* web_contents) override;
content::PictureInPictureResult EnterPictureInPicture(
content::WebContents* web_contents,
const viz::SurfaceId& surface_id,
const gfx::Size& natural_size) override;
void ExitPictureInPicture() override;
// content::WebContentsObserver methods. // content::WebContentsObserver methods.
using content::WebContentsObserver::BeforeUnloadFired; using content::WebContentsObserver::BeforeUnloadFired;

View File

@ -46,7 +46,6 @@
#if defined(USE_AURA) #if defined(USE_AURA)
#include "ui/aura/env.h" #include "ui/aura/env.h"
#include "ui/display/screen.h" #include "ui/display/screen.h"
#include "ui/views/test/desktop_test_views_delegate.h"
#include "ui/views/widget/desktop_aura/desktop_screen.h" #include "ui/views/widget/desktop_aura/desktop_screen.h"
#include "ui/wm/core/wm_state.h" #include "ui/wm/core/wm_state.h"
@ -55,6 +54,15 @@
#endif #endif
#endif // defined(USE_AURA) #endif // defined(USE_AURA)
#if defined(TOOLKIT_VIEWS)
#if defined(OS_MACOSX)
#include "chrome/browser/ui/views/chrome_layout_provider.h"
#include "chrome/browser/ui/views/chrome_views_delegate.h"
#else
#include "ui/views/test/desktop_test_views_delegate.h"
#endif
#endif // defined(TOOLKIT_VIEWS)
#if defined(USE_AURA) && defined(OS_LINUX) #if defined(USE_AURA) && defined(OS_LINUX)
#include "ui/base/ime/init/input_method_initializer.h" #include "ui/base/ime/init/input_method_initializer.h"
#endif #endif
@ -91,8 +99,6 @@ void CefBrowserMainParts::ToolkitInitialized() {
#if defined(USE_AURA) #if defined(USE_AURA)
CHECK(aura::Env::GetInstance()); CHECK(aura::Env::GetInstance());
new views::DesktopTestViewsDelegate;
wm_state_.reset(new wm::WMState); wm_state_.reset(new wm::WMState);
#if defined(OS_WIN) #if defined(OS_WIN)
@ -100,6 +106,15 @@ void CefBrowserMainParts::ToolkitInitialized() {
CefContentBrowserClient::Get()->GetResourceDllName()); CefContentBrowserClient::Get()->GetResourceDllName());
#endif #endif
#endif // defined(USE_AURA) #endif // defined(USE_AURA)
#if defined(TOOLKIT_VIEWS)
#if defined(OS_MACOSX)
views_delegate_ = std::make_unique<ChromeViewsDelegate>();
layout_provider_ = ChromeLayoutProvider::CreateLayoutProvider();
#else
views_delegate_ = std::make_unique<views::DesktopTestViewsDelegate>();
#endif
#endif // defined(TOOLKIT_VIEWS)
} }
void CefBrowserMainParts::PreMainMessageLoopStart() { void CefBrowserMainParts::PreMainMessageLoopStart() {
@ -207,8 +222,10 @@ void CefBrowserMainParts::PostDestroyThreads() {
extensions_browser_client_.reset(); extensions_browser_client_.reset();
} }
#if defined(USE_AURA) #if defined(TOOLKIT_VIEWS)
// Delete the DesktopTestViewsDelegate. views_delegate_.reset();
delete views::ViewsDelegate::GetInstance(); #if defined(OS_MACOSX)
layout_provider_.reset();
#endif #endif
#endif // defined(TOOLKIT_VIEWS)
} }

View File

@ -29,6 +29,15 @@ class WMState;
} }
#endif #endif
#if defined(TOOLKIT_VIEWS)
namespace views {
class ViewsDelegate;
#if defined(OS_MACOSX)
class LayoutProvider;
#endif
}
#endif // defined(TOOLKIT_VIEWS)
class CefDevToolsDelegate; class CefDevToolsDelegate;
class CefBrowserMainParts : public content::BrowserMainParts { class CefBrowserMainParts : public content::BrowserMainParts {
@ -85,6 +94,13 @@ class CefBrowserMainParts : public content::BrowserMainParts {
std::unique_ptr<wm::WMState> wm_state_; std::unique_ptr<wm::WMState> wm_state_;
#endif #endif
#if defined(TOOLKIT_VIEWS)
std::unique_ptr<views::ViewsDelegate> views_delegate_;
#if defined(OS_MACOSX)
std::unique_ptr<views::LayoutProvider> layout_provider_;
#endif
#endif // defined(TOOLKIT_VIEWS)
DISALLOW_COPY_AND_ASSIGN(CefBrowserMainParts); DISALLOW_COPY_AND_ASSIGN(CefBrowserMainParts);
}; };

View File

@ -1362,6 +1362,18 @@ bool CefContentBrowserClient::HandleExternalProtocol(
return true; return true;
} }
std::unique_ptr<content::OverlayWindow>
CefContentBrowserClient::CreateWindowForPictureInPicture(
content::PictureInPictureWindowController* controller) {
// Note: content::OverlayWindow::Create() is defined by platform-specific
// implementation in chrome/browser/ui/views. This layering hack, which goes
// through //content and ContentBrowserClient, allows us to work around the
// dependency constraints that disallow directly calling
// chrome/browser/ui/views code either from here or from other code in
// chrome/browser.
return content::OverlayWindow::Create(controller);
}
std::string CefContentBrowserClient::GetProduct() { std::string CefContentBrowserClient::GetProduct() {
// Match the logic in chrome_content_browser_client.cc GetProduct(). // Match the logic in chrome_content_browser_client.cc GetProduct().
return ::GetProduct(); return ::GetProduct();

View File

@ -193,6 +193,8 @@ class CefContentBrowserClient : public content::ContentBrowserClient {
const network::ResourceRequest& request, const network::ResourceRequest& request,
network::mojom::URLLoaderFactoryRequest* factory_request, network::mojom::URLLoaderFactoryRequest* factory_request,
network::mojom::URLLoaderFactoryPtr* out_factory) override; network::mojom::URLLoaderFactoryPtr* out_factory) override;
std::unique_ptr<content::OverlayWindow> CreateWindowForPictureInPicture(
content::PictureInPictureWindowController* controller) override;
std::string GetProduct() override; std::string GetProduct() override;
std::string GetChromeProduct() override; std::string GetChromeProduct() override;

View File

@ -342,12 +342,13 @@ void PopulateWebPreferences(content::RenderViewHost* rvh,
// Set preferences based on the extension. // Set preferences based on the extension.
SetExtensionPrefs(rvh, web); SetExtensionPrefs(rvh, web);
if (browser) {
// Set preferences based on CefBrowserSettings. // Set preferences based on CefBrowserSettings.
if (browser)
SetCefPrefs(browser->settings(), web); SetCefPrefs(browser->settings(), web);
web.picture_in_picture_enabled = browser->IsPictureInPictureSupported();
// Set the background color for the WebView. // Set the background color for the WebView.
if (browser) {
web.base_background_color = browser->GetBackgroundColor(); web.base_background_color = browser->GetBackgroundColor();
} else { } else {
// We don't know for sure that the browser will be windowless but assume // We don't know for sure that the browser will be windowless but assume