Commit e031e566 authored by François Beaufort's avatar François Beaufort Committed by Commit Bot

Enable Picture-in-Picture for chrome apps.

This CL enables Picture-in-Picture in chrome apps by implementing
EnterPictureInPicture and ExitPictureInPicture in AppDelegate.

Bug: 863309
Change-Id: Ib35e83b03373abe864b3a0674ab1e0b341ce291b
Reviewed-on: https://chromium-review.googlesource.com/1156513
Commit-Queue: François Beaufort <beaufort.francois@gmail.com>
Reviewed-by: default avatarJochen Eisinger <jochen@chromium.org>
Reviewed-by: default avatarDevlin <rdevlin.cronin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#580497}
parent a445460b
......@@ -44,6 +44,7 @@
#include "components/web_modal/web_contents_modal_dialog_manager.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/host_zoom_map.h"
#include "content/public/browser/picture_in_picture_window_controller.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/test/browser_test_utils.h"
......@@ -1400,4 +1401,28 @@ IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, NewWindowAboutBlank) {
ASSERT_TRUE(RunPlatformAppTest("platform_apps/new_window_about_blank"));
}
// Tests that platform apps can enter and exit Picture-in-Picture.
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, PictureInPicture) {
LoadAndLaunchPlatformApp("picture_in_picture", "Launched");
WebContents* web_contents = GetFirstAppWindowWebContents();
ASSERT_TRUE(web_contents);
content::PictureInPictureWindowController* window_controller =
content::PictureInPictureWindowController::GetOrCreateForWebContents(
web_contents);
ASSERT_TRUE(window_controller->GetWindowForTesting());
EXPECT_FALSE(window_controller->GetWindowForTesting()->IsVisible());
bool result = false;
ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
web_contents, "enterPictureInPicture();", &result));
EXPECT_TRUE(result);
EXPECT_TRUE(window_controller->GetWindowForTesting()->IsVisible());
ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
web_contents, "exitPictureInPicture();", &result));
EXPECT_TRUE(result);
EXPECT_FALSE(window_controller->GetWindowForTesting()->IsVisible());
}
} // namespace extensions
......@@ -16,6 +16,7 @@
#include "chrome/browser/favicon/favicon_utils.h"
#include "chrome/browser/file_select_helper.h"
#include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h"
#include "chrome/browser/picture_in_picture/picture_in_picture_window_manager.h"
#include "chrome/browser/platform_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/shell_integration.h"
......@@ -366,6 +367,18 @@ bool ChromeAppDelegate::TakeFocus(content::WebContents* web_contents,
#endif
}
gfx::Size ChromeAppDelegate::EnterPictureInPicture(
content::WebContents* web_contents,
const viz::SurfaceId& surface_id,
const gfx::Size& natural_size) {
return PictureInPictureWindowManager::GetInstance()->EnterPictureInPicture(
web_contents, surface_id, natural_size);
}
void ChromeAppDelegate::ExitPictureInPicture() {
PictureInPictureWindowManager::GetInstance()->ExitPictureInPicture();
}
void ChromeAppDelegate::Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
......
......@@ -74,6 +74,10 @@ class ChromeAppDelegate : public extensions::AppDelegate,
void OnHide() override;
void OnShow() override;
bool TakeFocus(content::WebContents* web_contents, bool reverse) override;
gfx::Size EnterPictureInPicture(content::WebContents* web_contents,
const viz::SurfaceId& surface_id,
const gfx::Size& natural_size) override;
void ExitPictureInPicture() override;
// content::NotificationObserver:
void Observe(int type,
......
<!--
* Copyright 2018 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.
-->
<html>
<body>
<script src="main.js"></script>
</body>
</html>
// Copyright 2018 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.
const video = document.createElement('video');
video.src = chrome.runtime.getURL('bear.webm');
video.load();
video.addEventListener('loadedmetadata', function() {
chrome.test.sendMessage('Launched');
});
function enterPictureInPicture() {
video.requestPictureInPicture()
.catch(error => { window.domAutomationController.send(false); });
video.addEventListener('enterpictureinpicture', function(pipWindow) {
window.domAutomationController.send(
pipWindow.width != 0 && pipWindow.height != 0);
}, { once: true });
}
function exitPictureInPicture() {
document.exitPictureInPicture()
.catch(error => { window.domAutomationController.send(false); });
video.addEventListener('leavepictureinpicture', function() {
window.domAutomationController.send(true);
}, { once: true });
}
{
"name": "Platform App Test: Picture-in-Picture",
"manifest_version": 2,
"version": "1",
"app": {
"background": {
"scripts": ["test.js"]
}
}
}
// Copyright 2018 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.
chrome.app.runtime.onLaunched.addListener(function() {
chrome.app.window.create('main.html', {}, function () {});
});
......@@ -25,6 +25,10 @@ class Rect;
class Size;
}
namespace viz {
class SurfaceId;
}
namespace extensions {
class Extension;
......@@ -89,6 +93,17 @@ class AppDelegate {
// a chance to handle the focus change.
// Return whether focus has been handled.
virtual bool TakeFocus(content::WebContents* web_contents, bool reverse) = 0;
// Notifies the Picture-in-Picture controller that there is a new player
// entering Picture-in-Picture.
// Returns the size of the Picture-in-Picture window.
virtual gfx::Size EnterPictureInPicture(content::WebContents* web_contents,
const viz::SurfaceId& surface_id,
const gfx::Size& natural_size) = 0;
// Updates the Picture-in-Picture controller with a signal that
// Picture-in-Picture mode has ended.
virtual void ExitPictureInPicture() = 0;
};
} // namespace extensions
......
......@@ -438,6 +438,16 @@ bool AppWindow::TakeFocus(WebContents* source, bool reverse) {
return app_delegate_->TakeFocus(source, reverse);
}
gfx::Size AppWindow::EnterPictureInPicture(const viz::SurfaceId& surface_id,
const gfx::Size& natural_size) {
return app_delegate_->EnterPictureInPicture(web_contents(), surface_id,
natural_size);
}
void AppWindow::ExitPictureInPicture() {
app_delegate_->ExitPictureInPicture();
}
bool AppWindow::OnMessageReceived(const IPC::Message& message,
content::RenderFrameHost* render_frame_host) {
bool handled = true;
......
......@@ -444,6 +444,9 @@ class AppWindow : public content::WebContentsDelegate,
content::RenderFrameHost* frame,
const content::BluetoothChooser::EventHandler& event_handler) override;
bool TakeFocus(content::WebContents* source, bool reverse) override;
gfx::Size EnterPictureInPicture(const viz::SurfaceId& surface_id,
const gfx::Size& natural_size) override;
void ExitPictureInPicture() override;
// content::WebContentsObserver implementation.
bool OnMessageReceived(const IPC::Message& message,
......
......@@ -106,4 +106,16 @@ bool ShellAppDelegate::TakeFocus(content::WebContents* web_contents,
return false;
}
gfx::Size ShellAppDelegate::EnterPictureInPicture(
content::WebContents* web_contents,
const viz::SurfaceId& surface_id,
const gfx::Size& natural_size) {
NOTREACHED();
return gfx::Size();
}
void ShellAppDelegate::ExitPictureInPicture() {
NOTREACHED();
}
} // namespace extensions
......@@ -52,6 +52,10 @@ class ShellAppDelegate : public AppDelegate {
void OnHide() override {}
void OnShow() override {}
bool TakeFocus(content::WebContents* web_contents, bool reverse) override;
gfx::Size EnterPictureInPicture(content::WebContents* web_contents,
const viz::SurfaceId& surface_id,
const gfx::Size& natural_size) override;
void ExitPictureInPicture() override;
private:
DISALLOW_COPY_AND_ASSIGN(ShellAppDelegate);
......
......@@ -289,6 +289,7 @@
# https://crbug.com/827327
-PictureInPictureWindowControllerBrowserTest.*
-ControlPictureInPictureWindowControllerBrowserTest.*
-PlatformAppBrowserTest.PictureInPicture
# These started failing with the switch to ws2.
# https:://crbug.com/855767
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment