summaryrefslogtreecommitdiff
path: root/chromium/headless
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/headless')
-rw-r--r--chromium/headless/BUILD.gn180
-rw-r--r--chromium/headless/DEPS2
-rw-r--r--chromium/headless/README.md11
-rw-r--r--chromium/headless/app/headless_shell.cc86
-rw-r--r--chromium/headless/app/headless_shell_main.cc9
-rw-r--r--chromium/headless/lib/browser/DEPS3
-rw-r--r--chromium/headless/lib/browser/devtools_api/client_api_generator.py (renamed from chromium/headless/lib/browser/client_api_generator.py)353
-rwxr-xr-x[-rw-r--r--]chromium/headless/lib/browser/devtools_api/client_api_generator_unittest.py (renamed from chromium/headless/lib/browser/client_api_generator_unittest.py)82
-rw-r--r--chromium/headless/lib/browser/devtools_api/deprecated_domain_h.template7
-rw-r--r--chromium/headless/lib/browser/devtools_api/deprecated_type_conversions_h.template14
-rw-r--r--chromium/headless/lib/browser/devtools_api/deprecated_types_h.template14
-rw-r--r--chromium/headless/lib/browser/devtools_api/domain_cc.template (renamed from chromium/headless/lib/browser/domain_cc.template)30
-rw-r--r--chromium/headless/lib/browser/devtools_api/domain_h.template (renamed from chromium/headless/lib/browser/domain_h.template)19
-rw-r--r--chromium/headless/lib/browser/devtools_api/domain_type_conversions_h.template (renamed from chromium/headless/lib/browser/type_conversions_h.template)37
-rw-r--r--chromium/headless/lib/browser/devtools_api/domain_types_cc.template (renamed from chromium/headless/lib/browser/types_cc.template)91
-rw-r--r--chromium/headless/lib/browser/devtools_api/domain_types_forward_declaration_h.template44
-rw-r--r--chromium/headless/lib/browser/devtools_api/domain_types_h.template (renamed from chromium/headless/lib/browser/types_h.template)108
-rw-r--r--chromium/headless/lib/browser/headless_browser_impl.cc6
-rw-r--r--chromium/headless/lib/browser/headless_browser_impl.h4
-rw-r--r--chromium/headless/lib/browser/headless_browser_manifest_overlay_template.json10
-rw-r--r--chromium/headless/lib/browser/headless_content_browser_client.cc37
-rw-r--r--chromium/headless/lib/browser/headless_content_browser_client.h2
-rw-r--r--chromium/headless/lib/browser/headless_devtools_client_impl.cc15
-rw-r--r--chromium/headless/lib/browser/headless_devtools_client_impl.h67
-rw-r--r--chromium/headless/lib/browser/headless_devtools_manager_delegate.cc18
-rw-r--r--chromium/headless/lib/browser/headless_screen.cc78
-rw-r--r--chromium/headless/lib/browser/headless_screen.h16
-rw-r--r--chromium/headless/lib/browser/headless_web_contents_impl.cc22
-rw-r--r--chromium/headless/lib/browser/headless_window_parenting_client.cc28
-rw-r--r--chromium/headless/lib/browser/headless_window_parenting_client.h31
-rw-r--r--chromium/headless/lib/browser/headless_window_tree_client.cc27
-rw-r--r--chromium/headless/lib/browser/headless_window_tree_client.h30
-rw-r--r--chromium/headless/lib/embedder_mojo_browsertest.cc14
-rw-r--r--chromium/headless/lib/headless_browser_browsertest.cc4
-rw-r--r--chromium/headless/lib/headless_devtools_client_browsertest.cc225
-rw-r--r--chromium/headless/lib/headless_web_contents_browsertest.cc24
-rw-r--r--chromium/headless/lib/resources/headless_lib_resources.grd1
-rw-r--r--chromium/headless/public/domains/README.md4
-rw-r--r--chromium/headless/public/domains/types_unittest.cc18
-rw-r--r--chromium/headless/public/headless_browser.cc5
-rw-r--r--chromium/headless/public/headless_browser.h6
-rw-r--r--chromium/headless/public/headless_devtools_client.h10
-rw-r--r--chromium/headless/public/headless_shell.h18
-rw-r--r--chromium/headless/public/internal/value_conversions.h2
-rw-r--r--chromium/headless/public/util/deterministic_dispatcher.cc9
-rw-r--r--chromium/headless/public/util/deterministic_dispatcher.h3
-rw-r--r--chromium/headless/public/util/deterministic_dispatcher_test.cc16
-rw-r--r--chromium/headless/public/util/dom_tree_extractor.cc109
-rw-r--r--chromium/headless/public/util/dom_tree_extractor.h88
-rw-r--r--chromium/headless/public/util/dom_tree_extractor_browsertest.cc845
-rw-r--r--chromium/headless/public/util/error_reporter.cc2
-rw-r--r--chromium/headless/public/util/error_reporter.h12
-rw-r--r--chromium/headless/public/util/error_reporter_unittest.cc8
-rw-r--r--chromium/headless/public/util/generic_url_request_job.cc7
-rw-r--r--chromium/headless/public/util/generic_url_request_job.h2
-rw-r--r--chromium/headless/public/util/generic_url_request_job_test.cc5
-rw-r--r--chromium/headless/public/util/http_url_fetcher.cc11
-rw-r--r--chromium/headless/public/util/testing/fake_managed_dispatch_url_request_job.cc6
-rw-r--r--chromium/headless/public/util/testing/fake_managed_dispatch_url_request_job.h2
59 files changed, 2173 insertions, 764 deletions
diff --git a/chromium/headless/BUILD.gn b/chromium/headless/BUILD.gn
index 8e5970bde4a..9c9d392f436 100644
--- a/chromium/headless/BUILD.gn
+++ b/chromium/headless/BUILD.gn
@@ -2,6 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import("//build/config/chrome_build.gni")
import("//mojo/public/tools/bindings/mojom.gni")
import("//testing/test.gni")
import("//tools/grit/grit_rule.gni")
@@ -22,6 +23,7 @@ repack("pak") {
"$root_gen_dir/blink/devtools_resources.pak",
"$root_gen_dir/blink/public/resources/blink_image_resources_100_percent.pak",
"$root_gen_dir/blink/public/resources/blink_resources.pak",
+ "$root_gen_dir/components/strings/components_strings_en-US.pak",
"$root_gen_dir/content/app/resources/content_resources_100_percent.pak",
"$root_gen_dir/content/app/strings/content_strings_en-US.pak",
"$root_gen_dir/content/browser/tracing/tracing_resources.pak",
@@ -34,8 +36,15 @@ repack("pak") {
"$root_gen_dir/ui/strings/ui_strings_en-US.pak",
]
+ if (is_chrome_branded) {
+ sources += [ "${root_gen_dir}/components/strings/components_google_chrome_strings_en-US.pak" ]
+ } else {
+ sources += [ "${root_gen_dir}/components/strings/components_chromium_strings_en-US.pak" ]
+ }
+
deps = [
":headless_lib_resources_grit",
+ "//components/strings",
"//content:resources",
"//content/app/resources",
"//content/app/strings",
@@ -59,76 +68,59 @@ grit("headless_lib_resources_grit") {
]
}
+devtools_domains = [
+ "accessibility",
+ "animation",
+ "application_cache",
+ "cache_storage",
+ "console",
+ "css",
+ "database",
+ "debugger",
+ "device_orientation",
+ "dom",
+ "dom_debugger",
+ "dom_storage",
+ "emulation",
+ "heap_profiler",
+ "indexeddb",
+ "input",
+ "inspector",
+ "io",
+ "layer_tree",
+ "log",
+ "memory",
+ "network",
+ "page",
+ "profiler",
+ "rendering",
+ "runtime",
+ "security",
+ "service_worker",
+ "target",
+ "tracing",
+]
+
generated_devtools_api = [
- "$target_gen_dir/public/domains/accessibility.cc",
- "$target_gen_dir/public/domains/accessibility.h",
- "$target_gen_dir/public/domains/animation.cc",
- "$target_gen_dir/public/domains/animation.h",
- "$target_gen_dir/public/domains/application_cache.cc",
- "$target_gen_dir/public/domains/application_cache.h",
- "$target_gen_dir/public/domains/browser.cc",
- "$target_gen_dir/public/domains/browser.h",
- "$target_gen_dir/public/domains/cache_storage.cc",
- "$target_gen_dir/public/domains/cache_storage.h",
- "$target_gen_dir/public/domains/console.cc",
- "$target_gen_dir/public/domains/console.h",
- "$target_gen_dir/public/domains/css.cc",
- "$target_gen_dir/public/domains/css.h",
- "$target_gen_dir/public/domains/database.cc",
- "$target_gen_dir/public/domains/database.h",
- "$target_gen_dir/public/domains/debugger.cc",
- "$target_gen_dir/public/domains/debugger.h",
- "$target_gen_dir/public/domains/device_orientation.cc",
- "$target_gen_dir/public/domains/device_orientation.h",
- "$target_gen_dir/public/domains/dom_debugger.cc",
- "$target_gen_dir/public/domains/dom_debugger.h",
- "$target_gen_dir/public/domains/dom.cc",
- "$target_gen_dir/public/domains/dom.h",
- "$target_gen_dir/public/domains/dom_storage.cc",
- "$target_gen_dir/public/domains/dom_storage.h",
- "$target_gen_dir/public/domains/emulation.cc",
- "$target_gen_dir/public/domains/emulation.h",
- "$target_gen_dir/public/domains/heap_profiler.cc",
- "$target_gen_dir/public/domains/heap_profiler.h",
- "$target_gen_dir/public/domains/indexeddb.cc",
- "$target_gen_dir/public/domains/indexeddb.h",
- "$target_gen_dir/public/domains/input.cc",
- "$target_gen_dir/public/domains/input.h",
- "$target_gen_dir/public/domains/inspector.cc",
- "$target_gen_dir/public/domains/inspector.h",
- "$target_gen_dir/public/domains/io.cc",
- "$target_gen_dir/public/domains/io.h",
- "$target_gen_dir/public/domains/layer_tree.cc",
- "$target_gen_dir/public/domains/layer_tree.h",
- "$target_gen_dir/public/domains/log.cc",
- "$target_gen_dir/public/domains/log.h",
- "$target_gen_dir/public/domains/memory.cc",
- "$target_gen_dir/public/domains/memory.h",
- "$target_gen_dir/public/domains/network.cc",
- "$target_gen_dir/public/domains/network.h",
- "$target_gen_dir/public/domains/page.cc",
- "$target_gen_dir/public/domains/page.h",
- "$target_gen_dir/public/domains/profiler.cc",
- "$target_gen_dir/public/domains/profiler.h",
- "$target_gen_dir/public/domains/rendering.cc",
- "$target_gen_dir/public/domains/rendering.h",
- "$target_gen_dir/public/domains/runtime.cc",
- "$target_gen_dir/public/domains/runtime.h",
- "$target_gen_dir/public/domains/security.cc",
- "$target_gen_dir/public/domains/security.h",
- "$target_gen_dir/public/domains/service_worker.cc",
- "$target_gen_dir/public/domains/service_worker.h",
- "$target_gen_dir/public/domains/tracing.cc",
- "$target_gen_dir/public/domains/tracing.h",
- "$target_gen_dir/public/domains/type_conversions.h",
- "$target_gen_dir/public/domains/types.cc",
"$target_gen_dir/public/domains/types.h",
- "$target_gen_dir/public/domains/worker.cc",
- "$target_gen_dir/public/domains/worker.h",
+ "$target_gen_dir/public/domains/type_conversions.h",
]
+foreach(domain, devtools_domains) {
+ generated_devtools_api += [
+ "$target_gen_dir/public/domains/" + domain + ".h",
+ "$target_gen_dir/public/devtools/domains/" + domain + ".cc",
+ "$target_gen_dir/public/devtools/domains/" + domain + ".h",
+ "$target_gen_dir/public/devtools/domains/types_" + domain + ".h",
+ "$target_gen_dir/public/devtools/domains/types_" + domain + ".cc",
+ "$target_gen_dir/public/devtools/internal/type_conversions_" + domain +
+ ".h",
+ "$target_gen_dir/public/devtools/internal/" +
+ "types_forward_declarations_" + domain + ".h",
+ ]
+}
action("gen_devtools_client_api") {
- script = "//headless/lib/browser/client_api_generator.py"
+ script = "//headless/lib/browser/devtools_api/client_api_generator.py"
deps = [
"//third_party/WebKit/Source/core/inspector:protocol_version",
]
@@ -139,18 +131,21 @@ action("gen_devtools_client_api") {
outputs = generated_devtools_api
sources = [
- "lib/browser/domain_cc.template",
- "lib/browser/domain_h.template",
- "lib/browser/type_conversions_h.template",
- "lib/browser/types_cc.template",
- "lib/browser/types_h.template",
+ "lib/browser/devtools_api/deprecated_type_conversions_h.template",
+ "lib/browser/devtools_api/deprecated_types_h.template",
+ "lib/browser/devtools_api/domain_cc.template",
+ "lib/browser/devtools_api/domain_h.template",
+ "lib/browser/devtools_api/domain_type_conversions_h.template",
+ "lib/browser/devtools_api/domain_types_cc.template",
+ "lib/browser/devtools_api/domain_types_forward_declaration_h.template",
+ "lib/browser/devtools_api/domain_types_h.template",
]
args = [
"--protocol",
rebase_path(inputs[0], root_build_dir),
"--output_dir",
- rebase_path(target_gen_dir) + "/public/domains",
+ rebase_path(target_gen_dir) + "/public",
]
}
@@ -178,8 +173,8 @@ static_library("headless_lib") {
"lib/browser/headless_url_request_context_getter.h",
"lib/browser/headless_web_contents_impl.cc",
"lib/browser/headless_web_contents_impl.h",
- "lib/browser/headless_window_tree_client.cc",
- "lib/browser/headless_window_tree_client.h",
+ "lib/browser/headless_window_parenting_client.cc",
+ "lib/browser/headless_window_parenting_client.h",
"lib/headless_content_client.cc",
"lib/headless_content_client.h",
"lib/headless_content_main_delegate.cc",
@@ -204,6 +199,8 @@ static_library("headless_lib") {
"public/util/deterministic_dispatcher.h",
"public/util/deterministic_http_protocol_handler.cc",
"public/util/deterministic_http_protocol_handler.h",
+ "public/util/dom_tree_extractor.cc",
+ "public/util/dom_tree_extractor.h",
"public/util/error_reporter.cc",
"public/util/error_reporter.h",
"public/util/expedited_dispatcher.cc",
@@ -231,14 +228,17 @@ static_library("headless_lib") {
":gen_devtools_client_api",
":pak",
"//base",
+ "//components/security_state/content",
+ "//components/security_state/core",
"//content/public/app:both",
"//content/public/browser",
"//content/public/child",
"//content/public/common",
+ "//content/public/common:service_names",
"//content/public/renderer",
"//content/public/utility",
"//net",
- "//services/shell/public/cpp",
+ "//services/service_manager/public/cpp",
"//third_party/mesa:osmesa",
"//ui/aura",
"//ui/base",
@@ -255,7 +255,6 @@ group("headless_tests") {
testonly = true
deps = [
- ":client_api_generator_tests",
":headless_browsertests",
":headless_unittests",
]
@@ -281,23 +280,6 @@ test("headless_unittests") {
]
}
-action("client_api_generator_tests") {
- _stamp = "$target_gen_dir/client_api_generator_unittests.stamp"
- inputs = [
- "lib/browser/client_api_generator.py",
- "lib/browser/client_api_generator_unittest.py",
- ]
- outputs = [
- _stamp,
- ]
-
- script = "lib/browser/client_api_generator_unittest.py"
- args = [
- "--stamp",
- rebase_path(_stamp, root_build_dir),
- ]
-}
-
mojom("embedder_mojo_for_testing") {
sources = [
"lib/embedder_test.mojom",
@@ -337,6 +319,7 @@ test("headless_browsertests") {
"lib/headless_browser_context_browsertest.cc",
"lib/headless_devtools_client_browsertest.cc",
"lib/headless_web_contents_browsertest.cc",
+ "public/util/dom_tree_extractor_browsertest.cc",
"test/headless_browser_test.cc",
"test/headless_browser_test.h",
"test/headless_test_launcher.cc",
@@ -363,14 +346,25 @@ test("headless_browsertests") {
]
}
-executable("headless_shell") {
+static_library("headless_shell_lib") {
sources = [
"app/headless_shell.cc",
"app/headless_shell_switches.cc",
"app/headless_shell_switches.h",
+ "public/headless_shell.h",
]
deps = [
"//headless:headless_lib",
]
}
+
+executable("headless_shell") {
+ sources = [
+ "app/headless_shell_main.cc",
+ ]
+
+ deps = [
+ "//headless:headless_shell_lib",
+ ]
+}
diff --git a/chromium/headless/DEPS b/chromium/headless/DEPS
index cc93e6b7e6c..500e0224908 100644
--- a/chromium/headless/DEPS
+++ b/chromium/headless/DEPS
@@ -9,5 +9,5 @@ include_rules = [
"+ui/gfx/geometry",
"+ui/gl",
"+ui/ozone/public",
- "+services/shell/public",
+ "+services/service_manager/public",
]
diff --git a/chromium/headless/README.md b/chromium/headless/README.md
index 9e3c7b02eba..06128d79b66 100644
--- a/chromium/headless/README.md
+++ b/chromium/headless/README.md
@@ -66,3 +66,14 @@ web pages. Its main classes are:
controlling a tab. The API functions corresponds to [DevTools commands](https://developer.chrome.com/devtools/docs/debugger-protocol).
See the [client API documentation](https://docs.google.com/document/d/1rlqcp8nk-ZQvldNJWdbaMbwfDbJoOXvahPCDoPGOwhQ/edit#)
for more information.
+
+## Documentation
+
+* [Virtual Time in Blink](https://docs.google.com/document/d/1y9kdt_zezt7pbey6uzvt1dgklwc1ob_vy4nzo1zbqmo/edit#heading=h.tn3gd1y9ifml)
+* [Headless Chrome architecture](https://docs.google.com/document/d/11zIkKkLBocofGgoTeeyibB2TZ_k7nR78v7kNelCatUE/edit)
+* [Headless Chrome C++ DevTools API](https://docs.google.com/document/d/1rlqcp8nk-ZQvldNJWdbaMbwfDbJoOXvahPCDoPGOwhQ/edit#heading=h.ng2bxb15li9a)
+* [Session isolation in Headless Chrome](https://docs.google.com/document/d/1XAKvrxtSEoe65vNghSWC5S3kJ--z2Zpt2UWW1Fi8GiM/edit)
+* [Headless Chrome mojo service](https://docs.google.com/document/d/1Fr6_DJH6OK9rG3-ibMvRPTNnHsAXPk0VzxxiuJDSK3M/edit#heading=h.qh0udvlk963d)
+* [Controlling BeginFrame through DevTools](https://docs.google.com/document/d/1LVMYDkfjrrX9PNkrD8pJH5-Np_XUTQHIuJ8IEOirQH4/edit?ts=57d96dbd#heading=h.ndv831lc9uf0)
+* [Viewport bounds and scale for screenshots](https://docs.google.com/document/d/1VTcYz4q_x0f1O5IVrvRX4u1DVd_K34IVUl1VULLTCWw/edit#heading=h.ndv831lc9uf0)
+* [BlinkOn 6 presentation slides](https://docs.google.com/presentation/d/1gqK9F4lGAY3TZudAtdcxzMQNEE7PcuQrGu83No3l0lw/edit#slide=id.p)
diff --git a/chromium/headless/app/headless_shell.cc b/chromium/headless/app/headless_shell.cc
index c2e3690f53d..b57fc5f9070 100644
--- a/chromium/headless/app/headless_shell.cc
+++ b/chromium/headless/app/headless_shell.cc
@@ -18,9 +18,9 @@
#include "base/strings/string_number_conversions.h"
#include "content/public/common/content_switches.h"
#include "headless/app/headless_shell_switches.h"
-#include "headless/public/domains/emulation.h"
-#include "headless/public/domains/page.h"
-#include "headless/public/domains/runtime.h"
+#include "headless/public/devtools/domains/emulation.h"
+#include "headless/public/devtools/domains/page.h"
+#include "headless/public/devtools/domains/runtime.h"
#include "headless/public/headless_browser.h"
#include "headless/public/headless_devtools_client.h"
#include "headless/public/headless_devtools_target.h"
@@ -33,14 +33,7 @@
#include "net/base/net_errors.h"
#include "ui/gfx/geometry/size.h"
-using headless::HeadlessBrowser;
-using headless::HeadlessBrowserContext;
-using headless::HeadlessDevToolsClient;
-using headless::HeadlessWebContents;
-namespace emulation = headless::emulation;
-namespace page = headless::page;
-namespace runtime = headless::runtime;
-
+namespace headless {
namespace {
// Address where to listen to incoming DevTools connections.
const char kDevToolsHttpServerAddress[] = "127.0.0.1";
@@ -59,7 +52,7 @@ bool ParseWindowSize(std::string window_size, gfx::Size* parsed_window_size) {
}
} // namespace
-// A sample application which demonstrates the use of the headless API.
+// An application which implements a simple headless browser.
class HeadlessShell : public HeadlessWebContents::Observer,
emulation::ExperimentalObserver,
page::Observer {
@@ -78,24 +71,24 @@ class HeadlessShell : public HeadlessWebContents::Observer,
HeadlessBrowserContext::Builder context_builder =
browser_->CreateBrowserContextBuilder();
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- headless::switches::kDeterministicFetch)) {
+ switches::kDeterministicFetch)) {
deterministic_dispatcher_.reset(
- new headless::DeterministicDispatcher(browser_->BrowserIOThread()));
+ new DeterministicDispatcher(browser_->BrowserIOThread()));
- headless::ProtocolHandlerMap protocol_handlers;
+ ProtocolHandlerMap protocol_handlers;
protocol_handlers[url::kHttpScheme] =
- base::MakeUnique<headless::DeterministicHttpProtocolHandler>(
+ base::MakeUnique<DeterministicHttpProtocolHandler>(
deterministic_dispatcher_.get(), browser->BrowserIOThread());
protocol_handlers[url::kHttpsScheme] =
- base::MakeUnique<headless::DeterministicHttpProtocolHandler>(
+ base::MakeUnique<DeterministicHttpProtocolHandler>(
deterministic_dispatcher_.get(), browser->BrowserIOThread());
context_builder.SetProtocolHandlers(std::move(protocol_handlers));
}
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- headless::switches::kHideScrollbars)) {
+ switches::kHideScrollbars)) {
context_builder.SetOverrideWebPreferencesCallback(
- base::Bind([](headless::WebPreferences* preferences) {
+ base::Bind([](WebPreferences* preferences) {
preferences->hide_scrollbars = true;
}));
}
@@ -147,10 +140,10 @@ class HeadlessShell : public HeadlessWebContents::Observer,
devtools_client_->GetEmulation()->GetExperimental()->AddObserver(this);
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- headless::switches::kVirtualTimeBudget)) {
+ switches::kVirtualTimeBudget)) {
std::string budget_ms_ascii =
base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
- headless::switches::kVirtualTimeBudget);
+ switches::kVirtualTimeBudget);
int budget_ms;
CHECK(base::StringToInt(budget_ms_ascii, &budget_ms))
<< "Expected an integer value for --virtual-time-budget=";
@@ -200,7 +193,7 @@ class HeadlessShell : public HeadlessWebContents::Observer,
// page::Observer implementation:
void OnLoadEventFired(const page::LoadEventFiredParams& params) override {
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- headless::switches::kVirtualTimeBudget)) {
+ switches::kVirtualTimeBudget)) {
return;
}
OnPageReady();
@@ -211,17 +204,16 @@ class HeadlessShell : public HeadlessWebContents::Observer,
return;
processed_page_ready_ = true;
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- headless::switches::kDumpDom)) {
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpDom)) {
FetchDom();
} else if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- headless::switches::kRepl)) {
+ switches::kRepl)) {
std::cout
<< "Type a Javascript expression to evaluate or \"quit\" to exit."
<< std::endl;
InputExpression();
} else if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- headless::switches::kScreenshot)) {
+ switches::kScreenshot)) {
CaptureScreenshot();
} else {
Shutdown();
@@ -281,7 +273,7 @@ class HeadlessShell : public HeadlessWebContents::Observer,
std::unique_ptr<page::CaptureScreenshotResult> result) {
base::FilePath file_name =
base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
- headless::switches::kScreenshot);
+ switches::kScreenshot);
if (file_name.empty()) {
file_name = base::FilePath().AppendASCII(kDefaultScreenshotFileName);
}
@@ -350,7 +342,7 @@ class HeadlessShell : public HeadlessWebContents::Observer,
bool RemoteDebuggingEnabled() const {
const base::CommandLine& command_line =
*base::CommandLine::ForCurrentProcess();
- return command_line.HasSwitch(switches::kRemoteDebuggingPort);
+ return command_line.HasSwitch(::switches::kRemoteDebuggingPort);
}
private:
@@ -361,23 +353,23 @@ class HeadlessShell : public HeadlessWebContents::Observer,
bool processed_page_ready_;
std::unique_ptr<net::FileStream> screenshot_file_stream_;
HeadlessBrowserContext* browser_context_;
- std::unique_ptr<headless::DeterministicDispatcher> deterministic_dispatcher_;
+ std::unique_ptr<DeterministicDispatcher> deterministic_dispatcher_;
DISALLOW_COPY_AND_ASSIGN(HeadlessShell);
};
-int main(int argc, const char** argv) {
- headless::RunChildProcessIfNeeded(argc, argv);
+int HeadlessShellMain(int argc, const char** argv) {
+ RunChildProcessIfNeeded(argc, argv);
HeadlessShell shell;
HeadlessBrowser::Options::Builder builder(argc, argv);
// Enable devtools if requested.
base::CommandLine command_line(argc, argv);
- if (command_line.HasSwitch(switches::kRemoteDebuggingPort)) {
+ if (command_line.HasSwitch(::switches::kRemoteDebuggingPort)) {
std::string address = kDevToolsHttpServerAddress;
- if (command_line.HasSwitch(headless::switches::kRemoteDebuggingAddress)) {
- address = command_line.GetSwitchValueASCII(
- headless::switches::kRemoteDebuggingAddress);
+ if (command_line.HasSwitch(switches::kRemoteDebuggingAddress)) {
+ address =
+ command_line.GetSwitchValueASCII(switches::kRemoteDebuggingAddress);
net::IPAddress parsed_address;
if (!net::ParseURLHostnameToAddress(address, &parsed_address)) {
LOG(ERROR) << "Invalid devtools server address";
@@ -386,7 +378,7 @@ int main(int argc, const char** argv) {
}
int parsed_port;
std::string port_str =
- command_line.GetSwitchValueASCII(switches::kRemoteDebuggingPort);
+ command_line.GetSwitchValueASCII(::switches::kRemoteDebuggingPort);
if (!base::StringToInt(port_str, &parsed_port) ||
!base::IsValueInRangeForNumericType<uint16_t>(parsed_port)) {
LOG(ERROR) << "Invalid devtools server port";
@@ -399,9 +391,9 @@ int main(int argc, const char** argv) {
devtools_address, base::checked_cast<uint16_t>(parsed_port)));
}
- if (command_line.HasSwitch(headless::switches::kProxyServer)) {
+ if (command_line.HasSwitch(switches::kProxyServer)) {
std::string proxy_server =
- command_line.GetSwitchValueASCII(headless::switches::kProxyServer);
+ command_line.GetSwitchValueASCII(switches::kProxyServer);
net::HostPortPair parsed_proxy_server =
net::HostPortPair::FromString(proxy_server);
if (parsed_proxy_server.host().empty() || !parsed_proxy_server.port()) {
@@ -411,25 +403,25 @@ int main(int argc, const char** argv) {
builder.SetProxyServer(parsed_proxy_server);
}
- if (command_line.HasSwitch(switches::kHostResolverRules)) {
+ if (command_line.HasSwitch(::switches::kHostResolverRules)) {
builder.SetHostResolverRules(
- command_line.GetSwitchValueASCII(switches::kHostResolverRules));
+ command_line.GetSwitchValueASCII(::switches::kHostResolverRules));
}
- if (command_line.HasSwitch(headless::switches::kUseGL)) {
+ if (command_line.HasSwitch(switches::kUseGL)) {
builder.SetGLImplementation(
- command_line.GetSwitchValueASCII(headless::switches::kUseGL));
+ command_line.GetSwitchValueASCII(switches::kUseGL));
}
- if (command_line.HasSwitch(headless::switches::kUserDataDir)) {
+ if (command_line.HasSwitch(switches::kUserDataDir)) {
builder.SetUserDataDir(
- command_line.GetSwitchValuePath(headless::switches::kUserDataDir));
+ command_line.GetSwitchValuePath(switches::kUserDataDir));
builder.SetIncognitoMode(false);
}
- if (command_line.HasSwitch(headless::switches::kWindowSize)) {
+ if (command_line.HasSwitch(switches::kWindowSize)) {
std::string window_size =
- command_line.GetSwitchValueASCII(headless::switches::kWindowSize);
+ command_line.GetSwitchValueASCII(switches::kWindowSize);
gfx::Size parsed_window_size;
if (!ParseWindowSize(window_size, &parsed_window_size)) {
LOG(ERROR) << "Malformed window size";
@@ -442,3 +434,5 @@ int main(int argc, const char** argv) {
builder.Build(),
base::Bind(&HeadlessShell::OnStart, base::Unretained(&shell)));
}
+
+} // namespace headless
diff --git a/chromium/headless/app/headless_shell_main.cc b/chromium/headless/app/headless_shell_main.cc
new file mode 100644
index 00000000000..3ae4553b068
--- /dev/null
+++ b/chromium/headless/app/headless_shell_main.cc
@@ -0,0 +1,9 @@
+// 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 "headless/public/headless_shell.h"
+
+int main(int argc, const char** argv) {
+ return headless::HeadlessShellMain(argc, argv);
+}
diff --git a/chromium/headless/lib/browser/DEPS b/chromium/headless/lib/browser/DEPS
index 75ab3c75a98..1704e22e758 100644
--- a/chromium/headless/lib/browser/DEPS
+++ b/chromium/headless/lib/browser/DEPS
@@ -1,3 +1,4 @@
include_rules = [
- "+ui/aura"
+ "+components/security_state",
+ "+ui/aura",
]
diff --git a/chromium/headless/lib/browser/client_api_generator.py b/chromium/headless/lib/browser/devtools_api/client_api_generator.py
index bb93ede97aa..ce96de211b4 100644
--- a/chromium/headless/lib/browser/client_api_generator.py
+++ b/chromium/headless/lib/browser/devtools_api/client_api_generator.py
@@ -3,9 +3,10 @@
# found in the LICENSE file.
import argparse
+import collections
import os.path
-import sys
import re
+import sys
try:
import json
except ImportError:
@@ -20,8 +21,9 @@ except ImportError:
# is regenerated, which causes a race condition and breaks concurrent build,
# since some compile processes will try to read the partially written cache.
module_path, module_filename = os.path.split(os.path.realpath(__file__))
-third_party_dir = os.path.normpath(os.path.join(
- module_path, os.pardir, os.pardir, os.pardir, 'third_party'))
+third_party_dir = os.path.normpath(
+ os.path.join(module_path, os.pardir, os.pardir, os.pardir, os.pardir,
+ 'third_party'))
templates_dir = module_path
# jinja2 is in chromium's third_party directory.
@@ -61,14 +63,14 @@ def CamelCaseToHackerStyle(name):
def SanitizeLiteral(literal):
return {
- # Rename null enumeration values to avoid a clash with the NULL macro.
- 'null': 'none',
- # Rename mathematical constants to avoid colliding with C macros.
- 'Infinity': 'InfinityValue',
- '-Infinity': 'NegativeInfinityValue',
- 'NaN': 'NaNValue',
- # Turn negative zero into a safe identifier.
- '-0': 'NegativeZeroValue',
+ # Rename null enumeration values to avoid a clash with the NULL macro.
+ 'null': 'none',
+ # Rename mathematical constants to avoid colliding with C macros.
+ 'Infinity': 'InfinityValue',
+ '-Infinity': 'NegativeInfinityValue',
+ 'NaN': 'NaNValue',
+ # Turn negative zero into a safe identifier.
+ '-0': 'NegativeZeroValue',
}.get(literal, literal)
@@ -82,10 +84,10 @@ def InitializeJinjaEnv(cache_dir):
lstrip_blocks=True, # So we can indent control flow tags.
trim_blocks=True)
jinja_env.filters.update({
- 'to_title_case': ToTitleCase,
- 'dash_to_camelcase': DashToCamelCase,
- 'camelcase_to_hacker_style': CamelCaseToHackerStyle,
- 'sanitize_literal': SanitizeLiteral,
+ 'to_title_case': ToTitleCase,
+ 'dash_to_camelcase': DashToCamelCase,
+ 'camelcase_to_hacker_style': CamelCaseToHackerStyle,
+ 'sanitize_literal': SanitizeLiteral,
})
jinja_env.add_extension('jinja2.ext.loopcontrols')
return jinja_env
@@ -113,108 +115,109 @@ def PatchFullQualifiedRefs(json_api):
def CreateUserTypeDefinition(domain, type):
namespace = CamelCaseToHackerStyle(domain['domain'])
return {
- 'return_type': 'std::unique_ptr<headless::%s::%s>' % (
- namespace, type['id']),
- 'pass_type': 'std::unique_ptr<headless::%s::%s>' % (namespace, type['id']),
- 'to_raw_type': '*%s',
- 'to_raw_return_type': '%s.get()',
- 'to_pass_type': 'std::move(%s)',
- 'type': 'std::unique_ptr<headless::%s::%s>' % (namespace, type['id']),
- 'raw_type': 'headless::%s::%s' % (namespace, type['id']),
- 'raw_pass_type': 'headless::%s::%s*' % (namespace, type['id']),
- 'raw_return_type': 'const headless::%s::%s*' % (namespace, type['id']),
+ 'return_type': 'std::unique_ptr<headless::%s::%s>' % (
+ namespace, type['id']),
+ 'pass_type': 'std::unique_ptr<headless::%s::%s>' % (
+ namespace, type['id']),
+ 'to_raw_type': '*%s',
+ 'to_raw_return_type': '%s.get()',
+ 'to_pass_type': 'std::move(%s)',
+ 'type': 'std::unique_ptr<headless::%s::%s>' % (namespace, type['id']),
+ 'raw_type': 'headless::%s::%s' % (namespace, type['id']),
+ 'raw_pass_type': 'headless::%s::%s*' % (namespace, type['id']),
+ 'raw_return_type': 'const headless::%s::%s*' % (namespace, type['id']),
}
def CreateEnumTypeDefinition(domain_name, type):
namespace = CamelCaseToHackerStyle(domain_name)
return {
- 'return_type': 'headless::%s::%s' % (namespace, type['id']),
- 'pass_type': 'headless::%s::%s' % (namespace, type['id']),
- 'to_raw_type': '%s',
- 'to_raw_return_type': '%s',
- 'to_pass_type': '%s',
- 'type': 'headless::%s::%s' % (namespace, type['id']),
- 'raw_type': 'headless::%s::%s' % (namespace, type['id']),
- 'raw_pass_type': 'headless::%s::%s' % (namespace, type['id']),
- 'raw_return_type': 'headless::%s::%s' % (namespace, type['id']),
+ 'return_type': 'headless::%s::%s' % (namespace, type['id']),
+ 'pass_type': 'headless::%s::%s' % (namespace, type['id']),
+ 'to_raw_type': '%s',
+ 'to_raw_return_type': '%s',
+ 'to_pass_type': '%s',
+ 'type': 'headless::%s::%s' % (namespace, type['id']),
+ 'raw_type': 'headless::%s::%s' % (namespace, type['id']),
+ 'raw_pass_type': 'headless::%s::%s' % (namespace, type['id']),
+ 'raw_return_type': 'headless::%s::%s' % (namespace, type['id']),
}
def CreateObjectTypeDefinition():
return {
- 'return_type': 'std::unique_ptr<base::DictionaryValue>',
- 'pass_type': 'std::unique_ptr<base::DictionaryValue>',
- 'to_raw_type': '*%s',
- 'to_raw_return_type': '%s.get()',
- 'to_pass_type': 'std::move(%s)',
- 'type': 'std::unique_ptr<base::DictionaryValue>',
- 'raw_type': 'base::DictionaryValue',
- 'raw_pass_type': 'base::DictionaryValue*',
- 'raw_return_type': 'const base::DictionaryValue*',
+ 'return_type': 'std::unique_ptr<base::DictionaryValue>',
+ 'pass_type': 'std::unique_ptr<base::DictionaryValue>',
+ 'to_raw_type': '*%s',
+ 'to_raw_return_type': '%s.get()',
+ 'to_pass_type': 'std::move(%s)',
+ 'type': 'std::unique_ptr<base::DictionaryValue>',
+ 'raw_type': 'base::DictionaryValue',
+ 'raw_pass_type': 'base::DictionaryValue*',
+ 'raw_return_type': 'const base::DictionaryValue*',
}
def WrapObjectTypeDefinition(type):
id = type.get('id', 'base::Value')
return {
- 'return_type': 'std::unique_ptr<%s>' % id,
- 'pass_type': 'std::unique_ptr<%s>' % id,
- 'to_raw_type': '*%s',
- 'to_raw_return_type': '%s.get()',
- 'to_pass_type': 'std::move(%s)',
- 'type': 'std::unique_ptr<%s>' % id,
- 'raw_type': id,
- 'raw_pass_type': '%s*' % id,
- 'raw_return_type': 'const %s*' % id,
+ 'return_type': 'std::unique_ptr<%s>' % id,
+ 'pass_type': 'std::unique_ptr<%s>' % id,
+ 'to_raw_type': '*%s',
+ 'to_raw_return_type': '%s.get()',
+ 'to_pass_type': 'std::move(%s)',
+ 'type': 'std::unique_ptr<%s>' % id,
+ 'raw_type': id,
+ 'raw_pass_type': '%s*' % id,
+ 'raw_return_type': 'const %s*' % id,
}
def CreateAnyTypeDefinition():
return {
- 'return_type': 'std::unique_ptr<base::Value>',
- 'pass_type': 'std::unique_ptr<base::Value>',
- 'to_raw_type': '*%s',
- 'to_raw_return_type': '%s.get()',
- 'to_pass_type': 'std::move(%s)',
- 'type': 'std::unique_ptr<base::Value>',
- 'raw_type': 'base::Value',
- 'raw_pass_type': 'base::Value*',
- 'raw_return_type': 'const base::Value*',
+ 'return_type': 'std::unique_ptr<base::Value>',
+ 'pass_type': 'std::unique_ptr<base::Value>',
+ 'to_raw_type': '*%s',
+ 'to_raw_return_type': '%s.get()',
+ 'to_pass_type': 'std::move(%s)',
+ 'type': 'std::unique_ptr<base::Value>',
+ 'raw_type': 'base::Value',
+ 'raw_pass_type': 'base::Value*',
+ 'raw_return_type': 'const base::Value*',
}
def CreateStringTypeDefinition(domain):
return {
- 'return_type': 'std::string',
- 'pass_type': 'const std::string&',
- 'to_pass_type': '%s',
- 'to_raw_type': '%s',
- 'to_raw_return_type': '%s',
- 'type': 'std::string',
- 'raw_type': 'std::string',
- 'raw_pass_type': 'const std::string&',
- 'raw_return_type': 'std::string',
+ 'return_type': 'std::string',
+ 'pass_type': 'const std::string&',
+ 'to_pass_type': '%s',
+ 'to_raw_type': '%s',
+ 'to_raw_return_type': '%s',
+ 'type': 'std::string',
+ 'raw_type': 'std::string',
+ 'raw_pass_type': 'const std::string&',
+ 'raw_return_type': 'std::string',
}
def CreatePrimitiveTypeDefinition(type):
typedefs = {
- 'number': 'double',
- 'integer': 'int',
- 'boolean': 'bool',
- 'string': 'std::string',
+ 'number': 'double',
+ 'integer': 'int',
+ 'boolean': 'bool',
+ 'string': 'std::string',
}
return {
- 'return_type': typedefs[type],
- 'pass_type': typedefs[type],
- 'to_pass_type': '%s',
- 'to_raw_type': '%s',
- 'to_raw_return_type': '%s',
- 'type': typedefs[type],
- 'raw_type': typedefs[type],
- 'raw_pass_type': typedefs[type],
- 'raw_return_type': typedefs[type],
+ 'return_type': typedefs[type],
+ 'pass_type': typedefs[type],
+ 'to_pass_type': '%s',
+ 'to_raw_type': '%s',
+ 'to_raw_return_type': '%s',
+ 'type': typedefs[type],
+ 'raw_type': typedefs[type],
+ 'raw_pass_type': typedefs[type],
+ 'raw_return_type': typedefs[type],
}
@@ -229,15 +232,15 @@ type_definitions['any'] = CreateAnyTypeDefinition()
def WrapArrayDefinition(type):
return {
- 'return_type': 'std::vector<%s>' % type['type'],
- 'pass_type': 'std::vector<%s>' % type['type'],
- 'to_raw_type': '%s',
- 'to_raw_return_type': '&%s',
- 'to_pass_type': 'std::move(%s)',
- 'type': 'std::vector<%s>' % type['type'],
- 'raw_type': 'std::vector<%s>' % type['type'],
- 'raw_pass_type': 'std::vector<%s>*' % type['type'],
- 'raw_return_type': 'const std::vector<%s>*' % type['type'],
+ 'return_type': 'std::vector<%s>' % type['type'],
+ 'pass_type': 'std::vector<%s>' % type['type'],
+ 'to_raw_type': '%s',
+ 'to_raw_return_type': '&%s',
+ 'to_pass_type': 'std::move(%s)',
+ 'type': 'std::vector<%s>' % type['type'],
+ 'raw_type': 'std::vector<%s>' % type['type'],
+ 'raw_pass_type': 'std::vector<%s>*' % type['type'],
+ 'raw_return_type': 'const std::vector<%s>*' % type['type'],
}
@@ -301,7 +304,8 @@ def SynthesizeEnumType(domain, owner, type):
def SynthesizeCommandTypes(json_api):
"""Generate types for command parameters, return values and enum
- properties."""
+ properties.
+ """
for domain in json_api['domains']:
if not 'types' in domain:
domain['types'] = []
@@ -317,11 +321,11 @@ def SynthesizeCommandTypes(json_api):
if 'enum' in parameter and not '$ref' in parameter:
SynthesizeEnumType(domain, command['name'], parameter)
parameters_type = {
- 'id': ToTitleCase(command['name']) + 'Params',
- 'type': 'object',
- 'description': 'Parameters for the %s command.' % ToTitleCase(
- command['name']),
- 'properties': command['parameters']
+ 'id': ToTitleCase(command['name']) + 'Params',
+ 'type': 'object',
+ 'description': 'Parameters for the %s command.' % ToTitleCase(
+ command['name']),
+ 'properties': command['parameters']
}
domain['types'].append(parameters_type)
if 'returns' in command:
@@ -329,11 +333,11 @@ def SynthesizeCommandTypes(json_api):
if 'enum' in parameter and not '$ref' in parameter:
SynthesizeEnumType(domain, command['name'], parameter)
result_type = {
- 'id': ToTitleCase(command['name']) + 'Result',
- 'type': 'object',
- 'description': 'Result for the %s command.' % ToTitleCase(
- command['name']),
- 'properties': command['returns']
+ 'id': ToTitleCase(command['name']) + 'Result',
+ 'type': 'object',
+ 'description': 'Result for the %s command.' % ToTitleCase(
+ command['name']),
+ 'properties': command['returns']
}
domain['types'].append(result_type)
@@ -352,18 +356,57 @@ def SynthesizeEventTypes(json_api):
if 'enum' in parameter and not '$ref' in parameter:
SynthesizeEnumType(domain, event['name'], parameter)
event_type = {
- 'id': ToTitleCase(event['name']) + 'Params',
- 'type': 'object',
- 'description': 'Parameters for the %s event.' % ToTitleCase(
- event['name']),
- 'properties': event.get('parameters', [])
+ 'id': ToTitleCase(event['name']) + 'Params',
+ 'type': 'object',
+ 'description': 'Parameters for the %s event.' % ToTitleCase(
+ event['name']),
+ 'properties': event.get('parameters', [])
}
domain['types'].append(event_type)
+def InitializeDomainDependencies(json_api):
+ """For each domain create list of domains given domain depends on,
+ including itself."""
+
+ direct_deps = collections.defaultdict(set)
+
+ def GetDomainDepsFromRefs(domain_name, json):
+ if isinstance(json, list):
+ for value in json:
+ GetDomainDepsFromRefs(domain_name, value)
+ return
+
+ if not isinstance(json, dict):
+ return
+ for value in json.itervalues():
+ GetDomainDepsFromRefs(domain_name, value)
+
+ if '$ref' in json:
+ if '.' in json['$ref']:
+ dep = json['$ref'].split('.')[0]
+ direct_deps[domain_name].add(dep)
+
+ for domain in json_api['domains']:
+ direct_deps[domain['domain']] = set(domain.get('dependencies', []))
+ GetDomainDepsFromRefs(domain['domain'], domain)
+
+ def TraverseDependencies(domain, deps):
+ if domain in deps:
+ return
+ deps.add(domain)
+
+ for dep in direct_deps[domain]:
+ TraverseDependencies(dep, deps)
+
+ for domain in json_api['domains']:
+ domain_deps = set()
+ TraverseDependencies(domain['domain'], domain_deps)
+ domain['dependencies'] = sorted(domain_deps)
+
+
def PatchExperimentalCommandsAndEvents(json_api):
- """
- Mark all commands and events in experimental domains as experimental
+ """Mark all commands and events in experimental domains as experimental
and make sure experimental commands have at least empty parameters
and return values.
"""
@@ -375,10 +418,14 @@ def PatchExperimentalCommandsAndEvents(json_api):
event['experimental'] = True
+def EnsureDirectoryExists(path):
+ if not os.path.exists(path):
+ os.makedirs(path)
+
+
def EnsureCommandsHaveParametersAndReturnTypes(json_api):
- """
- Make sure all commands have at least empty parameters and return values. This
- guarantees API compatibility if a previously experimental command is made
+ """Make sure all commands have at least empty parameters and return values.
+ This guarantees API compatibility if a previously experimental command is made
stable.
"""
for domain in json_api['domains']:
@@ -392,46 +439,98 @@ def EnsureCommandsHaveParametersAndReturnTypes(json_api):
event['parameters'] = []
-def Generate(jinja_env, output_dirname, json_api, class_name, file_types):
+def Generate(jinja_env, output_dirname, json_api,
+ class_name, file_types, file_name=None):
+ if file_name is None:
+ file_name = class_name
+ EnsureDirectoryExists(output_dirname)
template_context = {
- 'api': json_api,
- 'join_arrays': JoinArrays,
- 'resolve_type': ResolveType,
- 'type_definition': TypeDefinition,
+ 'api': json_api,
+ 'join_arrays': JoinArrays,
+ 'resolve_type': ResolveType,
+ 'type_definition': TypeDefinition,
}
for file_type in file_types:
template = jinja_env.get_template('/%s_%s.template' % (
class_name, file_type))
- output_file = '%s/%s.%s' % (output_dirname, class_name, file_type)
+ output_file = '%s/%s.%s' % (output_dirname, file_name, file_type)
with open(output_file, 'w') as f:
f.write(template.render(template_context))
-def GenerateDomains(jinja_env, output_dirname, json_api, class_name,
- file_types):
+def GeneratePerDomain(jinja_env, output_dirname, json_api, class_name,
+ file_types, domain_name_to_file_name_func):
+ EnsureDirectoryExists(output_dirname)
for file_type in file_types:
template = jinja_env.get_template('/%s_%s.template' % (
class_name, file_type))
for domain in json_api['domains']:
template_context = {
- 'domain': domain,
- 'resolve_type': ResolveType,
+ 'domain': domain,
+ 'resolve_type': ResolveType,
}
domain_name = CamelCaseToHackerStyle(domain['domain'])
- output_file = '%s/%s.%s' % (output_dirname, domain_name, file_type)
+ output_file = '%s/%s.%s' % (output_dirname,
+ domain_name_to_file_name_func(domain_name),
+ file_type)
with open(output_file, 'w') as f:
f.write(template.render(template_context))
+def GenerateDomains(jinja_env, output_dirname, json_api):
+ GeneratePerDomain(
+ jinja_env, os.path.join(output_dirname, 'devtools', 'domains'), json_api,
+ 'domain', ['cc', 'h'],
+ lambda domain_name: domain_name)
+
+ # TODO(altimin): Remove this in 2017.
+ # Generate DOMAIN.h in the old directory for backwards compatibility.
+ GeneratePerDomain(
+ jinja_env, os.path.join(output_dirname, 'domains'), json_api,
+ 'deprecated_domain', ['h'], lambda domain_name: domain_name)
+
+
+def GenerateTypes(jinja_env, output_dirname, json_api):
+ # Generate forward declarations for types.
+ GeneratePerDomain(
+ jinja_env, os.path.join(output_dirname, 'devtools', 'internal'),
+ json_api, 'domain_types_forward_declaration', ['h'],
+ lambda domain_name: 'types_forward_declaration_%s' % (domain_name, ))
+ # Generate types on per-domain basis.
+ GeneratePerDomain(
+ jinja_env, os.path.join(output_dirname, 'devtools', 'domains'),
+ json_api, 'domain_types', ['h', 'cc'],
+ lambda domain_name: 'types_%s' % (domain_name, ))
+
+ # TODO(altimin): Remove this in 2017.
+ # Generate types.h for backwards compatibility.
+ Generate(jinja_env, os.path.join(output_dirname, 'domains'), json_api,
+ 'deprecated_types', ['h'], 'types')
+
+
+def GenerateTypeConversions(jinja_env, output_dirname, json_api):
+ # Generate type conversions on per-domain basis.
+ GeneratePerDomain(
+ jinja_env, os.path.join(output_dirname, 'devtools', 'internal'),
+ json_api, 'domain_type_conversions', ['h'],
+ lambda domain_name: 'type_conversions_%s' % (domain_name, ))
+
+ # TODO(altimin): Remove this in 2017.
+ # Generate type_conversions.h for backwards compatibility.
+ Generate(jinja_env, os.path.join(output_dirname, 'domains'), json_api,
+ 'deprecated_type_conversions', ['h'], 'type_conversions')
+
+
if __name__ == '__main__':
json_api, output_dirname = ParseArguments(sys.argv[1:])
jinja_env = InitializeJinjaEnv(output_dirname)
+ InitializeDomainDependencies(json_api)
PatchExperimentalCommandsAndEvents(json_api)
EnsureCommandsHaveParametersAndReturnTypes(json_api)
SynthesizeCommandTypes(json_api)
SynthesizeEventTypes(json_api)
PatchFullQualifiedRefs(json_api)
CreateTypeDefinitions(json_api)
- Generate(jinja_env, output_dirname, json_api, 'types', ['cc', 'h'])
- Generate(jinja_env, output_dirname, json_api, 'type_conversions', ['h'])
- GenerateDomains(jinja_env, output_dirname, json_api, 'domain', ['cc', 'h'])
+ GenerateDomains(jinja_env, output_dirname, json_api)
+ GenerateTypes(jinja_env, output_dirname, json_api)
+ GenerateTypeConversions(jinja_env, output_dirname, json_api)
diff --git a/chromium/headless/lib/browser/client_api_generator_unittest.py b/chromium/headless/lib/browser/devtools_api/client_api_generator_unittest.py
index d9d3f81dea7..f41ac0920a0 100644..100755
--- a/chromium/headless/lib/browser/client_api_generator_unittest.py
+++ b/chromium/headless/lib/browser/devtools_api/client_api_generator_unittest.py
@@ -1,8 +1,9 @@
+#!/usr/bin/env python
+
# 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.
-import argparse
import client_api_generator
import shutil
import sys
@@ -351,6 +352,65 @@ class ClientApiGeneratorTest(unittest.TestCase):
types = json_api['domains'][0]['types']
self.assertListEqual(types, expected_types)
+ def test_InitializeDomainDependencies(self):
+ json_api = {
+ 'domains': [
+ {
+ 'domain': 'Domain1',
+ 'types': [
+ {
+ 'id': 'TestType',
+ 'type': 'object',
+ 'properties': [
+ {'name': 'p1', 'type': 'object', '$ref': 'Domain2.TestType'},
+ ],
+ },
+ ],
+ },
+ {
+ 'domain': 'Domain2',
+ 'dependencies': ['Domain3'],
+ 'types': [
+ {
+ 'id': 'TestType',
+ 'type': 'object',
+ 'properties': [
+ {'name': 'p1', 'type': 'object', '$ref': 'Domain1.TestType'},
+ ],
+ },
+ ],
+ },
+ {
+ 'domain': 'Domain3',
+ },
+ {
+ 'domain': 'Domain4',
+ 'dependencies': ['Domain1'],
+ },
+ ]
+ }
+ client_api_generator.InitializeDomainDependencies(json_api)
+
+ dependencies = [ {
+ 'domain': domain['domain'],
+ 'dependencies': domain['dependencies']
+ } for domain in json_api['domains'] ]
+
+ self.assertListEqual(dependencies, [ {
+ "domain": "Domain1",
+ "dependencies": ["Domain1", "Domain2", "Domain3"],
+ }, {
+ "domain": "Domain2",
+ "dependencies": ["Domain1", "Domain2", "Domain3"],
+ }, {
+ "domain": "Domain3",
+ "dependencies": ["Domain3"],
+ }, {
+ "domain": "Domain4",
+ "dependencies": ["Domain1", "Domain2", "Domain3", "Domain4"],
+ }
+ ])
+
def test_PatchExperimentalDomains(self):
json_api = {
'domains': [
@@ -453,10 +513,9 @@ class ClientApiGeneratorTest(unittest.TestCase):
try:
dirname = tempfile.mkdtemp()
jinja_env = client_api_generator.InitializeJinjaEnv(dirname)
- client_api_generator.Generate(jinja_env, dirname, json_api, 'types',
- ['cc'])
- client_api_generator.Generate(jinja_env, dirname, json_api, 'types',
- ['h'])
+ client_api_generator.CreateTypeDefinitions(json_api)
+ client_api_generator.Generate(jinja_env, dirname, json_api,
+ 'deprecated_types', ['h'])
# This is just a smoke test; we don't actually verify the generated output
# here.
finally:
@@ -488,8 +547,9 @@ class ClientApiGeneratorTest(unittest.TestCase):
try:
dirname = tempfile.mkdtemp()
jinja_env = client_api_generator.InitializeJinjaEnv(dirname)
- client_api_generator.GenerateDomains(jinja_env, dirname, json_api,
- 'domain', ['cc', 'h'])
+ client_api_generator.GeneratePerDomain(
+ jinja_env, dirname, json_api,
+ 'domain', ['cc', 'h'], lambda domain_name: domain_name)
# This is just a smoke test; we don't actually verify the generated output
# here.
finally:
@@ -497,10 +557,4 @@ class ClientApiGeneratorTest(unittest.TestCase):
if __name__ == '__main__':
- cmdline_parser = argparse.ArgumentParser()
- cmdline_parser.add_argument('--stamp')
- args = cmdline_parser.parse_args()
- unittest.main(verbosity=2, exit=False, argv=sys.argv[:1])
- if args.stamp:
- with open(args.stamp, 'a') as f:
- pass
+ unittest.main(verbosity=2, exit=False, argv=sys.argv)
diff --git a/chromium/headless/lib/browser/devtools_api/deprecated_domain_h.template b/chromium/headless/lib/browser/devtools_api/deprecated_domain_h.template
new file mode 100644
index 00000000000..e430a104e8d
--- /dev/null
+++ b/chromium/headless/lib/browser/devtools_api/deprecated_domain_h.template
@@ -0,0 +1,7 @@
+// This file is generated
+
+// 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 "headless/public/devtools/domains/{{domain.domain | camelcase_to_hacker_style }}.h"
diff --git a/chromium/headless/lib/browser/devtools_api/deprecated_type_conversions_h.template b/chromium/headless/lib/browser/devtools_api/deprecated_type_conversions_h.template
new file mode 100644
index 00000000000..4e17400c6ce
--- /dev/null
+++ b/chromium/headless/lib/browser/devtools_api/deprecated_type_conversions_h.template
@@ -0,0 +1,14 @@
+// This file is generated
+
+// 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 HEADLESS_PUBLIC_DOMAINS_TYPE_CONVERSIONS_H_
+#define HEADLESS_PUBLIC_DOMAINS_TYPE_CONVERSIONS_H_
+
+{% for domain in api.domains %}
+#include "headless/public/devtools/internal/type_conversions_{{domain.domain | camelcase_to_hacker_style}}.h"
+{% endfor %}
+
+#endif // HEADLESS_PUBLIC_DOMAINS_TYPE_CONVERSIONS_H_
diff --git a/chromium/headless/lib/browser/devtools_api/deprecated_types_h.template b/chromium/headless/lib/browser/devtools_api/deprecated_types_h.template
new file mode 100644
index 00000000000..85b5379c5bf
--- /dev/null
+++ b/chromium/headless/lib/browser/devtools_api/deprecated_types_h.template
@@ -0,0 +1,14 @@
+// This file is generated
+
+// 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 HEADLESS_PUBLIC_DOMAINS_TYPES_H_
+#define HEADLESS_PUBLIC_DOMAINS_TYPES_H_
+
+{% for domain in api.domains %}
+#include "headless/public/devtools/domains/types_{{domain.domain | camelcase_to_hacker_style}}.h"
+{% endfor %}
+
+#endif // HEADLESS_PUBLIC_DOMAINS_TYPES_H_
diff --git a/chromium/headless/lib/browser/domain_cc.template b/chromium/headless/lib/browser/devtools_api/domain_cc.template
index 643afe749a8..88f28b1f56a 100644
--- a/chromium/headless/lib/browser/domain_cc.template
+++ b/chromium/headless/lib/browser/devtools_api/domain_cc.template
@@ -4,7 +4,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "headless/public/domains/{{domain.domain | camelcase_to_hacker_style}}.h"
+#include "headless/public/devtools/domains/{{domain.domain | camelcase_to_hacker_style}}.h"
#include "base/bind.h"
@@ -18,12 +18,26 @@ ExperimentalDomain* Domain::GetExperimental() {
{% if "events" in domain %}
void Domain::AddObserver(Observer* observer) {
+ RegisterEventHandlersIfNeeded();
observers_.AddObserver(observer);
}
void Domain::RemoveObserver(Observer* observer) {
observers_.RemoveObserver(observer);
}
+
+void Domain::RegisterEventHandlersIfNeeded() {
+ if (event_handlers_registered_)
+ return;
+ event_handlers_registered_ = true;
+ {# Register all events in this domain. #}
+ {% for event in domain.events %}
+ dispatcher_->RegisterEventHandler(
+ "{{domain.domain}}.{{event.name}}",
+ base::Bind(&Domain::Dispatch{{event.name | to_title_case}}Event,
+ base::Unretained(this)));
+ {% endfor %}
+}
{% endif %}
{% for command in domain.commands %}
@@ -102,22 +116,15 @@ void Domain::Dispatch{{event.name | to_title_case}}Event(const base::Value& para
ErrorReporter errors;
std::unique_ptr<{{event.name | to_title_case}}Params> parsed_params({{event.name | to_title_case}}Params::Parse(params, &errors));
DCHECK(!errors.HasErrors());
- FOR_EACH_OBSERVER(ExperimentalObserver, observers_, On{{event.name | to_title_case}}(*parsed_params));
+ for (ExperimentalObserver& observer : observers_) {
+ observer.On{{event.name | to_title_case}}(*parsed_params);
+ }
}
{% endfor %}
{% endif %}
Domain::Domain(internal::MessageDispatcher* dispatcher)
: dispatcher_(dispatcher) {
- {% if "events" in domain %}
- {# Register all events in this domain. #}
- {% for event in domain.events %}
- dispatcher_->RegisterEventHandler(
- "{{domain.domain}}.{{event.name}}",
- base::Bind(&Domain::Dispatch{{event.name | to_title_case}}Event,
- base::Unretained(this)));
- {% endfor %}
- {% endif %}
}
Domain::~Domain() {}
@@ -129,6 +136,7 @@ ExperimentalDomain::~ExperimentalDomain() {}
{% if "events" in domain %}
void ExperimentalDomain::AddObserver(ExperimentalObserver* observer) {
+ RegisterEventHandlersIfNeeded();
observers_.AddObserver(observer);
}
diff --git a/chromium/headless/lib/browser/domain_h.template b/chromium/headless/lib/browser/devtools_api/domain_h.template
index 2d146a70b52..73110412f43 100644
--- a/chromium/headless/lib/browser/domain_h.template
+++ b/chromium/headless/lib/browser/devtools_api/domain_h.template
@@ -4,13 +4,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef HEADLESS_PUBLIC_DOMAINS_{{domain.domain | camelcase_to_hacker_style | upper}}_H_
-#define HEADLESS_PUBLIC_DOMAINS_{{domain.domain | camelcase_to_hacker_style | upper}}_H_
+#ifndef HEADLESS_PUBLIC_DEVTOOLS_DOMAINS_{{domain.domain | camelcase_to_hacker_style | upper}}_H_
+#define HEADLESS_PUBLIC_DEVTOOLS_DOMAINS_{{domain.domain | camelcase_to_hacker_style | upper}}_H_
#include "base/callback.h"
#include "base/observer_list.h"
#include "base/values.h"
-#include "headless/public/domains/types.h"
+{% for domain_name in domain.dependencies %}
+#include "headless/public/devtools/domains/types_{{domain_name | camelcase_to_hacker_style}}.h"
+{% endfor %}
#include "headless/public/headless_export.h"
#include "headless/public/internal/message_dispatcher.h"
@@ -120,7 +122,16 @@ class HEADLESS_EXPORT Domain {
base::ObserverList<ExperimentalObserver> observers_;
{% endif %}
+ {% if "events" in domain %}
+ protected:
+ void RegisterEventHandlersIfNeeded();
+
+ {% endif %}
private:
+ {% if "events" in domain %}
+ bool event_handlers_registered_ = false;
+
+ {% endif %}
DISALLOW_COPY_AND_ASSIGN(Domain);
};
@@ -152,4 +163,4 @@ class ExperimentalDomain : public Domain {
} // namespace {{domain.domain | camelcase_to_hacker_style}}
} // namespace headless
-#endif // HEADLESS_PUBLIC_DOMAINS_{{domain.domain | camelcase_to_hacker_style | upper}}_H_
+#endif // HEADLESS_PUBLIC_DEVTOOLS_DOMAINS_{{domain.domain | camelcase_to_hacker_style | upper}}_H_
diff --git a/chromium/headless/lib/browser/type_conversions_h.template b/chromium/headless/lib/browser/devtools_api/domain_type_conversions_h.template
index 1c918ac9ea3..f14b423a66a 100644
--- a/chromium/headless/lib/browser/type_conversions_h.template
+++ b/chromium/headless/lib/browser/devtools_api/domain_type_conversions_h.template
@@ -4,33 +4,32 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef HEADLESS_PUBLIC_DOMAINS_TYPE_CONVERSIONS_H_
-#define HEADLESS_PUBLIC_DOMAINS_TYPE_CONVERSIONS_H_
+#ifndef HEADLESS_PUBLIC_DEVTOOLS_INTERNAL_TYPE_CONVERSIONS_{{domain.domain | camelcase_to_hacker_style | upper}}_H_
+#define HEADLESS_PUBLIC_DEVTOOLS_INTERNAL_TYPE_CONVERSIONS_{{domain.domain | camelcase_to_hacker_style | upper}}_H_
-#include "headless/public/domains/types.h"
+#include "headless/public/devtools/domains/types_{{domain.domain | camelcase_to_hacker_style}}.h"
#include "headless/public/internal/value_conversions.h"
namespace headless {
namespace internal {
-{% for domain in api.domains %}
- {% for type in domain.types %}
- {% set namespace = domain.domain | camelcase_to_hacker_style %}
- {% if "enum" in type %}
+{% for type in domain.types %}
+ {% set namespace = domain.domain | camelcase_to_hacker_style %}
+ {% if "enum" in type %}
template <>
struct FromValue<{{namespace}}::{{type.id}}> {
static {{namespace}}::{{type.id}} Parse(const base::Value& value, ErrorReporter* errors) {
- {% set default = namespace + '::' + type.id + '::' + type.enum[0] | sanitize_literal | dash_to_camelcase | camelcase_to_hacker_style | upper %}
+ {% set default = namespace + '::' + type.id + '::' + type.enum[0] | sanitize_literal | dash_to_camelcase | camelcase_to_hacker_style | upper %}
std::string string_value;
if (!value.GetAsString(&string_value)) {
errors->AddError("string enum value expected");
{# Return an arbitrary enum member -- the caller will just ignore it. #}
return {{default}};
}
- {% for literal in type.enum %}
+ {% for literal in type.enum %}
if (string_value == "{{literal}}")
return {{namespace}}::{{type.id}}::{{literal | sanitize_literal | dash_to_camelcase | camelcase_to_hacker_style | upper }};
- {% endfor %}
+ {% endfor %}
errors->AddError("invalid enum value");
return {{default}};
}
@@ -39,18 +38,18 @@ struct FromValue<{{namespace}}::{{type.id}}> {
template <typename T>
std::unique_ptr<base::Value> ToValueImpl(const {{namespace}}::{{type.id}}& value, T*) {
switch (value) {
- {% for literal in type.enum %}
+ {% for literal in type.enum %}
case {{namespace}}::{{type.id}}::{{literal | sanitize_literal | dash_to_camelcase | camelcase_to_hacker_style | upper }}:
return base::WrapUnique(new base::StringValue("{{literal}}"));
- {% endfor %}
+ {% endfor %}
};
NOTREACHED();
return nullptr;
}
- {% continue %}
- {% endif %}
+ {% continue %}
+ {% endif %}
- {% if not (type.type == "object") or not ("properties" in type) %}{% continue %}{% endif %}
+ {% if not (type.type == "object") or not ("properties" in type) %}{% continue %}{% endif %}
template <>
struct FromValue<{{namespace}}::{{type.id}}> {
static std::unique_ptr<{{namespace}}::{{type.id}}> Parse(const base::Value& value, ErrorReporter* errors) {
@@ -63,15 +62,9 @@ std::unique_ptr<base::Value> ToValueImpl(const {{namespace}}::{{type.id}}& value
return value.Serialize();
}
- {% endfor %}
{% endfor %}
-template <typename T>
-std::unique_ptr<base::Value> ToValue(const T& value) {
- return ToValueImpl(value, static_cast<T*>(nullptr));
-}
-
} // namespace internal
} // namespace headless
-#endif // HEADLESS_PUBLIC_DOMAINS_TYPE_CONVERSIONS_H_
+#endif // HEADLESS_PUBLIC_DEVTOOLS_INTERNAL_TYPE_CONVERSIONS_{{domain.domain | camelcase_to_hacker_style | upper}}_H_
diff --git a/chromium/headless/lib/browser/types_cc.template b/chromium/headless/lib/browser/devtools_api/domain_types_cc.template
index 5be72cf7924..bd1c2773dd4 100644
--- a/chromium/headless/lib/browser/types_cc.template
+++ b/chromium/headless/lib/browser/devtools_api/domain_types_cc.template
@@ -4,65 +4,29 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "headless/public/domains/types.h"
+{% for domain_name in domain.dependencies %}
+#include "headless/public/devtools/domains/types_{{domain_name | camelcase_to_hacker_style}}.h"
+{% endfor %}
#include "base/memory/ptr_util.h"
-#include "headless/public/domains/type_conversions.h"
+{% for dep in domain.dependencies %}
+#include "headless/public/devtools/internal/type_conversions_{{dep | camelcase_to_hacker_style}}.h"
+{% endfor %}
namespace headless {
-// ------------- Enum values from types.
-{% for domain in api.domains %}
- {% continue %}
-
namespace internal {
- {% for type in domain.types %}
-// {{type}}
- {% if type.type == "array" %}
-template <>
-struct FromValue<{{resolve_type(type).raw_type}}> {
- static {{resolve_type(type).raw_type}} Parse(const base::Value& value, ErrorReporter* errors) {
- {{resolve_type(type).raw_type}} result;
- const base::ListValue* list;
- if (!value.GetAsList(&list)) {
- errors->AddError("list value expected");
- return result;
- }
- errors->Push();
- for (const auto& item : *list)
- result.push_back(FromValue<{{resolve_type(type).raw_type}}::value_type>::Parse(*item, errors));
- errors->Pop();
- return result;
- }
-};
-
- {% continue %}
- {% endif %}
-#}
- {% if not (type.type == "object") or not ("properties" in type) %}{% continue %}{% endif %}
- {% set namespace = domain.domain | camelcase_to_hacker_style %}
-template <>
-struct FromValue<{{namespace}}::{{type.id}}> {
- static std::unique_ptr<{{namespace}}::{{type.id}}> Parse(const base::Value& value, ErrorReporter* errors) {
- return {{namespace}}::{{type.id}}::Parse(value, errors);
- }
-};
-
template <typename T>
-std::unique_ptr<base::Value> ToValueImpl(const {{namespace}}::{{type.id}}& value, T*) {
- return value.Serialize();
+std::unique_ptr<base::Value> ToValue(const T& value) {
+ return ToValueImpl(value, static_cast<T*>(nullptr));
}
- {% endfor %}
} // namespace internal
-{% endfor %}
-
-{% for domain in api.domains %}
namespace {{domain.domain | camelcase_to_hacker_style}} {
- {% for type in domain.types %}
- {% if not (type.type == "object") or not ("properties" in type) %}{% continue %}{% endif %}
+{% for type in domain.types %}
+ {% if not (type.type == "object") or not ("properties" in type) %}{% continue %}{% endif %}
std::unique_ptr<{{type.id}}> {{type.id}}::Parse(const base::Value& value, ErrorReporter* errors) {
errors->Push();
@@ -77,24 +41,24 @@ std::unique_ptr<{{type.id}}> {{type.id}}::Parse(const base::Value& value, ErrorR
std::unique_ptr<{{type.id}}> result(new {{type.id}}());
errors->Push();
errors->SetName("{{type.id}}");
- {% for property in type.properties %}
- {% set value_name = property.name | camelcase_to_hacker_style + "_value" %}
+ {% for property in type.properties %}
+ {% set value_name = property.name | camelcase_to_hacker_style + "_value" %}
const base::Value* {{value_name}};
if (object->Get("{{property.name}}", &{{value_name}})) {
errors->SetName("{{property.name}}");
- {% if property.optional %}
+ {% if property.optional %}
result->{{property.name | camelcase_to_hacker_style}}_ = internal::FromValue<{{resolve_type(property).raw_type}}>::Parse(*{{value_name}}, errors);
- {% else %}
+ {% else %}
result->{{property.name | camelcase_to_hacker_style}}_ = internal::FromValue<{{resolve_type(property).raw_type}}>::Parse(*{{value_name}}, errors);
- {% endif %}
- {% if property.optional %}
+ {% endif %}
+ {% if property.optional %}
}
- {% else %}
+ {% else %}
} else {
errors->AddError("required property missing: {{property.name}}");
}
- {% endif %}
- {% endfor %}
+ {% endif %}
+ {% endfor %}
errors->Pop();
errors->Pop();
if (errors->HasErrors())
@@ -104,15 +68,15 @@ std::unique_ptr<{{type.id}}> {{type.id}}::Parse(const base::Value& value, ErrorR
std::unique_ptr<base::Value> {{type.id}}::Serialize() const {
std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue());
- {% for property in type.properties %}
- {% set type = resolve_type(property) %}
- {% if property.optional %}
+ {% for property in type.properties %}
+ {% set type = resolve_type(property) %}
+ {% if property.optional %}
if ({{property.name | camelcase_to_hacker_style}}_)
result->Set("{{property.name}}", internal::ToValue({{type.to_raw_type % ("%s_.value()" % property.name | camelcase_to_hacker_style)}}));
- {% else %}
+ {% else %}
result->Set("{{property.name}}", internal::ToValue({{type.to_raw_type % ("%s_" % property.name | camelcase_to_hacker_style)}}));
- {% endif %}
- {% endfor %}
+ {% endif %}
+ {% endfor %}
return std::move(result);
}
@@ -123,8 +87,7 @@ std::unique_ptr<{{type.id}}> {{type.id}}::Clone() const {
return result;
}
- {% endfor %}
-} // namespace {{domain.domain | camelcase_to_hacker_style}}
{% endfor %}
-} // namespace headless
+} // namespace {{domain.domain | camelcase_to_hacker_style}}
+} // namespace headless
diff --git a/chromium/headless/lib/browser/devtools_api/domain_types_forward_declaration_h.template b/chromium/headless/lib/browser/devtools_api/domain_types_forward_declaration_h.template
new file mode 100644
index 00000000000..4bb223b04ab
--- /dev/null
+++ b/chromium/headless/lib/browser/devtools_api/domain_types_forward_declaration_h.template
@@ -0,0 +1,44 @@
+// This file is generated
+
+// Copyright (c) 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 HEADLESS_PUBLIC_DEVTOOLS_INTERNAL_TYPES_FORWARD_DECLARATION_{{domain.domain | camelcase_to_hacker_style | upper}}_H_
+#define HEADLESS_PUBLIC_DEVTOOLS_INTERNAL_TYPES_FORWARD_DECLARATION_{{domain.domain | camelcase_to_hacker_style | upper}}_H_
+
+#include "base/optional.h"
+#include "base/values.h"
+#include "headless/public/headless_export.h"
+#include "headless/public/util/error_reporter.h"
+
+#include "base/memory/ptr_util.h"
+
+namespace headless {
+
+namespace {{domain.domain | camelcase_to_hacker_style}} {
+{% for type in domain.types %}
+ {% if type.type == "object" %}
+ {% if "properties" in type %}
+class {{type.id}};
+ {% else %}
+using {{type.id}} = base::Value;
+ {% endif %}
+ {% endif %}
+{% endfor %}
+
+{% for type in domain.types %}
+ {% if "enum" in type %}
+enum class {{type.id}} {
+ {% for literal in type.enum %}
+ {{ literal | sanitize_literal | dash_to_camelcase | camelcase_to_hacker_style | upper }}{{',' if not loop.last}}
+ {% endfor %}
+};
+
+ {% endif %}
+{% endfor %}
+} // namespace {{domain.domain | camelcase_to_hacker_style}}
+
+} // namespace headless
+
+#endif // HEADLESS_PUBLIC_DEVTOOLS_INTERNAL_TYPES_FORWARD_DECLARATION_{{domain.domain | camelcase_to_hacker_style | upper}}_H_
diff --git a/chromium/headless/lib/browser/types_h.template b/chromium/headless/lib/browser/devtools_api/domain_types_h.template
index 84b09cbeb24..f53f8ae1a52 100644
--- a/chromium/headless/lib/browser/types_h.template
+++ b/chromium/headless/lib/browser/devtools_api/domain_types_h.template
@@ -4,11 +4,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef HEADLESS_PUBLIC_DOMAINS_TYPES_H_
-#define HEADLESS_PUBLIC_DOMAINS_TYPES_H_
+#ifndef HEADLESS_PUBLIC_DEVTOOLS_DOMAINS_TYPES_{{domain.domain | camelcase_to_hacker_style | upper}}_H_
+#define HEADLESS_PUBLIC_DEVTOOLS_DOMAINS_TYPES_{{domain.domain | camelcase_to_hacker_style | upper}}_H_
#include "base/optional.h"
#include "base/values.h"
+{% for domain_name in domain.dependencies %}
+#include "headless/public/devtools/internal/types_forward_declaration_{{domain_name | camelcase_to_hacker_style}}.h"
+{% endfor %}
#include "headless/public/headless_export.h"
#include "headless/public/util/error_reporter.h"
@@ -16,67 +19,31 @@
namespace headless {
-// ------------- Forward declarations and typedefs.
-
-{% for domain in api.domains %}
-
-namespace {{domain.domain | camelcase_to_hacker_style}} {
- {% for type in domain.types %}
- {% if type.type == "object" %}
- {% if "properties" in type %}
-class {{type.id}};
- {% else %}
-using {{type.id}} = base::Value;
- {% endif %}
- {% endif %}
- {% endfor %}
-} // namespace {{domain.domain}}
-{% endfor %}
-
-{% for domain in api.domains %}
namespace {{domain.domain | camelcase_to_hacker_style}} {
- {% for type in domain.types %}
- {% if "enum" in type %}
-enum class {{type.id}} {
- {% for literal in type.enum %}
- {{ literal | sanitize_literal | dash_to_camelcase | camelcase_to_hacker_style | upper }}{{',' if not loop.last}}
- {% endfor %}
-};
-
- {% endif %}
- {% endfor %}
-} // namespace {{domain.domain | camelcase_to_hacker_style}}
-
-{% endfor %}
-
-// ------------- Type and builder declarations.
-{% for domain in api.domains %}
+{% for type in domain.types %}
+ {% if not (type.type == "object") or not ("properties" in type) %}{% continue %}{% endif %}
-namespace {{domain.domain | camelcase_to_hacker_style}} {
- {% for type in domain.types %}
- {% if not (type.type == "object") or not ("properties" in type) %}{% continue %}{% endif %}
-
- {% if type.description %}
+ {% if type.description %}
// {{type.description}}
- {% endif %}
+ {% endif %}
class HEADLESS_EXPORT {{type.id}} {
public:
static {{resolve_type(type).pass_type}} Parse(const base::Value& value, ErrorReporter* errors);
~{{type.id}}() { }
- {% for property in type.properties %}
+ {% for property in type.properties %}
- {% if property.description %}
+ {% if property.description %}
// {{property.description}}
- {% endif %}
- {% if property.optional %}
+ {% endif %}
+ {% if property.optional %}
bool Has{{property.name | to_title_case}}() const { return !!{{property.name | camelcase_to_hacker_style}}_; }
{{resolve_type(property).raw_return_type}} Get{{property.name | to_title_case}}() const { DCHECK(Has{{property.name | to_title_case}}()); return {{resolve_type(property).to_raw_return_type % ("%s_.value()" % property.name | camelcase_to_hacker_style)}}; }
void Set{{property.name | to_title_case}}({{resolve_type(property).pass_type}} value) { {{property.name | camelcase_to_hacker_style}}_ = {{resolve_type(property).to_pass_type % 'value'}}; }
- {% else %}
+ {% else %}
{{resolve_type(property).raw_return_type}} Get{{property.name | to_title_case}}() const { return {{resolve_type(property).to_raw_return_type % ("%s_" % property.name | camelcase_to_hacker_style)}}; }
void Set{{property.name | to_title_case}}({{resolve_type(property).pass_type}} value) { {{property.name | camelcase_to_hacker_style}}_ = {{resolve_type(property).to_pass_type % 'value'}}; }
- {% endif %}
- {% endfor %}
+ {% endif %}
+ {% endfor %}
std::unique_ptr<base::Value> Serialize() const;
{{resolve_type(type).pass_type}} Clone() const;
@@ -86,34 +53,34 @@ class HEADLESS_EXPORT {{type.id}} {
public:
enum {
kNoFieldsSet = 0,
- {% set count = 0 %}
- {% for property in type.properties %}
- {% if not(property.optional) %}
- {% set count = count + 1 %}
+ {% set count = 0 %}
+ {% for property in type.properties %}
+ {% if not(property.optional) %}
+ {% set count = count + 1 %}
k{{property.name | to_title_case}}Set = 1 << {{count}},
- {% endif %}
- {% endfor %}
+ {% endif %}
+ {% endfor %}
kAllRequiredFieldsSet = (
- {%- for property in type.properties %}
- {% if not(property.optional) %}k{{property.name | to_title_case}}Set | {%endif %}
- {% endfor %}0)
+ {%- for property in type.properties %}
+ {% if not(property.optional) %}k{{property.name | to_title_case}}Set | {%endif %}
+ {% endfor %}0)
};
- {% for property in type.properties %}
- {% if property.optional %}
+ {% for property in type.properties %}
+ {% if property.optional %}
{{type.id}}Builder<STATE>& Set{{property.name | to_title_case}}({{resolve_type(property).pass_type}} value) {
result_->Set{{property.name | to_title_case}}({{resolve_type(property).to_pass_type % 'value'}});
return *this;
}
- {% else %}
+ {% else %}
{{type.id}}Builder<STATE | k{{property.name | to_title_case}}Set>& Set{{property.name | to_title_case}}({{resolve_type(property).pass_type}} value) {
static_assert(!(STATE & k{{property.name | to_title_case}}Set), "property {{property.name}} should not have already been set");
result_->Set{{property.name | to_title_case}}({{resolve_type(property).to_pass_type % 'value'}});
return CastState<k{{property.name | to_title_case}}Set>();
}
- {% endif %}
+ {% endif %}
- {% endfor %}
+ {% endfor %}
{{resolve_type(type).pass_type}} Build() {
static_assert(STATE == kAllRequiredFieldsSet, "all required fields should have been set");
return std::move(result_);
@@ -137,22 +104,21 @@ class HEADLESS_EXPORT {{type.id}} {
private:
{{type.id}}() { }
- {% for property in type.properties %}
- {% if property.optional %}
+ {% for property in type.properties %}
+ {% if property.optional %}
base::Optional<{{resolve_type(property).type}}> {{property.name | camelcase_to_hacker_style}}_;
- {% else %}
+ {% else %}
{{resolve_type(property).type}} {{property.name | camelcase_to_hacker_style}}_;
- {% endif %}
- {% endfor %}
+ {% endif %}
+ {% endfor %}
DISALLOW_COPY_AND_ASSIGN({{type.id}});
};
- {% endfor %}
+{% endfor %}
} // namespace {{domain.domain | camelcase_to_hacker_style}}
-{% endfor %}
} // namespace headless
-#endif // HEADLESS_PUBLIC_DOMAINS_TYPES_H_
+#endif // HEADLESS_PUBLIC_DEVTOOLS_DOMAINS_TYPES_{{domain.domain | camelcase_to_hacker_style | upper}}_H_
diff --git a/chromium/headless/lib/browser/headless_browser_impl.cc b/chromium/headless/lib/browser/headless_browser_impl.cc
index 98fcac84ed3..c1647257fd3 100644
--- a/chromium/headless/lib/browser/headless_browser_impl.cc
+++ b/chromium/headless/lib/browser/headless_browser_impl.cc
@@ -18,7 +18,7 @@
#include "headless/lib/browser/headless_browser_context_impl.h"
#include "headless/lib/browser/headless_browser_main_parts.h"
#include "headless/lib/browser/headless_web_contents_impl.h"
-#include "headless/lib/browser/headless_window_tree_client.h"
+#include "headless/lib/browser/headless_window_parenting_client.h"
#include "headless/lib/headless_content_main_delegate.h"
#include "ui/aura/env.h"
#include "ui/aura/window_tree_host.h"
@@ -123,8 +123,8 @@ void HeadlessBrowserImpl::RunOnStartCallback() {
aura::WindowTreeHost::Create(gfx::Rect(options()->window_size)));
window_tree_host_->InitHost();
- window_tree_client_.reset(
- new HeadlessWindowTreeClient(window_tree_host_->window()));
+ window_parenting_client_.reset(
+ new HeadlessWindowParentingClient(window_tree_host_->window()));
on_start_callback_.Run(this);
on_start_callback_ = base::Callback<void(HeadlessBrowser*)>();
diff --git a/chromium/headless/lib/browser/headless_browser_impl.h b/chromium/headless/lib/browser/headless_browser_impl.h
index a31391816c0..74a4b6c29cf 100644
--- a/chromium/headless/lib/browser/headless_browser_impl.h
+++ b/chromium/headless/lib/browser/headless_browser_impl.h
@@ -20,7 +20,7 @@ namespace aura {
class WindowTreeHost;
namespace client {
-class WindowTreeClient;
+class WindowParentingClient;
}
}
@@ -78,7 +78,7 @@ class HeadlessBrowserImpl : public HeadlessBrowser {
// is used for all web contents. We should probably use one
// window per web contents, but additional investigation is needed.
std::unique_ptr<aura::WindowTreeHost> window_tree_host_;
- std::unique_ptr<aura::client::WindowTreeClient> window_tree_client_;
+ std::unique_ptr<aura::client::WindowParentingClient> window_parenting_client_;
std::unordered_map<std::string, std::unique_ptr<HeadlessBrowserContextImpl>>
browser_contexts_;
diff --git a/chromium/headless/lib/browser/headless_browser_manifest_overlay_template.json b/chromium/headless/lib/browser/headless_browser_manifest_overlay_template.json
new file mode 100644
index 00000000000..d5e3e9943c0
--- /dev/null
+++ b/chromium/headless/lib/browser/headless_browser_manifest_overlay_template.json
@@ -0,0 +1,10 @@
+{
+ "name": "content_browser",
+ "interface_provider_specs": {
+ "navigation:frame": {
+ "provides": {
+ "renderer": []
+ }
+ }
+ }
+}
diff --git a/chromium/headless/lib/browser/headless_content_browser_client.cc b/chromium/headless/lib/browser/headless_content_browser_client.cc
index 4b59e918e5c..1bfe88ff8cb 100644
--- a/chromium/headless/lib/browser/headless_content_browser_client.cc
+++ b/chromium/headless/lib/browser/headless_content_browser_client.cc
@@ -5,20 +5,30 @@
#include "headless/lib/browser/headless_content_browser_client.h"
#include <memory>
+#include <unordered_set>
#include "base/callback.h"
+#include "base/json/json_reader.h"
#include "base/memory/ptr_util.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
+#include "content/public/common/service_names.mojom.h"
+#include "headless/grit/headless_lib_resources.h"
#include "headless/lib/browser/headless_browser_context_impl.h"
#include "headless/lib/browser/headless_browser_impl.h"
#include "headless/lib/browser/headless_browser_main_parts.h"
#include "headless/lib/browser/headless_devtools_manager_delegate.h"
+#include "ui/base/resource/resource_bundle.h"
namespace headless {
+namespace {
+const char kCapabilityPath[] =
+ "interface_provider_specs.navigation:frame.provides.renderer";
+} // namespace
+
HeadlessContentBrowserClient::HeadlessContentBrowserClient(
HeadlessBrowserImpl* browser)
: browser_(browser) {}
@@ -49,4 +59,31 @@ HeadlessContentBrowserClient::GetDevToolsManagerDelegate() {
return new HeadlessDevToolsManagerDelegate(browser_->GetWeakPtr());
}
+std::unique_ptr<base::Value>
+HeadlessContentBrowserClient::GetServiceManifestOverlay(
+ const std::string& name) {
+ if (name != content::mojom::kBrowserServiceName ||
+ browser_->options()->mojo_service_names.empty())
+ return nullptr;
+
+ base::StringPiece manifest_template =
+ ui::ResourceBundle::GetSharedInstance().GetRawDataResource(
+ IDR_HEADLESS_BROWSER_MANIFEST_OVERLAY_TEMPLATE);
+ std::unique_ptr<base::Value> manifest =
+ base::JSONReader::Read(manifest_template);
+
+ // Add mojo_service_names to renderer capability specified in options.
+ base::DictionaryValue* manifest_dictionary = nullptr;
+ CHECK(manifest->GetAsDictionary(&manifest_dictionary));
+
+ base::ListValue* capability_list = nullptr;
+ CHECK(manifest_dictionary->GetList(kCapabilityPath, &capability_list));
+
+ for (std::string service_name : browser_->options()->mojo_service_names) {
+ capability_list->AppendString(service_name);
+ }
+
+ return manifest;
+}
+
} // namespace headless
diff --git a/chromium/headless/lib/browser/headless_content_browser_client.h b/chromium/headless/lib/browser/headless_content_browser_client.h
index 0bd58b12246..8e9651e9d21 100644
--- a/chromium/headless/lib/browser/headless_content_browser_client.h
+++ b/chromium/headless/lib/browser/headless_content_browser_client.h
@@ -24,6 +24,8 @@ class HeadlessContentBrowserClient : public content::ContentBrowserClient {
void OverrideWebkitPrefs(content::RenderViewHost* render_view_host,
content::WebPreferences* prefs) override;
content::DevToolsManagerDelegate* GetDevToolsManagerDelegate() override;
+ std::unique_ptr<base::Value> GetServiceManifestOverlay(
+ const std::string& name) override;
private:
HeadlessBrowserImpl* browser_; // Not owned.
diff --git a/chromium/headless/lib/browser/headless_devtools_client_impl.cc b/chromium/headless/lib/browser/headless_devtools_client_impl.cc
index a669e1e5b1d..833b9dc49af 100644
--- a/chromium/headless/lib/browser/headless_devtools_client_impl.cc
+++ b/chromium/headless/lib/browser/headless_devtools_client_impl.cc
@@ -35,7 +35,6 @@ HeadlessDevToolsClientImpl::HeadlessDevToolsClientImpl()
accessibility_domain_(this),
animation_domain_(this),
application_cache_domain_(this),
- browser_domain_(this),
cache_storage_domain_(this),
console_domain_(this),
css_domain_(this),
@@ -61,8 +60,8 @@ HeadlessDevToolsClientImpl::HeadlessDevToolsClientImpl()
runtime_domain_(this),
security_domain_(this),
service_worker_domain_(this),
+ target_domain_(this),
tracing_domain_(this),
- worker_domain_(this),
browser_main_thread_(content::BrowserThread::GetTaskRunnerForThread(
content::BrowserThread::UI)),
weak_ptr_factory_(this) {}
@@ -181,10 +180,6 @@ application_cache::Domain* HeadlessDevToolsClientImpl::GetApplicationCache() {
return &application_cache_domain_;
}
-browser::Domain* HeadlessDevToolsClientImpl::GetBrowser() {
- return &browser_domain_;
-}
-
cache_storage::Domain* HeadlessDevToolsClientImpl::GetCacheStorage() {
return &cache_storage_domain_;
}
@@ -285,12 +280,12 @@ service_worker::Domain* HeadlessDevToolsClientImpl::GetServiceWorker() {
return &service_worker_domain_;
}
-tracing::Domain* HeadlessDevToolsClientImpl::GetTracing() {
- return &tracing_domain_;
+target::Domain* HeadlessDevToolsClientImpl::GetTarget() {
+ return &target_domain_;
}
-worker::Domain* HeadlessDevToolsClientImpl::GetWorker() {
- return &worker_domain_;
+tracing::Domain* HeadlessDevToolsClientImpl::GetTracing() {
+ return &tracing_domain_;
}
template <typename CallbackType>
diff --git a/chromium/headless/lib/browser/headless_devtools_client_impl.h b/chromium/headless/lib/browser/headless_devtools_client_impl.h
index 619825d28ba..3ee800b13e8 100644
--- a/chromium/headless/lib/browser/headless_devtools_client_impl.h
+++ b/chromium/headless/lib/browser/headless_devtools_client_impl.h
@@ -10,37 +10,36 @@
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "content/public/browser/devtools_agent_host_client.h"
-#include "headless/public/domains/accessibility.h"
-#include "headless/public/domains/animation.h"
-#include "headless/public/domains/application_cache.h"
-#include "headless/public/domains/browser.h"
-#include "headless/public/domains/cache_storage.h"
-#include "headless/public/domains/console.h"
-#include "headless/public/domains/css.h"
-#include "headless/public/domains/database.h"
-#include "headless/public/domains/debugger.h"
-#include "headless/public/domains/device_orientation.h"
-#include "headless/public/domains/dom.h"
-#include "headless/public/domains/dom_debugger.h"
-#include "headless/public/domains/dom_storage.h"
-#include "headless/public/domains/emulation.h"
-#include "headless/public/domains/heap_profiler.h"
-#include "headless/public/domains/indexeddb.h"
-#include "headless/public/domains/input.h"
-#include "headless/public/domains/inspector.h"
-#include "headless/public/domains/io.h"
-#include "headless/public/domains/layer_tree.h"
-#include "headless/public/domains/log.h"
-#include "headless/public/domains/memory.h"
-#include "headless/public/domains/network.h"
-#include "headless/public/domains/page.h"
-#include "headless/public/domains/profiler.h"
-#include "headless/public/domains/rendering.h"
-#include "headless/public/domains/runtime.h"
-#include "headless/public/domains/security.h"
-#include "headless/public/domains/service_worker.h"
-#include "headless/public/domains/tracing.h"
-#include "headless/public/domains/worker.h"
+#include "headless/public/devtools/domains/accessibility.h"
+#include "headless/public/devtools/domains/animation.h"
+#include "headless/public/devtools/domains/application_cache.h"
+#include "headless/public/devtools/domains/cache_storage.h"
+#include "headless/public/devtools/domains/console.h"
+#include "headless/public/devtools/domains/css.h"
+#include "headless/public/devtools/domains/database.h"
+#include "headless/public/devtools/domains/debugger.h"
+#include "headless/public/devtools/domains/device_orientation.h"
+#include "headless/public/devtools/domains/dom.h"
+#include "headless/public/devtools/domains/dom_debugger.h"
+#include "headless/public/devtools/domains/dom_storage.h"
+#include "headless/public/devtools/domains/emulation.h"
+#include "headless/public/devtools/domains/heap_profiler.h"
+#include "headless/public/devtools/domains/indexeddb.h"
+#include "headless/public/devtools/domains/input.h"
+#include "headless/public/devtools/domains/inspector.h"
+#include "headless/public/devtools/domains/io.h"
+#include "headless/public/devtools/domains/layer_tree.h"
+#include "headless/public/devtools/domains/log.h"
+#include "headless/public/devtools/domains/memory.h"
+#include "headless/public/devtools/domains/network.h"
+#include "headless/public/devtools/domains/page.h"
+#include "headless/public/devtools/domains/profiler.h"
+#include "headless/public/devtools/domains/rendering.h"
+#include "headless/public/devtools/domains/runtime.h"
+#include "headless/public/devtools/domains/security.h"
+#include "headless/public/devtools/domains/service_worker.h"
+#include "headless/public/devtools/domains/target.h"
+#include "headless/public/devtools/domains/tracing.h"
#include "headless/public/headless_devtools_client.h"
#include "headless/public/internal/message_dispatcher.h"
@@ -67,7 +66,6 @@ class HeadlessDevToolsClientImpl : public HeadlessDevToolsClient,
accessibility::Domain* GetAccessibility() override;
animation::Domain* GetAnimation() override;
application_cache::Domain* GetApplicationCache() override;
- browser::Domain* GetBrowser() override;
cache_storage::Domain* GetCacheStorage() override;
console::Domain* GetConsole() override;
css::Domain* GetCSS() override;
@@ -93,8 +91,8 @@ class HeadlessDevToolsClientImpl : public HeadlessDevToolsClient,
runtime::Domain* GetRuntime() override;
security::Domain* GetSecurity() override;
service_worker::Domain* GetServiceWorker() override;
+ target::Domain* GetTarget() override;
tracing::Domain* GetTracing() override;
- worker::Domain* GetWorker() override;
// content::DevToolstAgentHostClient implementation:
void DispatchProtocolMessage(content::DevToolsAgentHost* agent_host,
@@ -168,7 +166,6 @@ class HeadlessDevToolsClientImpl : public HeadlessDevToolsClient,
accessibility::ExperimentalDomain accessibility_domain_;
animation::ExperimentalDomain animation_domain_;
application_cache::ExperimentalDomain application_cache_domain_;
- browser::ExperimentalDomain browser_domain_;
cache_storage::ExperimentalDomain cache_storage_domain_;
console::ExperimentalDomain console_domain_;
css::ExperimentalDomain css_domain_;
@@ -194,8 +191,8 @@ class HeadlessDevToolsClientImpl : public HeadlessDevToolsClient,
runtime::ExperimentalDomain runtime_domain_;
security::ExperimentalDomain security_domain_;
service_worker::ExperimentalDomain service_worker_domain_;
+ target::ExperimentalDomain target_domain_;
tracing::ExperimentalDomain tracing_domain_;
- worker::ExperimentalDomain worker_domain_;
scoped_refptr<base::SingleThreadTaskRunner> browser_main_thread_;
base::WeakPtrFactory<HeadlessDevToolsClientImpl> weak_ptr_factory_;
diff --git a/chromium/headless/lib/browser/headless_devtools_manager_delegate.cc b/chromium/headless/lib/browser/headless_devtools_manager_delegate.cc
index a53e8c773df..0c82f334ab8 100644
--- a/chromium/headless/lib/browser/headless_devtools_manager_delegate.cc
+++ b/chromium/headless/lib/browser/headless_devtools_manager_delegate.cc
@@ -15,7 +15,7 @@
#include "headless/lib/browser/headless_browser_context_impl.h"
#include "headless/lib/browser/headless_browser_impl.h"
#include "headless/lib/browser/headless_web_contents_impl.h"
-#include "headless/public/domains/browser.h"
+#include "headless/public/devtools/domains/target.h"
#include "ui/base/resource/resource_bundle.h"
namespace headless {
@@ -23,13 +23,13 @@ namespace headless {
HeadlessDevToolsManagerDelegate::HeadlessDevToolsManagerDelegate(
base::WeakPtr<HeadlessBrowserImpl> browser)
: browser_(std::move(browser)), default_browser_context_(nullptr) {
- command_map_["Browser.createTarget"] =
+ command_map_["Target.createTarget"] =
&HeadlessDevToolsManagerDelegate::CreateTarget;
- command_map_["Browser.closeTarget"] =
+ command_map_["Target.closeTarget"] =
&HeadlessDevToolsManagerDelegate::CloseTarget;
- command_map_["Browser.createBrowserContext"] =
+ command_map_["Target.createBrowserContext"] =
&HeadlessDevToolsManagerDelegate::CreateBrowserContext;
- command_map_["Browser.disposeBrowserContext"] =
+ command_map_["Target.disposeBrowserContext"] =
&HeadlessDevToolsManagerDelegate::DisposeBrowserContext;
}
@@ -103,7 +103,7 @@ std::unique_ptr<base::Value> HeadlessDevToolsManagerDelegate::CreateTarget(
.SetWindowSize(gfx::Size(width, height))
.Build());
- return browser::CreateTargetResult::Builder()
+ return target::CreateTargetResult::Builder()
.SetTargetId(web_contents_impl->GetDevToolsAgentHostId())
.Build()
->Serialize();
@@ -122,7 +122,7 @@ std::unique_ptr<base::Value> HeadlessDevToolsManagerDelegate::CloseTarget(
web_contents->Close();
success = true;
}
- return browser::CloseTargetResult::Builder()
+ return target::CloseTargetResult::Builder()
.SetSuccess(success)
.Build()
->Serialize();
@@ -135,7 +135,7 @@ HeadlessDevToolsManagerDelegate::CreateBrowserContext(
browser_->CreateBrowserContextBuilder().Build();
std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue());
- return browser::CreateBrowserContextResult::Builder()
+ return target::CreateBrowserContextResult::Builder()
.SetBrowserContextId(browser_context->Id())
.Build()
->Serialize();
@@ -158,7 +158,7 @@ HeadlessDevToolsManagerDelegate::DisposeBrowserContext(
context->Close();
}
- return browser::DisposeBrowserContextResult::Builder()
+ return target::DisposeBrowserContextResult::Builder()
.SetSuccess(success)
.Build()
->Serialize();
diff --git a/chromium/headless/lib/browser/headless_screen.cc b/chromium/headless/lib/browser/headless_screen.cc
index c8be18bfdb1..be86924d2e3 100644
--- a/chromium/headless/lib/browser/headless_screen.cc
+++ b/chromium/headless/lib/browser/headless_screen.cc
@@ -12,7 +12,6 @@
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/ime/input_method.h"
-#include "ui/display/screen.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/gfx/native_widget_types.h"
@@ -37,7 +36,8 @@ HeadlessScreen::~HeadlessScreen() {}
aura::WindowTreeHost* HeadlessScreen::CreateHostForPrimaryDisplay() {
DCHECK(!host_);
- host_ = aura::WindowTreeHost::Create(gfx::Rect(display_.GetSizeInPixel()));
+ host_ = aura::WindowTreeHost::Create(
+ gfx::Rect(GetPrimaryDisplay().GetSizeInPixel()));
// Some tests don't correctly manage window focus/activation states.
// Makes sure InputMethod is default focused so that IME basics can work.
host_->GetInputMethod()->OnFocus();
@@ -47,50 +47,59 @@ aura::WindowTreeHost* HeadlessScreen::CreateHostForPrimaryDisplay() {
}
void HeadlessScreen::SetDeviceScaleFactor(float device_scale_factor) {
- gfx::Rect bounds_in_pixel(display_.GetSizeInPixel());
- display_.SetScaleAndBounds(device_scale_factor, bounds_in_pixel);
+ display::Display display(GetPrimaryDisplay());
+ gfx::Rect bounds_in_pixel(display.GetSizeInPixel());
+ display.SetScaleAndBounds(device_scale_factor, bounds_in_pixel);
+ display_list().UpdateDisplay(display);
}
void HeadlessScreen::SetDisplayRotation(display::Display::Rotation rotation) {
- gfx::Rect bounds_in_pixel(display_.GetSizeInPixel());
+ display::Display display(GetPrimaryDisplay());
+ gfx::Rect bounds_in_pixel(display.GetSizeInPixel());
gfx::Rect new_bounds(bounds_in_pixel);
- if (IsRotationPortrait(rotation) != IsRotationPortrait(display_.rotation())) {
+ if (IsRotationPortrait(rotation) != IsRotationPortrait(display.rotation())) {
new_bounds.set_width(bounds_in_pixel.height());
new_bounds.set_height(bounds_in_pixel.width());
}
- display_.set_rotation(rotation);
- display_.SetScaleAndBounds(display_.device_scale_factor(), new_bounds);
+ display.set_rotation(rotation);
+ display.SetScaleAndBounds(display.device_scale_factor(), new_bounds);
+ display_list().UpdateDisplay(display);
host_->SetRootTransform(GetRotationTransform() * GetUIScaleTransform());
}
void HeadlessScreen::SetUIScale(float ui_scale) {
ui_scale_ = ui_scale;
- gfx::Rect bounds_in_pixel(display_.GetSizeInPixel());
+ display::Display display(GetPrimaryDisplay());
+ gfx::Rect bounds_in_pixel(display.GetSizeInPixel());
gfx::Rect new_bounds = gfx::ToNearestRect(
gfx::ScaleRect(gfx::RectF(bounds_in_pixel), 1.0f / ui_scale));
- display_.SetScaleAndBounds(display_.device_scale_factor(), new_bounds);
+ display.SetScaleAndBounds(display.device_scale_factor(), new_bounds);
+ display_list().UpdateDisplay(display);
host_->SetRootTransform(GetRotationTransform() * GetUIScaleTransform());
}
void HeadlessScreen::SetWorkAreaInsets(const gfx::Insets& insets) {
- display_.UpdateWorkAreaFromInsets(insets);
+ display::Display display(GetPrimaryDisplay());
+ display.UpdateWorkAreaFromInsets(insets);
+ display_list().UpdateDisplay(display);
}
gfx::Transform HeadlessScreen::GetRotationTransform() const {
gfx::Transform rotate;
- switch (display_.rotation()) {
+ display::Display display(GetPrimaryDisplay());
+ switch (display.rotation()) {
case display::Display::ROTATE_0:
break;
case display::Display::ROTATE_90:
- rotate.Translate(display_.bounds().height(), 0);
+ rotate.Translate(display.bounds().height(), 0);
rotate.Rotate(90);
break;
case display::Display::ROTATE_270:
- rotate.Translate(0, display_.bounds().width());
+ rotate.Translate(0, display.bounds().width());
rotate.Rotate(270);
break;
case display::Display::ROTATE_180:
- rotate.Translate(display_.bounds().width(), display_.bounds().height());
+ rotate.Translate(display.bounds().width(), display.bounds().height());
rotate.Rotate(180);
break;
}
@@ -108,8 +117,10 @@ void HeadlessScreen::OnWindowBoundsChanged(aura::Window* window,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds) {
DCHECK_EQ(host_->window(), window);
- display_.SetSize(gfx::ScaleToFlooredSize(new_bounds.size(),
- display_.device_scale_factor()));
+ display::Display display(GetPrimaryDisplay());
+ display.SetSize(gfx::ScaleToFlooredSize(new_bounds.size(),
+ display.device_scale_factor()));
+ display_list().UpdateDisplay(display);
}
void HeadlessScreen::OnWindowDestroying(aura::Window* window) {
@@ -132,42 +143,17 @@ gfx::NativeWindow HeadlessScreen::GetWindowAtScreenPoint(
return host_->window()->GetTopWindowContainingPoint(point);
}
-int HeadlessScreen::GetNumDisplays() const {
- return 1;
-}
-
-std::vector<display::Display> HeadlessScreen::GetAllDisplays() const {
- return std::vector<display::Display>(1, display_);
-}
-
display::Display HeadlessScreen::GetDisplayNearestWindow(
gfx::NativeWindow window) const {
- return display_;
-}
-
-display::Display HeadlessScreen::GetDisplayNearestPoint(
- const gfx::Point& point) const {
- return display_;
+ return GetPrimaryDisplay();
}
-display::Display HeadlessScreen::GetDisplayMatching(
- const gfx::Rect& match_rect) const {
- return display_;
-}
-
-display::Display HeadlessScreen::GetPrimaryDisplay() const {
- return display_;
-}
-
-void HeadlessScreen::AddObserver(display::DisplayObserver* observer) {}
-
-void HeadlessScreen::RemoveObserver(display::DisplayObserver* observer) {}
-
HeadlessScreen::HeadlessScreen(const gfx::Rect& screen_bounds)
: host_(NULL), ui_scale_(1.0f) {
static int64_t synthesized_display_id = 2000;
- display_.set_id(synthesized_display_id++);
- display_.SetScaleAndBounds(1.0f, screen_bounds);
+ display::Display display(synthesized_display_id++);
+ display.SetScaleAndBounds(1.0f, screen_bounds);
+ ProcessDisplayChanged(display, true /* is_primary */);
}
} // namespace headless
diff --git a/chromium/headless/lib/browser/headless_screen.h b/chromium/headless/lib/browser/headless_screen.h
index 962fc9c61b8..ed9e388f079 100644
--- a/chromium/headless/lib/browser/headless_screen.h
+++ b/chromium/headless/lib/browser/headless_screen.h
@@ -9,7 +9,7 @@
#include "base/macros.h"
#include "ui/aura/window_observer.h"
#include "ui/display/display.h"
-#include "ui/display/screen.h"
+#include "ui/display/screen_base.h"
namespace gfx {
class Insets;
@@ -19,13 +19,13 @@ class Transform;
namespace aura {
class Window;
-class WindowTreeClient;
+class WindowParentingClient;
class WindowTreeHost;
}
namespace headless {
-class HeadlessScreen : public display::Screen, public aura::WindowObserver {
+class HeadlessScreen : public display::ScreenBase, public aura::WindowObserver {
public:
// Creates a display::Screen of the specified size (physical pixels).
static HeadlessScreen* Create(const gfx::Size& size);
@@ -52,22 +52,12 @@ class HeadlessScreen : public display::Screen, public aura::WindowObserver {
gfx::Point GetCursorScreenPoint() override;
bool IsWindowUnderCursor(gfx::NativeWindow window) override;
gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point) override;
- int GetNumDisplays() const override;
- std::vector<display::Display> GetAllDisplays() const override;
display::Display GetDisplayNearestWindow(gfx::NativeView view) const override;
- display::Display GetDisplayNearestPoint(
- const gfx::Point& point) const override;
- display::Display GetDisplayMatching(
- const gfx::Rect& match_rect) const override;
- display::Display GetPrimaryDisplay() const override;
- void AddObserver(display::DisplayObserver* observer) override;
- void RemoveObserver(display::DisplayObserver* observer) override;
private:
explicit HeadlessScreen(const gfx::Rect& screen_bounds);
aura::WindowTreeHost* host_;
- display::Display display_;
float ui_scale_;
DISALLOW_COPY_AND_ASSIGN(HeadlessScreen);
diff --git a/chromium/headless/lib/browser/headless_web_contents_impl.cc b/chromium/headless/lib/browser/headless_web_contents_impl.cc
index 20865a3da63..dfdf31b30db 100644
--- a/chromium/headless/lib/browser/headless_web_contents_impl.cc
+++ b/chromium/headless/lib/browser/headless_web_contents_impl.cc
@@ -13,6 +13,8 @@
#include "base/memory/weak_ptr.h"
#include "base/strings/utf_string_conversions.h"
#include "base/trace_event/trace_event.h"
+#include "components/security_state/content/content_utils.h"
+#include "components/security_state/core/security_state.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/navigation_handle.h"
@@ -23,12 +25,13 @@
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/common/bindings_policy.h"
+#include "content/public/common/origin_util.h"
#include "content/public/renderer/render_frame.h"
#include "headless/lib/browser/headless_browser_context_impl.h"
#include "headless/lib/browser/headless_browser_impl.h"
#include "headless/lib/browser/headless_browser_main_parts.h"
#include "headless/lib/browser/headless_devtools_client_impl.h"
-#include "services/shell/public/cpp/interface_registry.h"
+#include "services/service_manager/public/cpp/interface_registry.h"
#include "ui/aura/window.h"
namespace headless {
@@ -80,6 +83,21 @@ class HeadlessWebContentsImpl::Delegate : public content::WebContentsDelegate {
browser_context_->RegisterWebContents(std::move(web_contents));
}
+ // Return the security style of the given |web_contents|, populating
+ // |security_style_explanations| to explain why the SecurityStyle was chosen.
+ blink::WebSecurityStyle GetSecurityStyle(
+ content::WebContents* web_contents,
+ content::SecurityStyleExplanations* security_style_explanations)
+ override {
+ security_state::SecurityInfo security_info;
+ security_state::GetSecurityInfo(
+ security_state::GetVisibleSecurityState(web_contents),
+ false /* used_policy_installed_certificate */,
+ base::Bind(&content::IsOriginSecure), &security_info);
+ return security_state::GetSecurityStyle(security_info,
+ security_style_explanations);
+ }
+
private:
HeadlessBrowserContextImpl* browser_context_; // Not owned.
DISALLOW_COPY_AND_ASSIGN(Delegate);
@@ -154,7 +172,7 @@ void HeadlessWebContentsImpl::RenderFrameCreated(
content::BINDINGS_POLICY_HEADLESS);
}
- shell::InterfaceRegistry* interface_registry =
+ service_manager::InterfaceRegistry* interface_registry =
render_frame_host->GetInterfaceRegistry();
for (const MojoService& service : mojo_services_) {
diff --git a/chromium/headless/lib/browser/headless_window_parenting_client.cc b/chromium/headless/lib/browser/headless_window_parenting_client.cc
new file mode 100644
index 00000000000..e27da578895
--- /dev/null
+++ b/chromium/headless/lib/browser/headless_window_parenting_client.cc
@@ -0,0 +1,28 @@
+// 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 "headless/lib/browser/headless_window_parenting_client.h"
+
+#include "ui/aura/window.h"
+
+namespace headless {
+
+HeadlessWindowParentingClient::HeadlessWindowParentingClient(
+ aura::Window* root_window)
+ : root_window_(root_window) {
+ aura::client::SetWindowParentingClient(root_window_, this);
+}
+
+HeadlessWindowParentingClient::~HeadlessWindowParentingClient() {
+ aura::client::SetWindowParentingClient(root_window_, nullptr);
+}
+
+aura::Window* HeadlessWindowParentingClient::GetDefaultParent(
+ aura::Window* context,
+ aura::Window* window,
+ const gfx::Rect& bounds) {
+ return root_window_;
+}
+
+} // namespace headless
diff --git a/chromium/headless/lib/browser/headless_window_parenting_client.h b/chromium/headless/lib/browser/headless_window_parenting_client.h
new file mode 100644
index 00000000000..1694080fd3f
--- /dev/null
+++ b/chromium/headless/lib/browser/headless_window_parenting_client.h
@@ -0,0 +1,31 @@
+// 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 HEADLESS_LIB_BROWSER_HEADLESS_WINDOW_PARENTING_CLIENT_H_
+#define HEADLESS_LIB_BROWSER_HEADLESS_WINDOW_PARENTING_CLIENT_H_
+
+#include "base/macros.h"
+#include "ui/aura/client/window_parenting_client.h"
+
+namespace headless {
+
+class HeadlessWindowParentingClient
+ : public aura::client::WindowParentingClient {
+ public:
+ explicit HeadlessWindowParentingClient(aura::Window* root_window);
+ ~HeadlessWindowParentingClient() override;
+
+ aura::Window* GetDefaultParent(aura::Window* context,
+ aura::Window* window,
+ const gfx::Rect& bounds) override;
+
+ private:
+ aura::Window* root_window_; // Not owned.
+
+ DISALLOW_COPY_AND_ASSIGN(HeadlessWindowParentingClient);
+};
+
+} // namespace headless
+
+#endif // HEADLESS_LIB_BROWSER_HEADLESS_WINDOW_PARENTING_CLIENT_H_
diff --git a/chromium/headless/lib/browser/headless_window_tree_client.cc b/chromium/headless/lib/browser/headless_window_tree_client.cc
deleted file mode 100644
index be797ce3032..00000000000
--- a/chromium/headless/lib/browser/headless_window_tree_client.cc
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 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 "headless/lib/browser/headless_window_tree_client.h"
-
-#include "ui/aura/window.h"
-
-namespace headless {
-
-HeadlessWindowTreeClient::HeadlessWindowTreeClient(aura::Window* root_window)
- : root_window_(root_window) {
- aura::client::SetWindowTreeClient(root_window_, this);
-}
-
-HeadlessWindowTreeClient::~HeadlessWindowTreeClient() {
- aura::client::SetWindowTreeClient(root_window_, nullptr);
-}
-
-aura::Window* HeadlessWindowTreeClient::GetDefaultParent(
- aura::Window* context,
- aura::Window* window,
- const gfx::Rect& bounds) {
- return root_window_;
-}
-
-} // namespace headless
diff --git a/chromium/headless/lib/browser/headless_window_tree_client.h b/chromium/headless/lib/browser/headless_window_tree_client.h
deleted file mode 100644
index c64e3daf92b..00000000000
--- a/chromium/headless/lib/browser/headless_window_tree_client.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 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 HEADLESS_LIB_BROWSER_HEADLESS_WINDOW_TREE_CLIENT_H_
-#define HEADLESS_LIB_BROWSER_HEADLESS_WINDOW_TREE_CLIENT_H_
-
-#include "base/macros.h"
-#include "ui/aura/client/window_tree_client.h"
-
-namespace headless {
-
-class HeadlessWindowTreeClient : public aura::client::WindowTreeClient {
- public:
- explicit HeadlessWindowTreeClient(aura::Window* root_window);
- ~HeadlessWindowTreeClient() override;
-
- aura::Window* GetDefaultParent(aura::Window* context,
- aura::Window* window,
- const gfx::Rect& bounds) override;
-
- private:
- aura::Window* root_window_; // Not owned.
-
- DISALLOW_COPY_AND_ASSIGN(HeadlessWindowTreeClient);
-};
-
-} // namespace headless
-
-#endif // HEADLESS_LIB_BROWSER_HEADLESS_WINDOW_TREE_CLIENT_H_
diff --git a/chromium/headless/lib/embedder_mojo_browsertest.cc b/chromium/headless/lib/embedder_mojo_browsertest.cc
index a8338e04801..3fb4ed1a5f5 100644
--- a/chromium/headless/lib/embedder_mojo_browsertest.cc
+++ b/chromium/headless/lib/embedder_mojo_browsertest.cc
@@ -5,14 +5,15 @@
#include <memory>
#include "base/optional.h"
#include "base/path_service.h"
+#include "base/strings/string_piece.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread_restrictions.h"
#include "content/public/test/browser_test.h"
#include "headless/grit/headless_browsertest_resources.h"
#include "headless/lib/embedder_test.mojom.h"
-#include "headless/public/domains/network.h"
-#include "headless/public/domains/page.h"
-#include "headless/public/domains/runtime.h"
+#include "headless/public/devtools/domains/network.h"
+#include "headless/public/devtools/domains/page.h"
+#include "headless/public/devtools/domains/runtime.h"
#include "headless/public/headless_browser.h"
#include "headless/public/headless_devtools_client.h"
#include "headless/public/headless_devtools_target.h"
@@ -49,6 +50,13 @@ class EmbedderMojoTest : public HeadlessBrowserTest,
~EmbedderMojoTest() override {}
+ void SetUp() override {
+ // Set service names before they are used during main thread initialization.
+ options()->mojo_service_names.insert("embedder_test::TestEmbedderService");
+
+ HeadlessBrowserTest::SetUp();
+ }
+
void SetUpOnMainThread() override {
base::ThreadRestrictions::SetIOAllowed(true);
base::FilePath pak_path;
diff --git a/chromium/headless/lib/headless_browser_browsertest.cc b/chromium/headless/lib/headless_browser_browsertest.cc
index 77796ffe349..0bbf976849c 100644
--- a/chromium/headless/lib/headless_browser_browsertest.cc
+++ b/chromium/headless/lib/headless_browser_browsertest.cc
@@ -10,8 +10,8 @@
#include "base/strings/stringprintf.h"
#include "base/threading/thread_restrictions.h"
#include "content/public/test/browser_test.h"
-#include "headless/public/domains/network.h"
-#include "headless/public/domains/page.h"
+#include "headless/public/devtools/domains/network.h"
+#include "headless/public/devtools/domains/page.h"
#include "headless/public/headless_browser.h"
#include "headless/public/headless_devtools_client.h"
#include "headless/public/headless_devtools_target.h"
diff --git a/chromium/headless/lib/headless_devtools_client_browsertest.cc b/chromium/headless/lib/headless_devtools_client_browsertest.cc
index 5188e74c404..26252d8a7fd 100644
--- a/chromium/headless/lib/headless_devtools_client_browsertest.cc
+++ b/chromium/headless/lib/headless_devtools_client_browsertest.cc
@@ -9,11 +9,11 @@
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test.h"
#include "headless/lib/browser/headless_web_contents_impl.h"
-#include "headless/public/domains/browser.h"
-#include "headless/public/domains/emulation.h"
-#include "headless/public/domains/network.h"
-#include "headless/public/domains/page.h"
-#include "headless/public/domains/runtime.h"
+#include "headless/public/devtools/domains/emulation.h"
+#include "headless/public/devtools/domains/network.h"
+#include "headless/public/devtools/domains/page.h"
+#include "headless/public/devtools/domains/runtime.h"
+#include "headless/public/devtools/domains/target.h"
#include "headless/public/headless_browser.h"
#include "headless/public/headless_devtools_client.h"
#include "headless/public/headless_devtools_target.h"
@@ -218,25 +218,25 @@ class HeadlessDevToolsClientExperimentalTest
HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessDevToolsClientExperimentalTest);
-class BrowserDomainCreateAndDeletePageTest
+class TargetDomainCreateAndDeletePageTest
: public HeadlessAsyncDevTooledBrowserTest {
void RunDevTooledTest() override {
EXPECT_TRUE(embedded_test_server()->Start());
EXPECT_EQ(1u, GetAllWebContents(browser()).size());
- devtools_client_->GetBrowser()->GetExperimental()->CreateTarget(
- browser::CreateTargetParams::Builder()
+ devtools_client_->GetTarget()->GetExperimental()->CreateTarget(
+ target::CreateTargetParams::Builder()
.SetUrl(embedded_test_server()->GetURL("/hello.html").spec())
.SetWidth(1)
.SetHeight(1)
.Build(),
- base::Bind(&BrowserDomainCreateAndDeletePageTest::OnCreateTargetResult,
+ base::Bind(&TargetDomainCreateAndDeletePageTest::OnCreateTargetResult,
base::Unretained(this)));
}
void OnCreateTargetResult(
- std::unique_ptr<browser::CreateTargetResult> result) {
+ std::unique_ptr<target::CreateTargetResult> result) {
EXPECT_EQ(2u, GetAllWebContents(browser()).size());
HeadlessWebContentsImpl* contents = HeadlessWebContentsImpl::From(
@@ -246,81 +246,81 @@ class BrowserDomainCreateAndDeletePageTest
->GetViewBounds()
.size());
- devtools_client_->GetBrowser()->GetExperimental()->CloseTarget(
- browser::CloseTargetParams::Builder()
+ devtools_client_->GetTarget()->GetExperimental()->CloseTarget(
+ target::CloseTargetParams::Builder()
.SetTargetId(result->GetTargetId())
.Build(),
- base::Bind(&BrowserDomainCreateAndDeletePageTest::OnCloseTargetResult,
+ base::Bind(&TargetDomainCreateAndDeletePageTest::OnCloseTargetResult,
base::Unretained(this)));
}
- void OnCloseTargetResult(std::unique_ptr<browser::CloseTargetResult> result) {
+ void OnCloseTargetResult(std::unique_ptr<target::CloseTargetResult> result) {
EXPECT_TRUE(result->GetSuccess());
EXPECT_EQ(1u, GetAllWebContents(browser()).size());
FinishAsynchronousTest();
}
};
-HEADLESS_ASYNC_DEVTOOLED_TEST_F(BrowserDomainCreateAndDeletePageTest);
+HEADLESS_ASYNC_DEVTOOLED_TEST_F(TargetDomainCreateAndDeletePageTest);
-class BrowserDomainCreateAndDeleteBrowserContextTest
+class TargetDomainCreateAndDeleteBrowserContextTest
: public HeadlessAsyncDevTooledBrowserTest {
void RunDevTooledTest() override {
EXPECT_TRUE(embedded_test_server()->Start());
EXPECT_EQ(1u, GetAllWebContents(browser()).size());
- devtools_client_->GetBrowser()->GetExperimental()->CreateBrowserContext(
- browser::CreateBrowserContextParams::Builder().Build(),
- base::Bind(&BrowserDomainCreateAndDeleteBrowserContextTest::
+ devtools_client_->GetTarget()->GetExperimental()->CreateBrowserContext(
+ target::CreateBrowserContextParams::Builder().Build(),
+ base::Bind(&TargetDomainCreateAndDeleteBrowserContextTest::
OnCreateContextResult,
base::Unretained(this)));
}
void OnCreateContextResult(
- std::unique_ptr<browser::CreateBrowserContextResult> result) {
+ std::unique_ptr<target::CreateBrowserContextResult> result) {
browser_context_id_ = result->GetBrowserContextId();
- devtools_client_->GetBrowser()->GetExperimental()->CreateTarget(
- browser::CreateTargetParams::Builder()
+ devtools_client_->GetTarget()->GetExperimental()->CreateTarget(
+ target::CreateTargetParams::Builder()
.SetUrl(embedded_test_server()->GetURL("/hello.html").spec())
.SetBrowserContextId(result->GetBrowserContextId())
.SetWidth(1)
.SetHeight(1)
.Build(),
- base::Bind(&BrowserDomainCreateAndDeleteBrowserContextTest::
+ base::Bind(&TargetDomainCreateAndDeleteBrowserContextTest::
OnCreateTargetResult,
base::Unretained(this)));
}
void OnCreateTargetResult(
- std::unique_ptr<browser::CreateTargetResult> result) {
+ std::unique_ptr<target::CreateTargetResult> result) {
EXPECT_EQ(2u, GetAllWebContents(browser()).size());
- devtools_client_->GetBrowser()->GetExperimental()->CloseTarget(
- browser::CloseTargetParams::Builder()
+ devtools_client_->GetTarget()->GetExperimental()->CloseTarget(
+ target::CloseTargetParams::Builder()
.SetTargetId(result->GetTargetId())
.Build(),
- base::Bind(&BrowserDomainCreateAndDeleteBrowserContextTest::
+ base::Bind(&TargetDomainCreateAndDeleteBrowserContextTest::
OnCloseTargetResult,
base::Unretained(this)));
}
- void OnCloseTargetResult(std::unique_ptr<browser::CloseTargetResult> result) {
+ void OnCloseTargetResult(std::unique_ptr<target::CloseTargetResult> result) {
EXPECT_EQ(1u, GetAllWebContents(browser()).size());
EXPECT_TRUE(result->GetSuccess());
- devtools_client_->GetBrowser()->GetExperimental()->DisposeBrowserContext(
- browser::DisposeBrowserContextParams::Builder()
+ devtools_client_->GetTarget()->GetExperimental()->DisposeBrowserContext(
+ target::DisposeBrowserContextParams::Builder()
.SetBrowserContextId(browser_context_id_)
.Build(),
- base::Bind(&BrowserDomainCreateAndDeleteBrowserContextTest::
+ base::Bind(&TargetDomainCreateAndDeleteBrowserContextTest::
OnDisposeBrowserContextResult,
base::Unretained(this)));
}
void OnDisposeBrowserContextResult(
- std::unique_ptr<browser::DisposeBrowserContextResult> result) {
+ std::unique_ptr<target::DisposeBrowserContextResult> result) {
EXPECT_TRUE(result->GetSuccess());
FinishAsynchronousTest();
}
@@ -329,73 +329,73 @@ class BrowserDomainCreateAndDeleteBrowserContextTest
std::string browser_context_id_;
};
-HEADLESS_ASYNC_DEVTOOLED_TEST_F(BrowserDomainCreateAndDeleteBrowserContextTest);
+HEADLESS_ASYNC_DEVTOOLED_TEST_F(TargetDomainCreateAndDeleteBrowserContextTest);
-class BrowserDomainDisposeContextFailsIfInUse
+class TargetDomainDisposeContextFailsIfInUse
: public HeadlessAsyncDevTooledBrowserTest {
void RunDevTooledTest() override {
EXPECT_TRUE(embedded_test_server()->Start());
EXPECT_EQ(1u, GetAllWebContents(browser()).size());
- devtools_client_->GetBrowser()->GetExperimental()->CreateBrowserContext(
- browser::CreateBrowserContextParams::Builder().Build(),
- base::Bind(&BrowserDomainDisposeContextFailsIfInUse::OnContextCreated,
+ devtools_client_->GetTarget()->GetExperimental()->CreateBrowserContext(
+ target::CreateBrowserContextParams::Builder().Build(),
+ base::Bind(&TargetDomainDisposeContextFailsIfInUse::OnContextCreated,
base::Unretained(this)));
}
void OnContextCreated(
- std::unique_ptr<browser::CreateBrowserContextResult> result) {
+ std::unique_ptr<target::CreateBrowserContextResult> result) {
context_id_ = result->GetBrowserContextId();
- devtools_client_->GetBrowser()->GetExperimental()->CreateTarget(
- browser::CreateTargetParams::Builder()
+ devtools_client_->GetTarget()->GetExperimental()->CreateTarget(
+ target::CreateTargetParams::Builder()
.SetUrl(embedded_test_server()->GetURL("/hello.html").spec())
.SetBrowserContextId(context_id_)
.Build(),
base::Bind(
- &BrowserDomainDisposeContextFailsIfInUse::OnCreateTargetResult,
+ &TargetDomainDisposeContextFailsIfInUse::OnCreateTargetResult,
base::Unretained(this)));
}
void OnCreateTargetResult(
- std::unique_ptr<browser::CreateTargetResult> result) {
+ std::unique_ptr<target::CreateTargetResult> result) {
page_id_ = result->GetTargetId();
- devtools_client_->GetBrowser()->GetExperimental()->DisposeBrowserContext(
- browser::DisposeBrowserContextParams::Builder()
+ devtools_client_->GetTarget()->GetExperimental()->DisposeBrowserContext(
+ target::DisposeBrowserContextParams::Builder()
.SetBrowserContextId(context_id_)
.Build(),
- base::Bind(&BrowserDomainDisposeContextFailsIfInUse::
+ base::Bind(&TargetDomainDisposeContextFailsIfInUse::
OnDisposeBrowserContextResult,
base::Unretained(this)));
}
void OnDisposeBrowserContextResult(
- std::unique_ptr<browser::DisposeBrowserContextResult> result) {
+ std::unique_ptr<target::DisposeBrowserContextResult> result) {
EXPECT_FALSE(result->GetSuccess());
// Close the page and try again.
- devtools_client_->GetBrowser()->GetExperimental()->CloseTarget(
- browser::CloseTargetParams::Builder().SetTargetId(page_id_).Build(),
+ devtools_client_->GetTarget()->GetExperimental()->CloseTarget(
+ target::CloseTargetParams::Builder().SetTargetId(page_id_).Build(),
base::Bind(
- &BrowserDomainDisposeContextFailsIfInUse::OnCloseTargetResult,
+ &TargetDomainDisposeContextFailsIfInUse::OnCloseTargetResult,
base::Unretained(this)));
}
- void OnCloseTargetResult(std::unique_ptr<browser::CloseTargetResult> result) {
+ void OnCloseTargetResult(std::unique_ptr<target::CloseTargetResult> result) {
EXPECT_TRUE(result->GetSuccess());
- devtools_client_->GetBrowser()->GetExperimental()->DisposeBrowserContext(
- browser::DisposeBrowserContextParams::Builder()
+ devtools_client_->GetTarget()->GetExperimental()->DisposeBrowserContext(
+ target::DisposeBrowserContextParams::Builder()
.SetBrowserContextId(context_id_)
.Build(),
- base::Bind(&BrowserDomainDisposeContextFailsIfInUse::
+ base::Bind(&TargetDomainDisposeContextFailsIfInUse::
OnDisposeBrowserContextResult2,
base::Unretained(this)));
}
void OnDisposeBrowserContextResult2(
- std::unique_ptr<browser::DisposeBrowserContextResult> result) {
+ std::unique_ptr<target::DisposeBrowserContextResult> result) {
EXPECT_TRUE(result->GetSuccess());
FinishAsynchronousTest();
}
@@ -405,34 +405,34 @@ class BrowserDomainDisposeContextFailsIfInUse
std::string page_id_;
};
-HEADLESS_ASYNC_DEVTOOLED_TEST_F(BrowserDomainDisposeContextFailsIfInUse);
+HEADLESS_ASYNC_DEVTOOLED_TEST_F(TargetDomainDisposeContextFailsIfInUse);
-class BrowserDomainCreateTwoContexts : public HeadlessAsyncDevTooledBrowserTest,
- public browser::ExperimentalObserver {
+class TargetDomainCreateTwoContexts : public HeadlessAsyncDevTooledBrowserTest,
+ public target::ExperimentalObserver {
public:
void RunDevTooledTest() override {
EXPECT_TRUE(embedded_test_server()->Start());
- devtools_client_->GetBrowser()->GetExperimental()->AddObserver(this);
- devtools_client_->GetBrowser()->GetExperimental()->CreateBrowserContext(
- browser::CreateBrowserContextParams::Builder().Build(),
- base::Bind(&BrowserDomainCreateTwoContexts::OnContextOneCreated,
+ devtools_client_->GetTarget()->GetExperimental()->AddObserver(this);
+ devtools_client_->GetTarget()->GetExperimental()->CreateBrowserContext(
+ target::CreateBrowserContextParams::Builder().Build(),
+ base::Bind(&TargetDomainCreateTwoContexts::OnContextOneCreated,
base::Unretained(this)));
- devtools_client_->GetBrowser()->GetExperimental()->CreateBrowserContext(
- browser::CreateBrowserContextParams::Builder().Build(),
- base::Bind(&BrowserDomainCreateTwoContexts::OnContextTwoCreated,
+ devtools_client_->GetTarget()->GetExperimental()->CreateBrowserContext(
+ target::CreateBrowserContextParams::Builder().Build(),
+ base::Bind(&TargetDomainCreateTwoContexts::OnContextTwoCreated,
base::Unretained(this)));
}
void OnContextOneCreated(
- std::unique_ptr<browser::CreateBrowserContextResult> result) {
+ std::unique_ptr<target::CreateBrowserContextResult> result) {
context_id_one_ = result->GetBrowserContextId();
MaybeCreatePages();
}
void OnContextTwoCreated(
- std::unique_ptr<browser::CreateBrowserContextResult> result) {
+ std::unique_ptr<target::CreateBrowserContextResult> result) {
context_id_two_ = result->GetBrowserContextId();
MaybeCreatePages();
}
@@ -441,31 +441,31 @@ class BrowserDomainCreateTwoContexts : public HeadlessAsyncDevTooledBrowserTest,
if (context_id_one_.empty() || context_id_two_.empty())
return;
- devtools_client_->GetBrowser()->GetExperimental()->CreateTarget(
- browser::CreateTargetParams::Builder()
+ devtools_client_->GetTarget()->GetExperimental()->CreateTarget(
+ target::CreateTargetParams::Builder()
.SetUrl(embedded_test_server()->GetURL("/hello.html").spec())
.SetBrowserContextId(context_id_one_)
.Build(),
- base::Bind(&BrowserDomainCreateTwoContexts::OnCreateTargetOneResult,
+ base::Bind(&TargetDomainCreateTwoContexts::OnCreateTargetOneResult,
base::Unretained(this)));
- devtools_client_->GetBrowser()->GetExperimental()->CreateTarget(
- browser::CreateTargetParams::Builder()
+ devtools_client_->GetTarget()->GetExperimental()->CreateTarget(
+ target::CreateTargetParams::Builder()
.SetUrl(embedded_test_server()->GetURL("/hello.html").spec())
.SetBrowserContextId(context_id_two_)
.Build(),
- base::Bind(&BrowserDomainCreateTwoContexts::OnCreateTargetTwoResult,
+ base::Bind(&TargetDomainCreateTwoContexts::OnCreateTargetTwoResult,
base::Unretained(this)));
}
void OnCreateTargetOneResult(
- std::unique_ptr<browser::CreateTargetResult> result) {
+ std::unique_ptr<target::CreateTargetResult> result) {
page_id_one_ = result->GetTargetId();
MaybeTestIsolation();
}
void OnCreateTargetTwoResult(
- std::unique_ptr<browser::CreateTargetResult> result) {
+ std::unique_ptr<target::CreateTargetResult> result) {
page_id_two_ = result->GetTargetId();
MaybeTestIsolation();
}
@@ -474,28 +474,34 @@ class BrowserDomainCreateTwoContexts : public HeadlessAsyncDevTooledBrowserTest,
if (page_id_one_.empty() || page_id_two_.empty())
return;
- devtools_client_->GetBrowser()->GetExperimental()->Attach(
- browser::AttachParams::Builder().SetTargetId(page_id_one_).Build(),
- base::Bind(&BrowserDomainCreateTwoContexts::OnAttachedOne,
+ devtools_client_->GetTarget()->GetExperimental()->AttachToTarget(
+ target::AttachToTargetParams::Builder()
+ .SetTargetId(page_id_one_)
+ .Build(),
+ base::Bind(&TargetDomainCreateTwoContexts::OnAttachedToTargetOne,
base::Unretained(this)));
- devtools_client_->GetBrowser()->GetExperimental()->Attach(
- browser::AttachParams::Builder().SetTargetId(page_id_two_).Build(),
- base::Bind(&BrowserDomainCreateTwoContexts::OnAttachedTwo,
+ devtools_client_->GetTarget()->GetExperimental()->AttachToTarget(
+ target::AttachToTargetParams::Builder()
+ .SetTargetId(page_id_two_)
+ .Build(),
+ base::Bind(&TargetDomainCreateTwoContexts::OnAttachedToTargetTwo,
base::Unretained(this)));
}
- void OnAttachedOne(std::unique_ptr<browser::AttachResult> result) {
- devtools_client_->GetBrowser()->GetExperimental()->SendMessage(
- browser::SendMessageParams::Builder()
+ void OnAttachedToTargetOne(
+ std::unique_ptr<target::AttachToTargetResult> result) {
+ devtools_client_->GetTarget()->GetExperimental()->SendMessageToTarget(
+ target::SendMessageToTargetParams::Builder()
.SetTargetId(page_id_one_)
.SetMessage("{\"id\":101, \"method\": \"Page.enable\"}")
.Build());
}
- void OnAttachedTwo(std::unique_ptr<browser::AttachResult> result) {
- devtools_client_->GetBrowser()->GetExperimental()->SendMessage(
- browser::SendMessageParams::Builder()
+ void OnAttachedToTargetTwo(
+ std::unique_ptr<target::AttachToTargetResult> result) {
+ devtools_client_->GetTarget()->GetExperimental()->SendMessageToTarget(
+ target::SendMessageToTargetParams::Builder()
.SetTargetId(page_id_two_)
.SetMessage("{\"id\":102, \"method\": \"Page.enable\"}")
.Build());
@@ -505,8 +511,8 @@ class BrowserDomainCreateTwoContexts : public HeadlessAsyncDevTooledBrowserTest,
if (!page_one_loaded_ || !page_two_loaded_)
return;
- devtools_client_->GetBrowser()->GetExperimental()->SendMessage(
- browser::SendMessageParams::Builder()
+ devtools_client_->GetTarget()->GetExperimental()->SendMessageToTarget(
+ target::SendMessageToTargetParams::Builder()
.SetTargetId(page_id_one_)
.SetMessage("{\"id\":201, \"method\": \"Runtime.evaluate\", "
"\"params\": {\"expression\": "
@@ -514,8 +520,8 @@ class BrowserDomainCreateTwoContexts : public HeadlessAsyncDevTooledBrowserTest,
.Build());
}
- void OnDispatchMessage(
- const browser::DispatchMessageParams& params) override {
+ void OnReceivedMessageFromTarget(
+ const target::ReceivedMessageFromTargetParams& params) override {
std::unique_ptr<base::Value> message =
base::JSONReader::Read(params.GetMessage(), base::JSON_PARSE_RFC);
const base::DictionaryValue* message_dict;
@@ -540,9 +546,10 @@ class BrowserDomainCreateTwoContexts : public HeadlessAsyncDevTooledBrowserTest,
return;
std::string value;
if (params.GetTargetId() == page_id_one_) {
- // TODO(alexclarke): Make some better bindings for Browser.sendMessage.
- devtools_client_->GetBrowser()->GetExperimental()->SendMessage(
- browser::SendMessageParams::Builder()
+ // TODO(alexclarke): Make some better bindings
+ // for Target.SendMessageToTarget.
+ devtools_client_->GetTarget()->GetExperimental()->SendMessageToTarget(
+ target::SendMessageToTargetParams::Builder()
.SetTargetId(page_id_two_)
.SetMessage("{\"id\":202, \"method\": \"Runtime.evaluate\", "
"\"params\": {\"expression\": "
@@ -552,48 +559,48 @@ class BrowserDomainCreateTwoContexts : public HeadlessAsyncDevTooledBrowserTest,
result_dict->GetString("value", &value)) {
EXPECT_EQ("", value) << "Page 2 should not share cookies from page one";
- devtools_client_->GetBrowser()->GetExperimental()->CloseTarget(
- browser::CloseTargetParams::Builder()
+ devtools_client_->GetTarget()->GetExperimental()->CloseTarget(
+ target::CloseTargetParams::Builder()
.SetTargetId(page_id_one_)
.Build(),
- base::Bind(&BrowserDomainCreateTwoContexts::OnCloseTarget,
+ base::Bind(&TargetDomainCreateTwoContexts::OnCloseTarget,
base::Unretained(this)));
- devtools_client_->GetBrowser()->GetExperimental()->CloseTarget(
- browser::CloseTargetParams::Builder()
+ devtools_client_->GetTarget()->GetExperimental()->CloseTarget(
+ target::CloseTargetParams::Builder()
.SetTargetId(page_id_two_)
.Build(),
- base::Bind(&BrowserDomainCreateTwoContexts::OnCloseTarget,
+ base::Bind(&TargetDomainCreateTwoContexts::OnCloseTarget,
base::Unretained(this)));
- devtools_client_->GetBrowser()->GetExperimental()->RemoveObserver(this);
+ devtools_client_->GetTarget()->GetExperimental()->RemoveObserver(this);
}
}
}
- void OnCloseTarget(std::unique_ptr<browser::CloseTargetResult> result) {
+ void OnCloseTarget(std::unique_ptr<target::CloseTargetResult> result) {
page_close_count_++;
if (page_close_count_ < 2)
return;
- devtools_client_->GetBrowser()->GetExperimental()->DisposeBrowserContext(
- browser::DisposeBrowserContextParams::Builder()
+ devtools_client_->GetTarget()->GetExperimental()->DisposeBrowserContext(
+ target::DisposeBrowserContextParams::Builder()
.SetBrowserContextId(context_id_one_)
.Build(),
- base::Bind(&BrowserDomainCreateTwoContexts::OnCloseContext,
+ base::Bind(&TargetDomainCreateTwoContexts::OnCloseContext,
base::Unretained(this)));
- devtools_client_->GetBrowser()->GetExperimental()->DisposeBrowserContext(
- browser::DisposeBrowserContextParams::Builder()
+ devtools_client_->GetTarget()->GetExperimental()->DisposeBrowserContext(
+ target::DisposeBrowserContextParams::Builder()
.SetBrowserContextId(context_id_two_)
.Build(),
- base::Bind(&BrowserDomainCreateTwoContexts::OnCloseContext,
+ base::Bind(&TargetDomainCreateTwoContexts::OnCloseContext,
base::Unretained(this)));
}
void OnCloseContext(
- std::unique_ptr<browser::DisposeBrowserContextResult> result) {
+ std::unique_ptr<target::DisposeBrowserContextResult> result) {
EXPECT_TRUE(result->GetSuccess());
if (++context_closed_count_ < 2)
return;
@@ -612,7 +619,7 @@ class BrowserDomainCreateTwoContexts : public HeadlessAsyncDevTooledBrowserTest,
int context_closed_count_ = 0;
};
-HEADLESS_ASYNC_DEVTOOLED_TEST_F(BrowserDomainCreateTwoContexts);
+HEADLESS_ASYNC_DEVTOOLED_TEST_F(TargetDomainCreateTwoContexts);
class HeadlessDevToolsNavigationControlTest
: public HeadlessAsyncDevTooledBrowserTest,
diff --git a/chromium/headless/lib/headless_web_contents_browsertest.cc b/chromium/headless/lib/headless_web_contents_browsertest.cc
index 0fd928371ed..51f519c9055 100644
--- a/chromium/headless/lib/headless_web_contents_browsertest.cc
+++ b/chromium/headless/lib/headless_web_contents_browsertest.cc
@@ -7,7 +7,8 @@
#include <vector>
#include "content/public/test/browser_test.h"
-#include "headless/public/domains/page.h"
+#include "headless/public/devtools/domains/page.h"
+#include "headless/public/devtools/domains/security.h"
#include "headless/public/headless_browser.h"
#include "headless/public/headless_devtools_client.h"
#include "headless/public/headless_web_contents.h"
@@ -74,4 +75,25 @@ class HeadlessWebContentsScreenshotTest
HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessWebContentsScreenshotTest);
+class HeadlessWebContentsSecurityTest
+ : public HeadlessAsyncDevTooledBrowserTest,
+ public security::ExperimentalObserver {
+ public:
+ void RunDevTooledTest() override {
+ devtools_client_->GetSecurity()->GetExperimental()->AddObserver(this);
+ devtools_client_->GetSecurity()->GetExperimental()->Enable(
+ security::EnableParams::Builder().Build());
+ }
+
+ void OnSecurityStateChanged(
+ const security::SecurityStateChangedParams& params) override {
+ EXPECT_EQ(security::SecurityState::NEUTRAL, params.GetSecurityState());
+ EXPECT_TRUE(params.HasExplanations());
+
+ FinishAsynchronousTest();
+ }
+};
+
+HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessWebContentsSecurityTest);
+
} // namespace headless
diff --git a/chromium/headless/lib/resources/headless_lib_resources.grd b/chromium/headless/lib/resources/headless_lib_resources.grd
index 3137ec64834..9a0e2b0e33c 100644
--- a/chromium/headless/lib/resources/headless_lib_resources.grd
+++ b/chromium/headless/lib/resources/headless_lib_resources.grd
@@ -10,6 +10,7 @@
<release seq="1">
<includes>
<include name="IDR_HEADLESS_LIB_DEVTOOLS_DISCOVERY_PAGE" file="devtools_discovery_page.html" type="BINDATA" />
+ <include name="IDR_HEADLESS_BROWSER_MANIFEST_OVERLAY_TEMPLATE" file="../browser/headless_browser_manifest_overlay_template.json" type="BINDATA" />
</includes>
</release>
</grit>
diff --git a/chromium/headless/public/domains/README.md b/chromium/headless/public/domains/README.md
index a3f8898c5b6..c0689e4002a 100644
--- a/chromium/headless/public/domains/README.md
+++ b/chromium/headless/public/domains/README.md
@@ -1,3 +1,3 @@
The client API domain classes are autogenerated. You can find them under the
-out-directory, e.g., out/Debug/gen/headless/public/domains, or in
-[Code Search](https://code.google.com/p/chromium/codesearch#search/&q=f%3Agen/headless/public/domains&sq=package:chromium&type=cs).
+out-directory, e.g., out/Debug/gen/headless/public/devtools/domains, or in
+[Code Search](https://code.google.com/p/chromium/codesearch#search/&q=f%3Agen/headless/public/devtools/domains&sq=package:chromium&type=cs).
diff --git a/chromium/headless/public/domains/types_unittest.cc b/chromium/headless/public/domains/types_unittest.cc
index bf59b01151a..e5c0efa7e5a 100644
--- a/chromium/headless/public/domains/types_unittest.cc
+++ b/chromium/headless/public/domains/types_unittest.cc
@@ -3,7 +3,9 @@
// found in the LICENSE file.
#include "base/json/json_reader.h"
-#include "headless/public/domains/types.h"
+#include "headless/public/devtools/domains/accessibility.h"
+#include "headless/public/devtools/domains/memory.h"
+#include "headless/public/devtools/domains/page.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace headless {
@@ -24,9 +26,11 @@ TEST(TypesTest, IntegerPropertyParseError) {
std::unique_ptr<base::Value> object = base::JSONReader::Read(json);
EXPECT_TRUE(object);
+#if DCHECK_IS_ON()
ErrorReporter errors;
EXPECT_FALSE(page::NavigateToHistoryEntryParams::Parse(*object, &errors));
EXPECT_TRUE(errors.HasErrors());
+#endif // DCHECK_IS_ON()
}
TEST(TypesTest, BooleanProperty) {
@@ -48,10 +52,12 @@ TEST(TypesTest, BooleanPropertyParseError) {
std::unique_ptr<base::Value> object = base::JSONReader::Read(json);
EXPECT_TRUE(object);
+#if DCHECK_IS_ON()
ErrorReporter errors;
EXPECT_FALSE(memory::SetPressureNotificationsSuppressedParams::Parse(
*object, &errors));
EXPECT_TRUE(errors.HasErrors());
+#endif // DCHECK_IS_ON()
}
TEST(TypesTest, DoubleProperty) {
@@ -70,9 +76,11 @@ TEST(TypesTest, DoublePropertyParseError) {
std::unique_ptr<base::Value> object = base::JSONReader::Read(json);
EXPECT_TRUE(object);
+#if DCHECK_IS_ON()
ErrorReporter errors;
EXPECT_FALSE(page::SetGeolocationOverrideParams::Parse(*object, &errors));
EXPECT_TRUE(errors.HasErrors());
+#endif // DCHECK_IS_ON()
}
TEST(TypesTest, StringProperty) {
@@ -91,9 +99,11 @@ TEST(TypesTest, StringPropertyParseError) {
std::unique_ptr<base::Value> object = base::JSONReader::Read(json);
EXPECT_TRUE(object);
+#if DCHECK_IS_ON()
ErrorReporter errors;
EXPECT_FALSE(page::NavigateParams::Parse(*object, &errors));
EXPECT_TRUE(errors.HasErrors());
+#endif // DCHECK_IS_ON()
}
TEST(TypesTest, EnumProperty) {
@@ -114,9 +124,11 @@ TEST(TypesTest, EnumPropertyParseError) {
std::unique_ptr<base::Value> object = base::JSONReader::Read(json);
EXPECT_TRUE(object);
+#if DCHECK_IS_ON()
ErrorReporter errors;
EXPECT_FALSE(runtime::RemoteObject::Parse(*object, &errors));
EXPECT_TRUE(errors.HasErrors());
+#endif // DCHECK_IS_ON()
}
TEST(TypesTest, ArrayProperty) {
@@ -146,9 +158,11 @@ TEST(TypesTest, ArrayPropertyParseError) {
std::unique_ptr<base::Value> object = base::JSONReader::Read(json);
EXPECT_TRUE(object);
+#if DCHECK_IS_ON()
ErrorReporter errors;
EXPECT_FALSE(dom::QuerySelectorAllResult::Parse(*object, &errors));
EXPECT_TRUE(errors.HasErrors());
+#endif // DCHECK_IS_ON()
}
TEST(TypesTest, ObjectProperty) {
@@ -173,9 +187,11 @@ TEST(TypesTest, ObjectPropertyParseError) {
std::unique_ptr<base::Value> object = base::JSONReader::Read(json);
EXPECT_TRUE(object);
+#if DCHECK_IS_ON()
ErrorReporter errors;
EXPECT_FALSE(runtime::EvaluateResult::Parse(*object, &errors));
EXPECT_TRUE(errors.HasErrors());
+#endif // DCHECK_IS_ON()
}
TEST(TypesTest, AnyProperty) {
diff --git a/chromium/headless/public/headless_browser.cc b/chromium/headless/public/headless_browser.cc
index cbfbc5e400e..2b4270bd591 100644
--- a/chromium/headless/public/headless_browser.cc
+++ b/chromium/headless/public/headless_browser.cc
@@ -82,6 +82,11 @@ Builder& Builder::SetGLImplementation(const std::string& gl_implementation) {
return *this;
}
+Builder& Builder::AddMojoServiceName(const std::string& mojo_service_name) {
+ options_.mojo_service_names.insert(mojo_service_name);
+ return *this;
+}
+
Builder& Builder::SetUserDataDir(const base::FilePath& user_data_dir) {
options_.user_data_dir = user_data_dir;
return *this;
diff --git a/chromium/headless/public/headless_browser.h b/chromium/headless/public/headless_browser.h
index 954b79e0db4..021e91064fb 100644
--- a/chromium/headless/public/headless_browser.h
+++ b/chromium/headless/public/headless_browser.h
@@ -8,6 +8,7 @@
#include <memory>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
#include "base/callback.h"
@@ -115,6 +116,10 @@ struct HeadlessBrowser::Options {
// string can be used to disable GL rendering (e.g., WebGL support).
std::string gl_implementation;
+ // Names of mojo services exposed by the browser to the renderer. These
+ // services will be added to the browser's service manifest.
+ std::unordered_set<std::string> mojo_service_names;
+
// Default per-context options, can be specialized on per-context basis.
std::string user_agent;
@@ -159,6 +164,7 @@ class HeadlessBrowser::Options::Builder {
Builder& SetSingleProcessMode(bool single_process_mode);
Builder& SetDisableSandbox(bool disable_sandbox);
Builder& SetGLImplementation(const std::string& gl_implementation);
+ Builder& AddMojoServiceName(const std::string& mojo_service_name);
// Per-context settings.
diff --git a/chromium/headless/public/headless_devtools_client.h b/chromium/headless/public/headless_devtools_client.h
index 36e6ea3877a..573336af792 100644
--- a/chromium/headless/public/headless_devtools_client.h
+++ b/chromium/headless/public/headless_devtools_client.h
@@ -21,9 +21,6 @@ class Domain;
namespace application_cache {
class Domain;
}
-namespace browser {
-class Domain;
-}
namespace cache_storage {
class Domain;
}
@@ -99,10 +96,10 @@ class Domain;
namespace service_worker {
class Domain;
}
-namespace tracing {
+namespace target {
class Domain;
}
-namespace worker {
+namespace tracing {
class Domain;
}
@@ -121,7 +118,6 @@ class HEADLESS_EXPORT HeadlessDevToolsClient {
virtual accessibility::Domain* GetAccessibility() = 0;
virtual animation::Domain* GetAnimation() = 0;
virtual application_cache::Domain* GetApplicationCache() = 0;
- virtual browser::Domain* GetBrowser() = 0;
virtual cache_storage::Domain* GetCacheStorage() = 0;
virtual console::Domain* GetConsole() = 0;
virtual css::Domain* GetCSS() = 0;
@@ -147,8 +143,8 @@ class HEADLESS_EXPORT HeadlessDevToolsClient {
virtual runtime::Domain* GetRuntime() = 0;
virtual security::Domain* GetSecurity() = 0;
virtual service_worker::Domain* GetServiceWorker() = 0;
+ virtual target::Domain* GetTarget() = 0;
virtual tracing::Domain* GetTracing() = 0;
- virtual worker::Domain* GetWorker() = 0;
// TODO(skyostil): Add notification for disconnection.
diff --git a/chromium/headless/public/headless_shell.h b/chromium/headless/public/headless_shell.h
new file mode 100644
index 00000000000..f083d2030c1
--- /dev/null
+++ b/chromium/headless/public/headless_shell.h
@@ -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.
+
+#ifndef HEADLESS_PUBLIC_HEADLESS_SHELL_H_
+#define HEADLESS_PUBLIC_HEADLESS_SHELL_H_
+
+#include "headless/public/headless_export.h"
+
+namespace headless {
+
+// Start the Headless Shell application. Intended to be called early in main().
+// Returns the exit code for the process.
+int HEADLESS_EXPORT HeadlessShellMain(int argc, const char** argv);
+
+} // namespace headless
+
+#endif // HEADLESS_PUBLIC_HEADLESS_SHELL_H_
diff --git a/chromium/headless/public/internal/value_conversions.h b/chromium/headless/public/internal/value_conversions.h
index c25a0cd1ce2..4a85a02a464 100644
--- a/chromium/headless/public/internal/value_conversions.h
+++ b/chromium/headless/public/internal/value_conversions.h
@@ -14,7 +14,7 @@ namespace headless {
namespace internal {
// Generic conversion from a type to a base::Value. Implemented in
-// type_conversions.h after all type-specific ToValueImpls have been defined.
+// types_DOMAIN.cc after all type-specific ToValueImpls have been defined.
template <typename T>
std::unique_ptr<base::Value> ToValue(const T& value);
diff --git a/chromium/headless/public/util/deterministic_dispatcher.cc b/chromium/headless/public/util/deterministic_dispatcher.cc
index 70696eaeaa9..20982db898c 100644
--- a/chromium/headless/public/util/deterministic_dispatcher.cc
+++ b/chromium/headless/public/util/deterministic_dispatcher.cc
@@ -15,7 +15,8 @@ namespace headless {
DeterministicDispatcher::DeterministicDispatcher(
scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner)
: io_thread_task_runner_(std::move(io_thread_task_runner)),
- dispatch_pending_(false) {}
+ dispatch_pending_(false),
+ weak_ptr_factory_(this) {}
DeterministicDispatcher::~DeterministicDispatcher() {}
@@ -63,7 +64,7 @@ void DeterministicDispatcher::MaybeDispatchJobLocked() {
io_thread_task_runner_->PostTask(
FROM_HERE,
base::Bind(&DeterministicDispatcher::MaybeDispatchJobOnIOThreadTask,
- base::Unretained(this)));
+ weak_ptr_factory_.GetWeakPtr()));
}
void DeterministicDispatcher::MaybeDispatchJobOnIOThreadTask() {
@@ -72,8 +73,10 @@ void DeterministicDispatcher::MaybeDispatchJobOnIOThreadTask() {
{
base::AutoLock lock(lock_);
- CHECK(!pending_requests_.empty());
dispatch_pending_ = false;
+ // If the job got deleted, |pending_requests_| may be empty.
+ if (pending_requests_.empty())
+ return;
job = pending_requests_.front();
StatusMap::const_iterator it = ready_status_map_.find(job);
// Bail out if the oldest job is not be ready for dispatch yet.
diff --git a/chromium/headless/public/util/deterministic_dispatcher.h b/chromium/headless/public/util/deterministic_dispatcher.h
index c2e73b61710..0fea383b9cc 100644
--- a/chromium/headless/public/util/deterministic_dispatcher.h
+++ b/chromium/headless/public/util/deterministic_dispatcher.h
@@ -10,6 +10,7 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/lock.h"
#include "headless/public/util/url_request_dispatcher.h"
@@ -54,6 +55,8 @@ class DeterministicDispatcher : public URLRequestDispatcher {
// |io_thread_task_runner_|
bool dispatch_pending_;
+ base::WeakPtrFactory<DeterministicDispatcher> weak_ptr_factory_;
+
DISALLOW_COPY_AND_ASSIGN(DeterministicDispatcher);
};
diff --git a/chromium/headless/public/util/deterministic_dispatcher_test.cc b/chromium/headless/public/util/deterministic_dispatcher_test.cc
index b4c1c1fe089..24cede8b2e9 100644
--- a/chromium/headless/public/util/deterministic_dispatcher_test.cc
+++ b/chromium/headless/public/util/deterministic_dispatcher_test.cc
@@ -110,4 +110,20 @@ TEST_F(DeterministicDispatcherTest,
"id: 3 err: -123", "id: 4 OK"));
}
+TEST_F(DeterministicDispatcherTest, JobKilled) {
+ std::vector<std::string> notifications;
+ {
+ std::unique_ptr<FakeManagedDispatchURLRequestJob> job(
+ new FakeManagedDispatchURLRequestJob(deterministic_dispatcher_.get(), 1,
+ &notifications));
+
+ job->Kill();
+ }
+
+ EXPECT_TRUE(notifications.empty());
+
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(notifications.empty());
+}
+
} // namespace headless
diff --git a/chromium/headless/public/util/dom_tree_extractor.cc b/chromium/headless/public/util/dom_tree_extractor.cc
new file mode 100644
index 00000000000..6e4154c44e4
--- /dev/null
+++ b/chromium/headless/public/util/dom_tree_extractor.cc
@@ -0,0 +1,109 @@
+// 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 "headless/public/util/dom_tree_extractor.h"
+
+#include "base/bind.h"
+#include "base/json/json_writer.h"
+#include "headless/public/headless_devtools_client.h"
+
+namespace headless {
+
+DomTreeExtractor::DomTreeExtractor(HeadlessDevToolsClient* devtools_client)
+ : work_in_progress_(false),
+ devtools_client_(devtools_client),
+ weak_factory_(this) {}
+
+DomTreeExtractor::~DomTreeExtractor() {}
+
+void DomTreeExtractor::ExtractDomTree(
+ const std::vector<std::string>& css_style_whitelist,
+ DomResultCB callback) {
+ DCHECK(!work_in_progress_);
+ work_in_progress_ = true;
+
+ callback_ = std::move(callback);
+
+ devtools_client_->GetDOM()->GetDocument(
+ dom::GetDocumentParams::Builder().SetDepth(-1).SetPierce(true).Build(),
+ base::Bind(&DomTreeExtractor::OnDocumentFetched,
+ weak_factory_.GetWeakPtr()));
+
+ devtools_client_->GetCSS()->GetExperimental()->GetLayoutTreeAndStyles(
+ css::GetLayoutTreeAndStylesParams::Builder()
+ .SetComputedStyleWhitelist(css_style_whitelist)
+ .Build(),
+ base::Bind(&DomTreeExtractor::OnLayoutTreeAndStylesFetched,
+ weak_factory_.GetWeakPtr()));
+}
+
+void DomTreeExtractor::OnDocumentFetched(
+ std::unique_ptr<dom::GetDocumentResult> result) {
+ dom_tree_.document_result_ = std::move(result);
+ MaybeExtractDomTree();
+}
+
+void DomTreeExtractor::OnLayoutTreeAndStylesFetched(
+ std::unique_ptr<css::GetLayoutTreeAndStylesResult> result) {
+ dom_tree_.layout_tree_and_styles_result_ = std::move(result);
+ MaybeExtractDomTree();
+}
+
+void DomTreeExtractor::MaybeExtractDomTree() {
+ if (dom_tree_.document_result_ && dom_tree_.layout_tree_and_styles_result_) {
+ EnumerateNodes(dom_tree_.document_result_->GetRoot());
+ ExtractLayoutTreeNodes();
+ ExtractComputedStyles();
+
+ work_in_progress_ = false;
+
+ callback_.Run(std::move(dom_tree_));
+ }
+}
+
+void DomTreeExtractor::EnumerateNodes(const dom::Node* node) {
+ // Allocate an index and record the node pointer.
+ size_t index = dom_tree_.node_id_to_index_.size();
+ dom_tree_.node_id_to_index_[node->GetNodeId()] = index;
+ dom_tree_.dom_nodes_.push_back(node);
+
+ if (node->HasContentDocument())
+ EnumerateNodes(node->GetContentDocument());
+
+ if (node->HasChildren()) {
+ for (const std::unique_ptr<dom::Node>& child : *node->GetChildren()) {
+ EnumerateNodes(child.get());
+ }
+ }
+}
+
+void DomTreeExtractor::ExtractLayoutTreeNodes() {
+ dom_tree_.layout_tree_nodes_.reserve(
+ dom_tree_.layout_tree_and_styles_result_->GetLayoutTreeNodes()->size());
+
+ for (const std::unique_ptr<css::LayoutTreeNode>& layout_node :
+ *dom_tree_.layout_tree_and_styles_result_->GetLayoutTreeNodes()) {
+ std::unordered_map<NodeId, size_t>::const_iterator it =
+ dom_tree_.node_id_to_index_.find(layout_node->GetNodeId());
+ DCHECK(it != dom_tree_.node_id_to_index_.end());
+ dom_tree_.layout_tree_nodes_.push_back(layout_node.get());
+ }
+}
+
+void DomTreeExtractor::ExtractComputedStyles() {
+ dom_tree_.computed_styles_.reserve(
+ dom_tree_.layout_tree_and_styles_result_->GetComputedStyles()->size());
+
+ for (const std::unique_ptr<css::ComputedStyle>& computed_style :
+ *dom_tree_.layout_tree_and_styles_result_->GetComputedStyles()) {
+ dom_tree_.computed_styles_.push_back(computed_style.get());
+ }
+}
+
+DomTreeExtractor::DomTree::DomTree() {}
+DomTreeExtractor::DomTree::~DomTree() {}
+
+DomTreeExtractor::DomTree::DomTree(DomTree&& other) = default;
+
+} // namespace headless
diff --git a/chromium/headless/public/util/dom_tree_extractor.h b/chromium/headless/public/util/dom_tree_extractor.h
new file mode 100644
index 00000000000..dcd08bfe917
--- /dev/null
+++ b/chromium/headless/public/util/dom_tree_extractor.h
@@ -0,0 +1,88 @@
+// 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 HEADLESS_PUBLIC_UTIL_DOM_TREE_EXTRACTOR_H_
+#define HEADLESS_PUBLIC_UTIL_DOM_TREE_EXTRACTOR_H_
+
+#include <unordered_map>
+#include <vector>
+
+#include "base/macros.h"
+#include "headless/public/devtools/domains/css.h"
+#include "headless/public/devtools/domains/dom.h"
+
+namespace headless {
+class HeadlessDevToolsClient;
+
+// A utility class for extracting information from the DOM via DevTools. In
+// addition, it also extracts details of bounding boxes and layout text (NB the
+// exact layout should not be regarded as stable, it's subject to change without
+// notice).
+class DomTreeExtractor {
+ public:
+ explicit DomTreeExtractor(HeadlessDevToolsClient* devtools_client);
+ ~DomTreeExtractor();
+
+ using NodeId = int;
+ using Index = size_t;
+
+ class DomTree {
+ public:
+ DomTree();
+ DomTree(DomTree&& other);
+ ~DomTree();
+
+ // Flattened dom tree. The root node is always the first entry.
+ std::vector<const dom::Node*> dom_nodes_;
+
+ // Map of node IDs to indexes into |dom_nodes_|.
+ std::unordered_map<NodeId, Index> node_id_to_index_;
+
+ std::vector<const css::LayoutTreeNode*> layout_tree_nodes_;
+
+ std::vector<const css::ComputedStyle*> computed_styles_;
+
+ private:
+ friend class DomTreeExtractor;
+
+ // Owns the raw pointers in |dom_nodes_|.
+ std::unique_ptr<dom::GetDocumentResult> document_result_;
+
+ // Owns the raw pointers in |layout_tree_nodes_|.
+ std::unique_ptr<css::GetLayoutTreeAndStylesResult>
+ layout_tree_and_styles_result_;
+
+ DISALLOW_COPY_AND_ASSIGN(DomTree);
+ };
+
+ using DomResultCB = base::Callback<void(DomTree)>;
+
+ // Extracts all nodes from the DOM. This is an asynchronous operation and
+ // it's an error to call ExtractDom while a previous operation is in flight.
+ void ExtractDomTree(const std::vector<std::string>& css_style_whitelist,
+ DomResultCB callback);
+
+ private:
+ void OnDocumentFetched(std::unique_ptr<dom::GetDocumentResult> result);
+
+ void OnLayoutTreeAndStylesFetched(
+ std::unique_ptr<css::GetLayoutTreeAndStylesResult> result);
+
+ void MaybeExtractDomTree();
+ void EnumerateNodes(const dom::Node* node);
+ void ExtractLayoutTreeNodes();
+ void ExtractComputedStyles();
+
+ DomResultCB callback_;
+ DomTree dom_tree_;
+ bool work_in_progress_;
+ HeadlessDevToolsClient* devtools_client_; // NOT OWNED
+ base::WeakPtrFactory<DomTreeExtractor> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(DomTreeExtractor);
+};
+
+} // namespace headless
+
+#endif // HEADLESS_PUBLIC_UTIL_DOM_TREE_EXTRACTOR_H_
diff --git a/chromium/headless/public/util/dom_tree_extractor_browsertest.cc b/chromium/headless/public/util/dom_tree_extractor_browsertest.cc
new file mode 100644
index 00000000000..57b6a54869f
--- /dev/null
+++ b/chromium/headless/public/util/dom_tree_extractor_browsertest.cc
@@ -0,0 +1,845 @@
+// 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 "headless/public/util/dom_tree_extractor.h"
+
+#include <memory>
+#include "base/json/json_reader.h"
+#include "base/json/json_writer.h"
+#include "base/strings/string_util.h"
+#include "content/public/browser/render_widget_host_view.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/test/browser_test.h"
+#include "headless/lib/browser/headless_web_contents_impl.h"
+#include "headless/public/devtools/domains/emulation.h"
+#include "headless/public/devtools/domains/network.h"
+#include "headless/public/devtools/domains/page.h"
+#include "headless/public/headless_browser.h"
+#include "headless/public/headless_devtools_client.h"
+#include "headless/public/headless_devtools_target.h"
+#include "headless/test/headless_browser_test.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace headless {
+
+namespace {
+
+std::string NormaliseJSON(const std::string& json) {
+ std::unique_ptr<base::Value> parsed_json = base::JSONReader::Read(json);
+ DCHECK(parsed_json);
+ std::string normalized_json;
+ base::JSONWriter::WriteWithOptions(
+ *parsed_json, base::JSONWriter::OPTIONS_PRETTY_PRINT, &normalized_json);
+ return normalized_json;
+}
+
+} // namespace
+
+class DomTreeExtractorBrowserTest : public HeadlessAsyncDevTooledBrowserTest,
+ public page::Observer {
+ public:
+ void RunDevTooledTest() override {
+ EXPECT_TRUE(embedded_test_server()->Start());
+ devtools_client_->GetPage()->AddObserver(this);
+ devtools_client_->GetPage()->Enable();
+ devtools_client_->GetPage()->Navigate(
+ embedded_test_server()->GetURL("/dom_tree_test.html").spec());
+ }
+
+ void OnLoadEventFired(const page::LoadEventFiredParams& params) override {
+ devtools_client_->GetPage()->RemoveObserver(this);
+
+ extractor_.reset(new DomTreeExtractor(devtools_client_.get()));
+
+ std::vector<std::string> css_whitelist = {
+ "color", "display", "font-style", "margin-left",
+ "margin-right", "margin-top", "margin-bottom"};
+ extractor_->ExtractDomTree(
+ css_whitelist,
+ base::Bind(&DomTreeExtractorBrowserTest::OnDomTreeExtracted,
+ base::Unretained(this)));
+ }
+
+ void OnDomTreeExtracted(DomTreeExtractor::DomTree dom_tree) {
+ GURL::Replacements replace_port;
+ replace_port.SetPortStr("");
+
+ std::vector<std::unique_ptr<base::DictionaryValue>> dom_nodes(
+ dom_tree.dom_nodes_.size());
+
+ // For convenience flatten the dom tree into an array.
+ for (size_t i = 0; i < dom_tree.dom_nodes_.size(); i++) {
+ dom::Node* node = const_cast<dom::Node*>(dom_tree.dom_nodes_[i]);
+
+ dom_nodes[i].reset(
+ static_cast<base::DictionaryValue*>(node->Serialize().release()));
+
+ // Convert child & content document pointers into indexes.
+ if (node->HasChildren()) {
+ std::unique_ptr<base::ListValue> children(new base::ListValue());
+ for (const std::unique_ptr<dom::Node>& child : *node->GetChildren()) {
+ children->AppendInteger(
+ dom_tree.node_id_to_index_[child->GetNodeId()]);
+ }
+ dom_nodes[i]->Set("childIndices", std::move(children));
+ dom_nodes[i]->Remove("children", nullptr);
+ }
+
+ if (node->HasContentDocument()) {
+ dom_nodes[i]->SetInteger(
+ "contentDocumentIndex",
+ dom_tree
+ .node_id_to_index_[node->GetContentDocument()->GetNodeId()]);
+ dom_nodes[i]->Remove("contentDocument", nullptr);
+ }
+
+ dom_nodes[i]->Remove("childNodeCount", nullptr);
+
+ // Frame IDs are random.
+ if (dom_nodes[i]->HasKey("frameId"))
+ dom_nodes[i]->SetString("frameId", "?");
+
+ // Ports are random.
+ std::string url;
+ if (dom_nodes[i]->GetString("baseURL", &url)) {
+ dom_nodes[i]->SetString(
+ "baseURL", GURL(url).ReplaceComponents(replace_port).spec());
+ }
+
+ if (dom_nodes[i]->GetString("documentURL", &url)) {
+ dom_nodes[i]->SetString(
+ "documentURL", GURL(url).ReplaceComponents(replace_port).spec());
+ }
+ }
+
+ // Merge LayoutTreeNode data into the dictionaries.
+ for (const css::LayoutTreeNode* layout_node : dom_tree.layout_tree_nodes_) {
+ auto it = dom_tree.node_id_to_index_.find(layout_node->GetNodeId());
+ ASSERT_TRUE(it != dom_tree.node_id_to_index_.end());
+
+ base::DictionaryValue* node_dict = dom_nodes[it->second].get();
+ node_dict->Set("boundingBox", layout_node->GetBoundingBox()->Serialize());
+
+ if (layout_node->HasLayoutText())
+ node_dict->SetString("layoutText", layout_node->GetLayoutText());
+
+ if (layout_node->HasStyleIndex())
+ node_dict->SetInteger("styleIndex", layout_node->GetStyleIndex());
+
+ if (layout_node->HasInlineTextNodes()) {
+ std::unique_ptr<base::ListValue> inline_text_nodes(
+ new base::ListValue());
+ for (const std::unique_ptr<css::InlineTextBox>& inline_text_box :
+ *layout_node->GetInlineTextNodes()) {
+ size_t index = inline_text_nodes->GetSize();
+ inline_text_nodes->Set(index, inline_text_box->Serialize());
+ }
+ node_dict->Set("inlineTextNodes", std::move(inline_text_nodes));
+ }
+ }
+
+ std::vector<std::unique_ptr<base::DictionaryValue>> computed_styles(
+ dom_tree.computed_styles_.size());
+
+ for (size_t i = 0; i < dom_tree.computed_styles_.size(); i++) {
+ std::unique_ptr<base::DictionaryValue> style(new base::DictionaryValue());
+ for (const auto& style_property :
+ *dom_tree.computed_styles_[i]->GetProperties()) {
+ style->SetString(style_property->GetName(), style_property->GetValue());
+ }
+ computed_styles[i] = std::move(style);
+ }
+
+ const std::vector<std::string> expected_dom_nodes = {
+ R"raw_string({
+ "backendNodeId": 3,
+ "baseURL": "http://127.0.0.1/dom_tree_test.html",
+ "boundingBox": {
+ "height": 600.0,
+ "width": 800.0,
+ "x": 0.0,
+ "y": 0.0
+ },
+ "childIndices": [ 1 ],
+ "documentURL": "http://127.0.0.1/dom_tree_test.html",
+ "localName": "",
+ "nodeId": 1,
+ "nodeName": "#document",
+ "nodeType": 9,
+ "nodeValue": "",
+ "xmlVersion": ""
+ })raw_string",
+
+ R"raw_string({
+ "attributes": [ ],
+ "backendNodeId": 4,
+ "boundingBox": {
+ "height": 600.0,
+ "width": 800.0,
+ "x": 0.0,
+ "y": 0.0
+ },
+ "childIndices": [ 2, 5 ],
+ "frameId": "?",
+ "localName": "html",
+ "nodeId": 2,
+ "nodeName": "HTML",
+ "nodeType": 1,
+ "nodeValue": "",
+ "styleIndex": 0
+ })raw_string",
+
+ R"raw_string({
+ "attributes": [ ],
+ "backendNodeId": 5,
+ "childIndices": [ 3 ],
+ "localName": "head",
+ "nodeId": 3,
+ "nodeName": "HEAD",
+ "nodeType": 1,
+ "nodeValue": ""
+ })raw_string",
+
+ R"raw_string({
+ "attributes": [ ],
+ "backendNodeId": 6,
+ "childIndices": [ 4 ],
+ "localName": "title",
+ "nodeId": 4,
+ "nodeName": "TITLE",
+ "nodeType": 1,
+ "nodeValue": ""
+ })raw_string",
+
+ R"raw_string({
+ "backendNodeId": 7,
+ "localName": "",
+ "nodeId": 5,
+ "nodeName": "#text",
+ "nodeType": 3,
+ "nodeValue": "Hello world!"
+ })raw_string",
+
+ R"raw_string({
+ "attributes": [ ],
+ "backendNodeId": 8,
+ "boundingBox": {
+ "height": 584.0,
+ "width": 784.0,
+ "x": 8.0,
+ "y": 8.0
+ },
+ "childIndices": [ 6 ],
+ "localName": "body",
+ "nodeId": 6,
+ "nodeName": "BODY",
+ "nodeType": 1,
+ "nodeValue": "",
+ "styleIndex": 1
+ })raw_string",
+
+ R"raw_string({
+ "attributes": [ "id", "id1" ],
+ "backendNodeId": 9,
+ "boundingBox": {
+ "height": 367.0,
+ "width": 784.0,
+ "x": 8.0,
+ "y": 8.0
+ },
+ "childIndices": [ 7, 9, 16 ],
+ "localName": "div",
+ "nodeId": 7,
+ "nodeName": "DIV",
+ "nodeType": 1,
+ "nodeValue": "",
+ "styleIndex": 0
+ })raw_string",
+
+ R"raw_string({
+ "attributes": [ "style", "color: red" ],
+ "backendNodeId": 10,
+ "boundingBox": {
+ "height": 37.0,
+ "width": 784.0,
+ "x": 8.0,
+ "y": 8.0
+ },
+ "childIndices": [ 8 ],
+ "localName": "h1",
+ "nodeId": 8,
+ "nodeName": "H1",
+ "nodeType": 1,
+ "nodeValue": "",
+ "styleIndex": 2
+ })raw_string",
+
+ R"raw_string({
+ "backendNodeId": 11,
+ "boundingBox": {
+ "height": 36.0,
+ "width": 143.0,
+ "x": 8.0,
+ "y": 8.0
+ },
+ "inlineTextNodes": [ {
+ "boundingBox": {
+ "height": 36.0,
+ "width": 142.171875,
+ "x": 8.0,
+ "y": 8.0
+ },
+ "numCharacters": 10,
+ "startCharacterIndex": 0
+ } ],
+ "layoutText": "Some text.",
+ "localName": "",
+ "nodeId": 9,
+ "nodeName": "#text",
+ "nodeType": 3,
+ "nodeValue": "Some text.",
+ "styleIndex": 2
+ })raw_string",
+
+ R"raw_string({
+ "attributes": [
+ "src", "/iframe.html", "width", "400", "height", "200" ],
+ "backendNodeId": 12,
+ "boundingBox": {
+ "height": 205.0,
+ "width": 404.0,
+ "x": 8.0,
+ "y": 66.0
+ },
+ "childIndices": [ ],
+ "contentDocumentIndex": 10,
+ "frameId": "?",
+ "localName": "iframe",
+ "nodeId": 10,
+ "nodeName": "IFRAME",
+ "nodeType": 1,
+ "nodeValue": "",
+ "styleIndex": 4
+ })raw_string",
+
+ R"raw_string({
+ "backendNodeId": 13,
+ "baseURL": "http://127.0.0.1/iframe.html",
+ "childIndices": [ 11 ],
+ "documentURL": "http://127.0.0.1/iframe.html",
+ "localName": "",
+ "nodeId": 11,
+ "nodeName": "#document",
+ "nodeType": 9,
+ "nodeValue": "",
+ "xmlVersion": ""
+ })raw_string",
+
+ R"raw_string({
+ "attributes": [ ],
+ "backendNodeId": 14,
+ "boundingBox": {
+ "height": 200.0,
+ "width": 400.0,
+ "x": 10.0,
+ "y": 68.0
+ },
+ "childIndices": [ 12, 13 ],
+ "frameId": "?",
+ "localName": "html",
+ "nodeId": 12,
+ "nodeName": "HTML",
+ "nodeType": 1,
+ "nodeValue": "",
+ "styleIndex": 0
+ })raw_string",
+
+ R"raw_string({
+ "attributes": [ ],
+ "backendNodeId": 15,
+ "childIndices": [ ],
+ "localName": "head",
+ "nodeId": 13,
+ "nodeName": "HEAD",
+ "nodeType": 1,
+ "nodeValue": ""
+ })raw_string",
+
+ R"raw_string({
+ "attributes": [ ],
+ "backendNodeId": 16,
+ "boundingBox": {
+ "height": 171.0,
+ "width": 384.0,
+ "x": 18.0,
+ "y": 76.0
+ },
+ "childIndices": [ 14 ],
+ "localName": "body",
+ "nodeId": 14,
+ "nodeName": "BODY",
+ "nodeType": 1,
+ "nodeValue": "",
+ "styleIndex": 1
+ })raw_string",
+
+ R"raw_string({
+ "attributes": [ ],
+ "backendNodeId": 17,
+ "boundingBox": {
+ "height": 37.0,
+ "width": 384.0,
+ "x": 18.0,
+ "y": 76.0
+ },
+ "childIndices": [ 15 ],
+ "localName": "h1",
+ "nodeId": 15,
+ "nodeName": "H1",
+ "nodeType": 1,
+ "nodeValue": "",
+ "styleIndex": 3
+ })raw_string",
+
+ R"raw_string({
+ "backendNodeId": 18,
+ "boundingBox": {
+ "height": 36.0,
+ "width": 308.0,
+ "x": 8.0,
+ "y": 8.0
+ },
+ "inlineTextNodes": [ {
+ "boundingBox": {
+ "height": 36.0,
+ "width": 307.734375,
+ "x": 8.0,
+ "y": 8.0
+ },
+ "numCharacters": 22,
+ "startCharacterIndex": 0
+ } ],
+ "layoutText": "Hello from the iframe!",
+ "localName": "",
+ "nodeId": 16,
+ "nodeName": "#text",
+ "nodeType": 3,
+ "nodeValue": "Hello from the iframe!",
+ "styleIndex": 3
+ })raw_string",
+
+ R"raw_string({
+ "attributes": [ "id", "id2" ],
+ "backendNodeId": 19,
+ "boundingBox": {
+ "height": 105.0,
+ "width": 784.0,
+ "x": 8.0,
+ "y": 270.0
+ },
+ "childIndices": [ 17 ],
+ "localName": "div",
+ "nodeId": 17,
+ "nodeName": "DIV",
+ "nodeType": 1,
+ "nodeValue": "",
+ "styleIndex": 0
+ })raw_string",
+
+ R"raw_string({
+ "attributes": [ "id", "id3" ],
+ "backendNodeId": 20,
+ "boundingBox": {
+ "height": 105.0,
+ "width": 784.0,
+ "x": 8.0,
+ "y": 270.0
+ },
+ "childIndices": [ 18 ],
+ "localName": "div",
+ "nodeId": 18,
+ "nodeName": "DIV",
+ "nodeType": 1,
+ "nodeValue": "",
+ "styleIndex": 0
+ })raw_string",
+
+ R"raw_string({
+ "attributes": [ "id", "id4" ],
+ "backendNodeId": 21,
+ "boundingBox": {
+ "height": 105.0,
+ "width": 784.0,
+ "x": 8.0,
+ "y": 270.0
+ },
+ "childIndices": [ 19, 21, 23, 24 ],
+ "localName": "div",
+ "nodeId": 19,
+ "nodeName": "DIV",
+ "nodeType": 1,
+ "nodeValue": "",
+ "styleIndex": 0
+ })raw_string",
+
+ R"raw_string({
+ "attributes": [ "href", "https://www.google.com" ],
+ "backendNodeId": 22,
+ "boundingBox": {
+ "height": 18.0,
+ "width": 53.0,
+ "x": 8.0,
+ "y": 270.0
+ },
+ "childIndices": [ 20 ],
+ "localName": "a",
+ "nodeId": 20,
+ "nodeName": "A",
+ "nodeType": 1,
+ "nodeValue": "",
+ "styleIndex": 5
+ })raw_string",
+
+ R"raw_string({
+ "backendNodeId": 23,
+ "boundingBox": {
+ "height": 18.0,
+ "width": 53.0,
+ "x": 8.0,
+ "y": 270.0
+ },
+ "inlineTextNodes": [ {
+ "boundingBox": {
+ "height": 17.0,
+ "width": 52.421875,
+ "x": 8.0,
+ "y": 270.4375
+ },
+ "numCharacters": 7,
+ "startCharacterIndex": 0
+ } ],
+ "layoutText": "Google!",
+ "localName": "",
+ "nodeId": 21,
+ "nodeName": "#text",
+ "nodeType": 3,
+ "nodeValue": "Google!",
+ "styleIndex": 5
+ })raw_string",
+
+ R"raw_string({
+ "attributes": [ ],
+ "backendNodeId": 24,
+ "boundingBox": {
+ "height": 19.0,
+ "width": 784.0,
+ "x": 8.0,
+ "y": 304.0
+ },
+ "childIndices": [ 22 ],
+ "localName": "p",
+ "nodeId": 22,
+ "nodeName": "P",
+ "nodeType": 1,
+ "nodeValue": "",
+ "styleIndex": 6
+ })raw_string",
+
+ R"raw_string({
+ "backendNodeId": 25,
+ "boundingBox": {
+ "height": 18.0,
+ "width": 85.0,
+ "x": 8.0,
+ "y": 304.0
+ },
+ "inlineTextNodes": [ {
+ "boundingBox": {
+ "height": 17.0,
+ "width": 84.84375,
+ "x": 8.0,
+ "y": 304.4375
+ },
+ "numCharacters": 12,
+ "startCharacterIndex": 0
+ } ],
+ "layoutText": "A paragraph!",
+ "localName": "",
+ "nodeId": 23,
+ "nodeName": "#text",
+ "nodeType": 3,
+ "nodeValue": "A paragraph!",
+ "styleIndex": 6
+ })raw_string",
+
+ R"raw_string({
+ "attributes": [ ],
+ "backendNodeId": 26,
+ "boundingBox": {
+ "height": 0.0,
+ "width": 0.0,
+ "x": 0.0,
+ "y": 0.0
+ },
+ "childIndices": [ ],
+ "inlineTextNodes": [ {
+ "boundingBox": {
+ "height": 17.0,
+ "width": 0.0,
+ "x": 8.0,
+ "y": 338.4375
+ },
+ "numCharacters": 1,
+ "startCharacterIndex": 0
+ } ],
+ "layoutText": "\n",
+ "localName": "br",
+ "nodeId": 24,
+ "nodeName": "BR",
+ "nodeType": 1,
+ "nodeValue": "",
+ "styleIndex": 4
+ })raw_string",
+
+ R"raw_string({
+ "attributes": [ "style", "color: green" ],
+ "backendNodeId": 27,
+ "boundingBox": {
+ "height": 19.0,
+ "width": 784.0,
+ "x": 8.0,
+ "y": 356.0
+ },
+ "childIndices": [ 25, 26, 28 ],
+ "localName": "div",
+ "nodeId": 25,
+ "nodeName": "DIV",
+ "nodeType": 1,
+ "nodeValue": "",
+ "styleIndex": 7
+ })raw_string",
+
+ R"raw_string({
+ "backendNodeId": 28,
+ "boundingBox": {
+ "height": 18.0,
+ "width": 41.0,
+ "x": 8.0,
+ "y": 356.0
+ },
+ "inlineTextNodes": [ {
+ "boundingBox": {
+ "height": 17.0,
+ "width": 40.4375,
+ "x": 8.0,
+ "y": 356.4375
+ },
+ "numCharacters": 5,
+ "startCharacterIndex": 0
+ } ],
+ "layoutText": "Some ",
+ "localName": "",
+ "nodeId": 26,
+ "nodeName": "#text",
+ "nodeType": 3,
+ "nodeValue": "Some ",
+ "styleIndex": 7
+ })raw_string",
+
+ R"raw_string({
+ "attributes": [ ],
+ "backendNodeId": 29,
+ "boundingBox": {
+ "height": 18.0,
+ "width": 37.0,
+ "x": 48.0,
+ "y": 356.0
+ },
+ "childIndices": [ 27 ],
+ "localName": "em",
+ "nodeId": 27,
+ "nodeName": "EM",
+ "nodeType": 1,
+ "nodeValue": "",
+ "styleIndex": 8
+ })raw_string",
+
+ R"raw_string({
+ "backendNodeId": 30,
+ "boundingBox": {
+ "height": 18.0,
+ "width": 37.0,
+ "x": 48.0,
+ "y": 356.0
+ },
+ "inlineTextNodes": [ {
+ "boundingBox": {
+ "height": 17.0,
+ "width": 35.828125,
+ "x": 48.4375,
+ "y": 356.4375
+ },
+ "numCharacters": 5,
+ "startCharacterIndex": 0
+ } ],
+ "layoutText": "green",
+ "localName": "",
+ "nodeId": 28,
+ "nodeName": "#text",
+ "nodeType": 3,
+ "nodeValue": "green",
+ "styleIndex": 8
+ })raw_string",
+
+ R"raw_string({
+ "backendNodeId": 31,
+ "boundingBox": {
+ "height": 18.0,
+ "width": 41.0,
+ "x": 84.0,
+ "y": 356.0
+ },
+ "inlineTextNodes": [ {
+ "boundingBox": {
+ "height": 17.0,
+ "width": 39.984375,
+ "x": 84.265625,
+ "y": 356.4375
+ },
+ "numCharacters": 8,
+ "startCharacterIndex": 0
+ } ],
+ "layoutText": " text...",
+ "localName": "",
+ "nodeId": 29,
+ "nodeName": "#text",
+ "nodeType": 3,
+ "nodeValue": " text...",
+ "styleIndex": 7
+ })raw_string"};
+
+ EXPECT_EQ(expected_dom_nodes.size(), dom_nodes.size());
+
+ for (size_t i = 0; i < dom_nodes.size(); i++) {
+ std::string result_json;
+ base::JSONWriter::WriteWithOptions(
+ *dom_nodes[i], base::JSONWriter::OPTIONS_PRETTY_PRINT, &result_json);
+
+ ASSERT_LT(i, expected_dom_nodes.size());
+ EXPECT_EQ(NormaliseJSON(expected_dom_nodes[i]), result_json) << " Node # "
+ << i;
+ }
+
+ const std::vector<std::string> expected_styles = {
+ R"raw_string({
+ "color": "rgb(0, 0, 0)",
+ "display": "block",
+ "font-style": "normal",
+ "margin-bottom": "0px",
+ "margin-left": "0px",
+ "margin-right": "0px",
+ "margin-top": "0px"
+ })raw_string",
+
+ R"raw_string({
+ "color": "rgb(0, 0, 0)",
+ "display": "block",
+ "font-style": "normal",
+ "margin-bottom": "8px",
+ "margin-left": "8px",
+ "margin-right": "8px",
+ "margin-top": "8px"
+ })raw_string",
+
+ R"raw_string({
+ "color": "rgb(255, 0, 0)",
+ "display": "block",
+ "font-style": "normal",
+ "margin-bottom": "21.44px",
+ "margin-left": "0px",
+ "margin-right": "0px",
+ "margin-top": "21.44px"
+ })raw_string",
+
+ R"raw_string({
+ "color": "rgb(0, 0, 0)",
+ "display": "block",
+ "font-style": "normal",
+ "margin-bottom": "21.44px",
+ "margin-left": "0px",
+ "margin-right": "0px",
+ "margin-top": "21.44px"
+ })raw_string",
+
+ R"raw_string({
+ "color": "rgb(0, 0, 0)",
+ "display": "inline",
+ "font-style": "normal",
+ "margin-bottom": "0px",
+ "margin-left": "0px",
+ "margin-right": "0px",
+ "margin-top": "0px"
+ })raw_string",
+
+ R"raw_string({
+ "color": "rgb(0, 0, 238)",
+ "display": "inline",
+ "font-style": "normal",
+ "margin-bottom": "0px",
+ "margin-left": "0px",
+ "margin-right": "0px",
+ "margin-top": "0px"
+ })raw_string",
+
+ R"raw_string({
+ "color": "rgb(0, 0, 0)",
+ "display": "block",
+ "font-style": "normal",
+ "margin-bottom": "16px",
+ "margin-left": "0px",
+ "margin-right": "0px",
+ "margin-top": "16px"
+ })raw_string",
+
+ R"raw_string({
+ "color": "rgb(0, 128, 0)",
+ "display": "block",
+ "font-style": "normal",
+ "margin-bottom": "0px",
+ "margin-left": "0px",
+ "margin-right": "0px",
+ "margin-top": "0px"
+ })raw_string",
+
+ R"raw_string({
+ "color": "rgb(0, 128, 0)",
+ "display": "inline",
+ "font-style": "italic",
+ "margin-bottom": "0px",
+ "margin-left": "0px",
+ "margin-right": "0px",
+ "margin-top": "0px"
+ })raw_string"};
+
+ for (size_t i = 0; i < computed_styles.size(); i++) {
+ std::string result_json;
+ base::JSONWriter::WriteWithOptions(*computed_styles[i],
+ base::JSONWriter::OPTIONS_PRETTY_PRINT,
+ &result_json);
+
+ ASSERT_LT(i, expected_styles.size());
+ EXPECT_EQ(NormaliseJSON(expected_styles[i]), result_json) << " Style # "
+ << i;
+ }
+
+ FinishAsynchronousTest();
+ }
+
+ std::unique_ptr<DomTreeExtractor> extractor_;
+};
+
+HEADLESS_ASYNC_DEVTOOLED_TEST_F(DomTreeExtractorBrowserTest);
+
+} // namespace headless
diff --git a/chromium/headless/public/util/error_reporter.cc b/chromium/headless/public/util/error_reporter.cc
index 88722d7b79d..9daa0198670 100644
--- a/chromium/headless/public/util/error_reporter.cc
+++ b/chromium/headless/public/util/error_reporter.cc
@@ -14,6 +14,7 @@ ErrorReporter::ErrorReporter() {}
ErrorReporter::~ErrorReporter() {}
+#if DCHECK_IS_ON()
void ErrorReporter::Push() {
path_.push_back(nullptr);
}
@@ -47,5 +48,6 @@ void ErrorReporter::AddError(base::StringPiece description) {
bool ErrorReporter::HasErrors() const {
return !errors_.empty();
}
+#endif // DCHECK_IS_ON()
} // namespace headless
diff --git a/chromium/headless/public/util/error_reporter.h b/chromium/headless/public/util/error_reporter.h
index d7eb5e96d21..2fd432f3f2d 100644
--- a/chromium/headless/public/util/error_reporter.h
+++ b/chromium/headless/public/util/error_reporter.h
@@ -13,12 +13,14 @@
namespace headless {
-// Tracks errors which are encountered while parsing client API types.
+// Tracks errors which are encountered while parsing client API types. Note that
+// errors are only reported in debug builds (i.e., when DCHECK is enabled).
class HEADLESS_EXPORT ErrorReporter {
public:
ErrorReporter();
~ErrorReporter();
+#if DCHECK_IS_ON()
// Enter a new nested parsing context. It will initially have a null name.
void Push();
@@ -37,6 +39,14 @@ class HEADLESS_EXPORT ErrorReporter {
// Returns a list of reported errors.
const std::vector<std::string>& errors() const { return errors_; }
+#else // DCHECK_IS_ON()
+ inline void Push() {}
+ inline void Pop() {}
+ inline void SetName(const char* name) {}
+ inline void AddError(base::StringPiece description) {}
+ inline bool HasErrors() const { return false; }
+ std::vector<std::string> errors() const { return std::vector<std::string>(); }
+#endif // DCHECK_IS_ON()
private:
std::vector<const char*> path_;
diff --git a/chromium/headless/public/util/error_reporter_unittest.cc b/chromium/headless/public/util/error_reporter_unittest.cc
index f23ced9ef29..5752c86b570 100644
--- a/chromium/headless/public/util/error_reporter_unittest.cc
+++ b/chromium/headless/public/util/error_reporter_unittest.cc
@@ -9,18 +9,22 @@ namespace headless {
TEST(ErrorReporterTest, NoErrors) {
ErrorReporter reporter;
+#if DCHECK_IS_ON()
EXPECT_FALSE(reporter.HasErrors());
EXPECT_TRUE(reporter.errors().empty());
+#endif // DCHECK_IS_ON()
}
TEST(ErrorReporterTest, TopLevelErrors) {
ErrorReporter reporter;
reporter.AddError("instructions unclear");
reporter.AddError("head stuck in std::unordered_map");
+#if DCHECK_IS_ON()
EXPECT_TRUE(reporter.HasErrors());
EXPECT_EQ(2u, reporter.errors().size());
EXPECT_EQ("instructions unclear", reporter.errors()[0]);
EXPECT_EQ("head stuck in std::unordered_map", reporter.errors()[1]);
+#endif // DCHECK_IS_ON()
}
TEST(ErrorReporterTest, UnnamedContext) {
@@ -28,9 +32,11 @@ TEST(ErrorReporterTest, UnnamedContext) {
reporter.Push();
reporter.AddError("lp0 is on fire");
reporter.Pop();
+#if DCHECK_IS_ON()
EXPECT_TRUE(reporter.HasErrors());
EXPECT_EQ(1u, reporter.errors().size());
EXPECT_EQ("lp0 is on fire", reporter.errors()[0]);
+#endif // DCHECK_IS_ON()
}
TEST(ErrorReporterTest, NestedContexts) {
@@ -43,10 +49,12 @@ TEST(ErrorReporterTest, NestedContexts) {
reporter.Pop();
reporter.AddError("uh oh");
reporter.Pop();
+#if DCHECK_IS_ON()
EXPECT_TRUE(reporter.HasErrors());
EXPECT_EQ(2u, reporter.errors().size());
EXPECT_EQ("ship.front: fell off", reporter.errors()[0]);
EXPECT_EQ("ship: uh oh", reporter.errors()[1]);
+#endif // DCHECK_IS_ON()
}
} // namespace headless
diff --git a/chromium/headless/public/util/generic_url_request_job.cc b/chromium/headless/public/util/generic_url_request_job.cc
index 9c7245bc430..a82925d9623 100644
--- a/chromium/headless/public/util/generic_url_request_job.cc
+++ b/chromium/headless/public/util/generic_url_request_job.cc
@@ -140,6 +140,7 @@ void GenericURLRequestJob::OnFetchComplete(
scoped_refptr<net::HttpResponseHeaders> response_headers,
const char* body,
size_t body_size) {
+ response_time_ = base::TimeTicks::Now();
http_response_code_ = http_response_code;
response_headers_ = response_headers;
body_ = body;
@@ -186,4 +187,10 @@ bool GenericURLRequestJob::GetCharset(std::string* charset) {
return response_headers_->GetCharset(charset);
}
+void GenericURLRequestJob::GetLoadTimingInfo(
+ net::LoadTimingInfo* load_timing_info) const {
+ // TODO(alexclarke): Investigate setting the other members too where possible.
+ load_timing_info->receive_headers_end = response_time_;
+}
+
} // namespace headless
diff --git a/chromium/headless/public/util/generic_url_request_job.h b/chromium/headless/public/util/generic_url_request_job.h
index 514a5e176f9..850f0ce6c99 100644
--- a/chromium/headless/public/util/generic_url_request_job.h
+++ b/chromium/headless/public/util/generic_url_request_job.h
@@ -95,6 +95,7 @@ class GenericURLRequestJob : public ManagedDispatchURLRequestJob,
void GetResponseInfo(net::HttpResponseInfo* info) override;
bool GetMimeType(std::string* mime_type) const override;
bool GetCharset(std::string* charset) override;
+ void GetLoadTimingInfo(net::LoadTimingInfo* load_timing_info) const override;
// URLFetcher::FetchResultListener implementation:
void OnFetchStartError(net::Error error) override;
@@ -121,6 +122,7 @@ class GenericURLRequestJob : public ManagedDispatchURLRequestJob,
int http_response_code_ = 0;
size_t body_size_ = 0;
size_t read_offset_ = 0;
+ base::TimeTicks response_time_;
base::WeakPtrFactory<GenericURLRequestJob> weak_factory_;
diff --git a/chromium/headless/public/util/generic_url_request_job_test.cc b/chromium/headless/public/util/generic_url_request_job_test.cc
index 989b5f61638..e1942f86e8b 100644
--- a/chromium/headless/public/util/generic_url_request_job_test.cc
+++ b/chromium/headless/public/util/generic_url_request_job_test.cc
@@ -86,6 +86,7 @@ class MockFetcher : public URLFetcher {
response_headers->AddHeader(
base::StringPrintf("%s: %s", it.key().c_str(), value.c_str()));
}
+
result_listener->OnFetchComplete(
GURL(final_url), http_response_code, std::move(response_headers),
response_data_.c_str(), response_data_.size());
@@ -240,6 +241,10 @@ TEST_F(GenericURLRequestJobTest, BasicRequestContents) {
EXPECT_TRUE(request->Read(buffer.get(), kBufferSize, &bytes_read));
EXPECT_EQ(5, bytes_read);
EXPECT_EQ("Reply", std::string(buffer->data(), 5));
+
+ net::LoadTimingInfo load_timing_info;
+ request->GetLoadTimingInfo(&load_timing_info);
+ EXPECT_FALSE(load_timing_info.receive_headers_end.is_null());
}
TEST_F(GenericURLRequestJobTest, ReadInParts) {
diff --git a/chromium/headless/public/util/http_url_fetcher.cc b/chromium/headless/public/util/http_url_fetcher.cc
index cbb2c0ad667..af5451218dd 100644
--- a/chromium/headless/public/util/http_url_fetcher.cc
+++ b/chromium/headless/public/util/http_url_fetcher.cc
@@ -6,6 +6,7 @@
#include "net/base/io_buffer.h"
#include "net/cert/cert_status_flags.h"
+#include "net/http/http_response_headers.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
@@ -165,9 +166,13 @@ void HttpURLFetcher::Delegate::OnResponseCompleted(net::URLRequest* request,
return;
}
- result_listener_->OnFetchCompleteExtractHeaders(
- request->url(), request->GetResponseCode(), bytes_read_so_far_.c_str(),
- bytes_read_so_far_.size());
+ // TODO(alexclarke) apart from the headers there's a lot of stuff in
+ // |request->response_info()| that we drop here. Find a way to pipe it
+ // through.
+ result_listener_->OnFetchComplete(
+ request->url(), request->GetResponseCode(),
+ request->response_info().headers,
+ bytes_read_so_far_.c_str(), bytes_read_so_far_.size());
}
HttpURLFetcher::HttpURLFetcher(
diff --git a/chromium/headless/public/util/testing/fake_managed_dispatch_url_request_job.cc b/chromium/headless/public/util/testing/fake_managed_dispatch_url_request_job.cc
index 24191d3f026..a541cb7af6a 100644
--- a/chromium/headless/public/util/testing/fake_managed_dispatch_url_request_job.cc
+++ b/chromium/headless/public/util/testing/fake_managed_dispatch_url_request_job.cc
@@ -4,6 +4,8 @@
#include "headless/public/util/testing/fake_managed_dispatch_url_request_job.h"
+#include "headless/public/util/url_request_dispatcher.h"
+
namespace headless {
void FakeManagedDispatchURLRequestJob::OnHeadersComplete() {
@@ -14,4 +16,8 @@ void FakeManagedDispatchURLRequestJob::OnStartError(net::Error error) {
notifications_->push_back(base::StringPrintf("id: %d err: %d", id_, error));
}
+void FakeManagedDispatchURLRequestJob::Kill() {
+ url_request_dispatcher_->JobKilled(this);
+}
+
} // namespace headless
diff --git a/chromium/headless/public/util/testing/fake_managed_dispatch_url_request_job.h b/chromium/headless/public/util/testing/fake_managed_dispatch_url_request_job.h
index cb0dabdf5b1..79a749bd261 100644
--- a/chromium/headless/public/util/testing/fake_managed_dispatch_url_request_job.h
+++ b/chromium/headless/public/util/testing/fake_managed_dispatch_url_request_job.h
@@ -31,6 +31,8 @@ class FakeManagedDispatchURLRequestJob : public ManagedDispatchURLRequestJob {
using ManagedDispatchURLRequestJob::DispatchHeadersComplete;
using ManagedDispatchURLRequestJob::DispatchStartError;
+ void Kill() override;
+
void Start() override {}
void OnHeadersComplete() override;