Implementation of chrome://cast WebUI.
Spec: go/cast-setup-chrome-webui
BUG=611758
CQ_INCLUDE_TRYBOTS=tryserver.chromium.linux:closure_compilation
Review-Url: https://codereview.chromium.org/1820023002
Cr-Commit-Position: refs/heads/master@{#396501}
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index 297fcc2..6e840445 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -518,6 +518,12 @@
<if expr="enable_media_router">
<part file="media_router_resources.grdp" />
</if>
+ <if expr="enable_media_router and (chromeos or is_win or is_macosx)">
+ <include name="IDR_CAST_HTML" file="resources\cast\cast.html" type="BINDATA" />
+ <include name="IDR_CAST_CSS" file="resources\cast\cast.css" type="BINDATA" />
+ <include name="IDR_CAST_JS" file="resources\cast\cast.js" type="BINDATA" />
+ <include name="IDR_CAST_FAVICON" file="resources\cast\cast_favicon.ico" type="BINDATA" />
+ </if>
<if expr="not is_android and not is_ios and not chromeos">
<include name="IDR_IME_WINDOW_CLOSE" file="resources\input_ime\ime_window_close.png" type="BINDATA" />
<include name="IDR_IME_WINDOW_CLOSE_C" file="resources\input_ime\ime_window_close_click.png" type="BINDATA" />
diff --git a/chrome/browser/resources/cast/OWNERS b/chrome/browser/resources/cast/OWNERS
new file mode 100644
index 0000000..5b34f4712
--- /dev/null
+++ b/chrome/browser/resources/cast/OWNERS
@@ -0,0 +1 @@
+sheretov@chromium.org
diff --git a/chrome/browser/resources/cast/cast.css b/chrome/browser/resources/cast/cast.css
new file mode 100644
index 0000000..5193f40
--- /dev/null
+++ b/chrome/browser/resources/cast/cast.css
@@ -0,0 +1,18 @@
+/* Copyright 2016 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. */
+
+body,
+extensionview,
+html {
+ border: 0;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+ width: 100%;
+}
+
+extensionview {
+ overflow: hidden;
+ position: absolute;
+}
diff --git a/chrome/browser/resources/cast/cast.html b/chrome/browser/resources/cast/cast.html
new file mode 100644
index 0000000..e7afdd9
--- /dev/null
+++ b/chrome/browser/resources/cast/cast.html
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML>
+<html i18n-values="dir:textdirection;lang:language">
+<head>
+ <meta charset="utf-8">
+ <title>Google Cast</title>
+ <link rel="stylesheet" href="cast.css">
+ <link rel="shortcut icon" href="cast_favicon.ico">
+ <script src="chrome://resources/js/load_time_data.js"></script>
+ <script src="strings.js"></script>
+ <script src="cast.js"></script>
+</head>
+<body>
+ <extensionview></extensionview>
+</body>
+</html>
diff --git a/chrome/browser/resources/cast/cast.js b/chrome/browser/resources/cast/cast.js
new file mode 100644
index 0000000..e7bd2059
--- /dev/null
+++ b/chrome/browser/resources/cast/cast.js
@@ -0,0 +1,40 @@
+// Copyright 2016 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.
+
+window.addEventListener('load', function init() {
+ var extensionView = document.querySelector('extensionview');
+
+ /**
+ * @param {string} str
+ * @return {!Array<string>}
+ */
+ var splitUrlOnHash = function(str) {
+ str = str || '';
+ var pos = str.indexOf('#');
+ return (pos !== -1) ? [str.substr(0, pos), str.substr(pos + 1)] : [str, ''];
+ };
+
+ new MutationObserver(function() {
+ var newHash = splitUrlOnHash(extensionView.getAttribute('src'))[1];
+ var oldHash = window.location.hash.substr(1);
+ if (newHash !== oldHash) {
+ window.location.hash = newHash;
+ }
+ }).observe(extensionView, {
+ attributes: true
+ });
+
+ window.addEventListener('hashchange', function() {
+ var newHash = window.location.hash.substr(1);
+ var extensionViewSrcParts = splitUrlOnHash(
+ extensionView.getAttribute('src'));
+ if (newHash !== extensionViewSrcParts[1]) {
+ extensionView.load(extensionViewSrcParts[0] + '#' + newHash);
+ }
+ });
+
+ extensionView.load('chrome-extension://' +
+ loadTimeData.getString('extensionId') + '/cast_setup/devices.html');
+});
+
diff --git a/chrome/browser/resources/cast/cast_favicon.ico b/chrome/browser/resources/cast/cast_favicon.ico
new file mode 100644
index 0000000..7f72553
--- /dev/null
+++ b/chrome/browser/resources/cast/cast_favicon.ico
Binary files differ
diff --git a/chrome/browser/ui/webui/cast/OWNERS b/chrome/browser/ui/webui/cast/OWNERS
new file mode 100644
index 0000000..5b34f4712
--- /dev/null
+++ b/chrome/browser/ui/webui/cast/OWNERS
@@ -0,0 +1 @@
+sheretov@chromium.org
diff --git a/chrome/browser/ui/webui/cast/cast_ui.cc b/chrome/browser/ui/webui/cast/cast_ui.cc
new file mode 100644
index 0000000..3b39ba6
--- /dev/null
+++ b/chrome/browser/ui/webui/cast/cast_ui.cc
@@ -0,0 +1,42 @@
+// Copyright 2016 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.
+
+#include "chrome/browser/ui/webui/cast/cast_ui.h"
+
+#include "chrome/browser/media/router/media_router_factory.h"
+#include "chrome/browser/media/router/mojo/media_router_mojo_impl.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/url_constants.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_ui.h"
+#include "content/public/browser/web_ui_data_source.h"
+#include "grit/browser_resources.h"
+#include "grit/generated_resources.h"
+
+CastUI::CastUI(content::WebUI* web_ui)
+ : content::WebUIController(web_ui) {
+ // Retrieve the ID of the component extension.
+ // TODO(crbug.com/597778): remove reference to MediaRouterMojoImpl.
+ auto router = static_cast<media_router::MediaRouterMojoImpl*>(
+ media_router::MediaRouterFactory::GetApiForBrowserContext(
+ web_ui->GetWebContents()->GetBrowserContext()));
+ std::string extension_id = router->media_route_provider_extension_id();
+
+ // Set up the chrome://cast data source and add required resources.
+ content::WebUIDataSource* html_source =
+ content::WebUIDataSource::Create(chrome::kChromeUICastHost);
+
+ html_source->AddResourcePath("cast.css", IDR_CAST_CSS);
+ html_source->AddResourcePath("cast.js", IDR_CAST_JS);
+ html_source->AddResourcePath("cast_favicon.ico", IDR_CAST_FAVICON);
+ html_source->AddString("extensionId", extension_id);
+ html_source->SetJsonPath("strings.js");
+ html_source->SetDefaultResource(IDR_CAST_HTML);
+ html_source->OverrideContentSecurityPolicyObjectSrc("object-src *;");
+
+ content::WebUIDataSource::Add(Profile::FromWebUI(web_ui), html_source);
+}
+
+CastUI::~CastUI() {
+}
diff --git a/chrome/browser/ui/webui/cast/cast_ui.h b/chrome/browser/ui/webui/cast/cast_ui.h
new file mode 100644
index 0000000..2cae6dd
--- /dev/null
+++ b/chrome/browser/ui/webui/cast/cast_ui.h
@@ -0,0 +1,21 @@
+// Copyright 2016 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 CHROME_BROWSER_UI_WEBUI_CAST_CAST_UI_H_
+#define CHROME_BROWSER_UI_WEBUI_CAST_CAST_UI_H_
+
+#include "base/macros.h"
+#include "base/values.h"
+#include "content/public/browser/web_ui_controller.h"
+
+// The WebUI for chrome://cast
+class CastUI : public content::WebUIController {
+ public:
+ explicit CastUI(content::WebUI* web_ui);
+ ~CastUI() override;
+ private:
+ DISALLOW_COPY_AND_ASSIGN(CastUI);
+};
+
+#endif // CHROME_BROWSER_UI_WEBUI_CAST_CAST_UI_H_
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
index 1bbf46d..1085b74 100644
--- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
+++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -91,10 +91,15 @@
#include "chrome/browser/ui/webui/print_preview/print_preview_ui.h"
#endif
-#if defined(ENABLE_MEDIA_ROUTER) && !defined(OS_ANDROID)
+#if defined(ENABLE_MEDIA_ROUTER)
+#if !defined(OS_ANDROID)
#include "chrome/browser/media/router/media_router_feature.h"
#include "chrome/browser/ui/webui/media_router/media_router_ui.h"
#endif
+#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS)
+#include "chrome/browser/ui/webui/cast/cast_ui.h"
+#endif
+#endif
#if defined(OS_ANDROID)
#include "chrome/browser/ui/webui/net_export_ui.h"
@@ -567,12 +572,20 @@
if (url.host() == chrome::kChromeUIWebRtcLogsHost)
return &NewWebUI<WebRtcLogsUI>;
#endif
-#if defined(ENABLE_MEDIA_ROUTER) && !defined(OS_ANDROID)
+#if defined(ENABLE_MEDIA_ROUTER)
+#if !defined(OS_ANDROID)
if (url.host() == chrome::kChromeUIMediaRouterHost &&
media_router::MediaRouterEnabled(profile)) {
return &NewWebUI<media_router::MediaRouterUI>;
}
#endif
+#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS)
+ if (url.host() == chrome::kChromeUICastHost &&
+ media_router::MediaRouterEnabled(profile)) {
+ return &NewWebUI<CastUI>;
+ }
+#endif
+#endif
if (IsAboutUI(url))
return &NewWebUI<AboutUI>;
diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi
index c18d044..06f8ae9 100644
--- a/chrome/chrome_browser_ui.gypi
+++ b/chrome/chrome_browser_ui.gypi
@@ -728,6 +728,8 @@
'browser/ui/views/select_file_dialog_extension.h',
'browser/ui/views/select_file_dialog_extension_factory.cc',
'browser/ui/views/select_file_dialog_extension_factory.h',
+ 'browser/ui/webui/cast/cast_ui.cc',
+ 'browser/ui/webui/cast/cast_ui.h',
],
# ARC-only sources.
'chrome_browser_ui_chromeos_arc_sources': [
@@ -1518,6 +1520,8 @@
'browser/ui/passwords/manage_passwords_icon.cc',
'browser/ui/passwords/manage_passwords_icon.h',
'browser/ui/web_contents_sizer.mm',
+ 'browser/ui/webui/cast/cast_ui.cc',
+ 'browser/ui/webui/cast/cast_ui.h',
],
'chrome_browser_ui_media_router_sources': [
'browser/ui/toolbar/media_router_action.cc',
@@ -2552,6 +2556,8 @@
'browser/ui/views/network_profile_bubble_view.cc',
'browser/ui/views/uninstall_view.cc',
'browser/ui/views/uninstall_view.h',
+ 'browser/ui/webui/cast/cast_ui.cc',
+ 'browser/ui/webui/cast/cast_ui.h',
'browser/ui/webui/conflicts_ui.cc',
'browser/ui/webui/conflicts_ui.h',
'browser/ui/webui/set_as_default_browser_ui.cc',
diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc
index 4464a92..68c305a 100644
--- a/chrome/common/url_constants.cc
+++ b/chrome/common/url_constants.cc
@@ -145,6 +145,9 @@
#if defined(ENABLE_MEDIA_ROUTER)
const char kChromeUIMediaRouterURL[] = "chrome://media-router/";
+#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS)
+const char kChromeUICastURL[] = "chrome://cast/";
+#endif
#endif
#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS)
@@ -329,6 +332,9 @@
#if defined(ENABLE_MEDIA_ROUTER)
const char kChromeUIMediaRouterHost[] = "media-router";
+#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS)
+const char kChromeUICastHost[] = "cast";
+#endif
#endif
// Option sub pages.
diff --git a/chrome/common/url_constants.h b/chrome/common/url_constants.h
index 38192c0..5088e56 100644
--- a/chrome/common/url_constants.h
+++ b/chrome/common/url_constants.h
@@ -135,6 +135,9 @@
#if defined(ENABLE_MEDIA_ROUTER)
extern const char kChromeUIMediaRouterURL[];
+#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS)
+extern const char kChromeUICastURL[];
+#endif
#endif
#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS)
@@ -306,6 +309,9 @@
#if defined(ENABLE_MEDIA_ROUTER)
extern const char kChromeUIMediaRouterHost[];
+#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS)
+extern const char kChromeUICastHost[];
+#endif
#endif
// Options sub-pages.
diff --git a/extensions/common/api/_api_features.json b/extensions/common/api/_api_features.json
index 45ef8e5..ac12ff9 100644
--- a/extensions/common/api/_api_features.json
+++ b/extensions/common/api/_api_features.json
@@ -188,7 +188,10 @@
"internal": true,
"channel": "stable",
"contexts": ["webui"],
- "matches": ["chrome://media-router/*"]
+ "matches": [
+ "chrome://cast/*",
+ "chrome://media-router/*"
+ ]
}
],
"events": {
@@ -208,6 +211,7 @@
"channel": "trunk",
"contexts": ["webui"],
"matches": [
+ "chrome://cast/*",
"chrome://extensions-frame/*",
"chrome://extensions/*",
"chrome://chrome-signin/*",