diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-01-31 16:33:43 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-02-06 16:33:22 +0000 |
commit | da51f56cc21233c2d30f0fe0d171727c3102b2e0 (patch) | |
tree | 4e579ab70ce4b19bee7984237f3ce05a96d59d83 /chromium/headless | |
parent | c8c2d1901aec01e934adf561a9fdf0cc776cdef8 (diff) | |
download | qtwebengine-chromium-da51f56cc21233c2d30f0fe0d171727c3102b2e0.tar.gz |
BASELINE: Update Chromium to 65.0.3525.40
Also imports missing submodules
Change-Id: I36901b7c6a325cda3d2c10cedb2186c25af3b79b
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/headless')
59 files changed, 882 insertions, 390 deletions
diff --git a/chromium/headless/BUILD.gn b/chromium/headless/BUILD.gn index 912c913d763..bf0905c2f77 100644 --- a/chromium/headless/BUILD.gn +++ b/chromium/headless/BUILD.gn @@ -430,6 +430,7 @@ component("headless") { "//gin", "//third_party/WebKit/public:blink", "//third_party/WebKit/public:blink_headers", + "//ui/gl", "//v8", ] diff --git a/chromium/headless/README.md b/chromium/headless/README.md index 4a909f19f8d..bad3f0745e4 100644 --- a/chromium/headless/README.md +++ b/chromium/headless/README.md @@ -136,7 +136,8 @@ Bug tracker: [Internals>Headless](https://bugs.chromium.org/p/chromium/issues/li * [Deterministic page loading for Blink](https://docs.google.com/document/d/19s2g4fPP9p9qmMZvwPX8uDGbb-39rgR9k56B4B-ueG8/edit#) * [Crash dumps for Headless Chrome](https://docs.google.com/document/d/1l6AGOOBLk99PaAKoZQW_DVhM8FQ6Fut27lD938CRbTM/edit) * [Runtime headless mode for Chrome](https://docs.google.com/document/d/1aIJUzQr3eougZQp90bp4mqGr5gY6hdUice8UPa-Ys90/edit#) -* [Virtual Time in Blink](https://docs.google.com/document/d/1y9kdt_zezt7pbey6uzvt1dgklwc1ob_vy4nzo1zbqmo/edit#heading=h.tn3gd1y9ifml) +* [Virtual Time in + Blink](https://docs.google.com/document/d/1y9KDT_ZEzT7pBeY6uzVt1dgKlwc1OB_vY4NZO1zBQmo/edit?usp=sharing) * [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) diff --git a/chromium/headless/app/headless_shell.cc b/chromium/headless/app/headless_shell.cc index 1c6537d152c..332713d54ba 100644 --- a/chromium/headless/app/headless_shell.cc +++ b/chromium/headless/app/headless_shell.cc @@ -17,7 +17,6 @@ #include "base/files/file_util.h" #include "base/json/json_writer.h" #include "base/location.h" -#include "base/memory/ptr_util.h" #include "base/memory/weak_ptr.h" #include "base/numerics/safe_conversions.h" #include "base/path_service.h" @@ -160,12 +159,12 @@ void HeadlessShell::OnStart(HeadlessBrowser* browser) { ProtocolHandlerMap protocol_handlers; protocol_handlers[url::kHttpScheme] = - base::MakeUnique<DeterministicHttpProtocolHandler>( + std::make_unique<DeterministicHttpProtocolHandler>( deterministic_dispatcher_.get(), browser->BrowserIOThread()); http_handler = static_cast<DeterministicHttpProtocolHandler*>( protocol_handlers[url::kHttpScheme].get()); protocol_handlers[url::kHttpsScheme] = - base::MakeUnique<DeterministicHttpProtocolHandler>( + std::make_unique<DeterministicHttpProtocolHandler>( deterministic_dispatcher_.get(), browser->BrowserIOThread()); https_handler = static_cast<DeterministicHttpProtocolHandler*>( protocol_handlers[url::kHttpsScheme].get()); @@ -378,7 +377,7 @@ void HeadlessShell::OnRequestIntercepted( DCHECK_CURRENTLY_ON(content::BrowserThread::UI); if (params.GetIsNavigationRequest()) { deterministic_dispatcher_->NavigationRequested( - base::MakeUnique<ShellNavigationRequest>(weak_factory_.GetWeakPtr(), + std::make_unique<ShellNavigationRequest>(weak_factory_.GetWeakPtr(), params.GetInterceptionId())); return; } @@ -519,7 +518,7 @@ void HeadlessShell::WriteFile(const std::string& file_path_switch, return; } - file_proxy_ = base::MakeUnique<base::FileProxy>(file_task_runner_.get()); + file_proxy_ = std::make_unique<base::FileProxy>(file_task_runner_.get()); if (!file_proxy_->CreateOrOpen( file_name, base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE, base::Bind(&HeadlessShell::OnFileOpened, weak_factory_.GetWeakPtr(), diff --git a/chromium/headless/app/headless_shell_switches.cc b/chromium/headless/app/headless_shell_switches.cc index e2cabfa3bcf..be4da2be041 100644 --- a/chromium/headless/app/headless_shell_switches.cc +++ b/chromium/headless/app/headless_shell_switches.cc @@ -109,5 +109,8 @@ const char kVirtualTimeBudget[] = "virtual-time-budget"; // Sets the initial window size. Provided as string in the format "800,600". const char kWindowSize[] = "window-size"; +// Whitelist for Negotitate Auth servers. +const char kAuthServerWhitelist[] = "auth-server-whitelist"; + } // namespace switches } // namespace headless diff --git a/chromium/headless/app/headless_shell_switches.h b/chromium/headless/app/headless_shell_switches.h index 6011f3c22d0..cef83537449 100644 --- a/chromium/headless/app/headless_shell_switches.h +++ b/chromium/headless/app/headless_shell_switches.h @@ -32,6 +32,7 @@ extern const char kUserAgent[]; extern const char kUserDataDir[]; extern const char kVirtualTimeBudget[]; extern const char kWindowSize[]; +extern const char kAuthServerWhitelist[]; // Switches which are replicated from content. using ::switches::kHostResolverRules; diff --git a/chromium/headless/app/shell_navigation_request.cc b/chromium/headless/app/shell_navigation_request.cc index 3f5344d7d02..e1af96b5417 100644 --- a/chromium/headless/app/shell_navigation_request.cc +++ b/chromium/headless/app/shell_navigation_request.cc @@ -4,6 +4,8 @@ #include "headless/app/shell_navigation_request.h" +#include <memory> + #include "content/public/browser/browser_thread.h" #include "headless/app/headless_shell.h" @@ -13,7 +15,7 @@ ShellNavigationRequest::ShellNavigationRequest( base::WeakPtr<HeadlessShell> headless_shell, const std::string& interception_id) : headless_shell_( - base::MakeUnique<base::WeakPtr<HeadlessShell>>(headless_shell)), + std::make_unique<base::WeakPtr<HeadlessShell>>(headless_shell)), interception_id_(interception_id) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); } diff --git a/chromium/headless/lib/browser/DEPS b/chromium/headless/lib/browser/DEPS index 78c24cf79da..328f550405b 100644 --- a/chromium/headless/lib/browser/DEPS +++ b/chromium/headless/lib/browser/DEPS @@ -8,6 +8,7 @@ include_rules = [ "+storage/browser/quota", "+storage/common/quota", "+third_party/skia/include", + "+third_party/WebKit/common/quota", "+ui/aura", "+ui/compositor", ] diff --git a/chromium/headless/lib/browser/devtools_api/domain_cc.template b/chromium/headless/lib/browser/devtools_api/domain_cc.template index ac16d62dd52..c2071aa5d8e 100644 --- a/chromium/headless/lib/browser/devtools_api/domain_cc.template +++ b/chromium/headless/lib/browser/devtools_api/domain_cc.template @@ -104,7 +104,7 @@ void Domain::Handle{{method_name}}Response(base::Callback<void(std::unique_ptr<{ if (callback.is_null()) return; // This is an error response. - if (response.IsType(base::Value::Type::NONE)) { + if (response.is_none()) { callback.Run(nullptr); return; } diff --git a/chromium/headless/lib/browser/devtools_api/domain_externs_js.template b/chromium/headless/lib/browser/devtools_api/domain_externs_js.template index 8e01c0fd2a2..a2fc689ffba 100644 --- a/chromium/headless/lib/browser/devtools_api/domain_externs_js.template +++ b/chromium/headless/lib/browser/devtools_api/domain_externs_js.template @@ -43,7 +43,7 @@ chromium.DevTools.{{domain.domain}}.prototype.removeEventListener = function(id) {% if not "enum" in type %}{% continue %}{% endif %} /** {% if type.description %} - * {{type.description}} + * {{type.description.replace('\n', '\n * ')}} * {% endif %} * @enum {string} @@ -61,12 +61,12 @@ chromium.DevTools.{{domain.domain}}.{{type.id}} = { {% if not (type.type == "object") or not ("properties" in type) %}{% continue %}{% endif %} /** {% if type.description %} - * {{type.description}} + * {{type.description.replace('\n', '\n * ')}} * {% endif %} {% for property in type.properties %} {% if property.description %} - * {{property.name}}: {{property.description}} + * {{property.name}}: {{property.description.replace('\n', '\n * ')}} {% endif %} {% endfor %} * @@ -96,7 +96,7 @@ chromium.DevTools.{{domain.domain}}.{{type.id}}; /** {% if command.description %} - * {{ command.description }} + * {{ command.description.replace('\n', '\n * ') }} * {% endif %} {% if command.parameters|length > 0 %} @@ -129,7 +129,7 @@ chromium.DevTools.Experimental{{domain.domain}}.prototype.{{method_name}} = func /** {% if event.description %} - * {{ event.description }} + * {{ event.description.replace('\n', '\n * ') }} * {% endif %} * @param {{param_type}} listener @@ -148,7 +148,7 @@ chromium.DevTools.Experimental{{domain.domain}}.prototype.on{{event.name | to_ti /** {% if command.description %} - * {{ command.description }} + * {{ command.description.replace('\n', '\n * ') }} * {% endif %} {% if command.parameters|length > 0 %} @@ -182,7 +182,7 @@ chromium.DevTools.{{domain.domain}}.prototype.{{method_name}} = function() {}; /** {% if event.description %} - * {{ event.description }} + * {{ event.description.replace('\n', '\n * ') }} * {% endif %} * @param {{param_type}} listener diff --git a/chromium/headless/lib/browser/devtools_api/domain_h.template b/chromium/headless/lib/browser/devtools_api/domain_h.template index 74b6b7a62bf..680f5c1a3aa 100644 --- a/chromium/headless/lib/browser/devtools_api/domain_h.template +++ b/chromium/headless/lib/browser/devtools_api/domain_h.template @@ -20,7 +20,7 @@ {% macro command_decl(command) %} {% set method_name = command.name | sanitize_literal | to_title_case %} {% if command.description %} - // {{ command.description }} + // {{ command.description.replace('\n', '\n // ') }} {% endif %} void {{method_name}}(std::unique_ptr<{{method_name}}Params> params, base::Callback<void(std::unique_ptr<{{method_name}}Result>)> callback = base::Callback<void(std::unique_ptr<{{method_name}}Result>)>()); {# Generate convenience methods that take the required parameters directly. #} @@ -59,7 +59,7 @@ class HEADLESS_EXPORT ExperimentalObserver { virtual ~ExperimentalObserver() {} {% for event in domain.events %} {% if event.description %} - // {{event.description}} + // {{event.description.replace('\n', '\n // ')}} {% endif %} virtual void On{{event.name | to_title_case}}(const {{event.name | to_title_case}}Params& params) {} {% endfor %} @@ -70,7 +70,7 @@ class HEADLESS_EXPORT Observer : public ExperimentalObserver { virtual ~Observer() {} {% for event in domain.events %} {% if event.description %} - // {% if event.experimental %}Experimental: {% endif %}{{event.description}} + // {% if event.experimental %}Experimental: {% endif %}{{event.description.replace('\n', '\n // ')}} {% endif %} virtual void On{{event.name | to_title_case}}(const {{event.name | to_title_case}}Params& params) {% if event.experimental %}final {% endif %}{} {% endfor %} @@ -78,7 +78,7 @@ class HEADLESS_EXPORT Observer : public ExperimentalObserver { {% endif %} {% if domain.description %} -// {{domain.description}} +// {{domain.description.replace('\n', '\n// ')}} {% endif %} class HEADLESS_EXPORT Domain { public: diff --git a/chromium/headless/lib/browser/devtools_api/domain_js.template b/chromium/headless/lib/browser/devtools_api/domain_js.template index be236a5d9bf..4f18227c176 100644 --- a/chromium/headless/lib/browser/devtools_api/domain_js.template +++ b/chromium/headless/lib/browser/devtools_api/domain_js.template @@ -78,7 +78,7 @@ const {{domain.domain}} = chromium.DevTools.{{domain.domain}}; {% if not "enum" in type %}{% continue %}{% endif %} /** {% if type.description %} - * {{type.description}} + * {{type.description.replace('\n', '\n * ')}} * {% endif %} * @enum {string} @@ -96,12 +96,12 @@ const {{domain.domain}} = chromium.DevTools.{{domain.domain}}; {% if not (type.type == "object") or not ("properties" in type) %}{% continue %}{% endif %} /** {% if type.description %} - * {{type.description}} + * {{type.description.replace('\n', '\n * ')}} * {% endif %} {% for property in type.properties %} {% if property.description %} - * {{property.name}}: {{property.description}} + * {{property.name}}: {{property.description.replace('\n', '\n * ')}} {% endif %} {% endfor %} * @@ -131,7 +131,7 @@ const {{domain.domain}} = chromium.DevTools.{{domain.domain}}; /** {% if command.description %} - * {{ command.description }} + * {{ command.description.replace('\n', '\n * ') }} * {% endif %} {% if command.parameters|length > 0 %} @@ -170,7 +170,7 @@ Experimental{{domain.domain}}.prototype.{{method_name}} = function() { /** {% if event.description %} - * {{ event.description }} + * {{ event.description.replace('\n', '\n * ') }} * {% endif %} * @param {{param_type}} listener @@ -192,7 +192,7 @@ Experimental{{domain.domain}}.prototype.on{{event.name | to_title_case}} = funct /** {% if command.description %} - * {{ command.description }} + * {{ command.description.replace('\n', '\n * ') }} * {% endif %} {% if command.parameters|length > 0 %} @@ -232,7 +232,7 @@ Experimental{{domain.domain}}.prototype.on{{event.name | to_title_case}} = funct /** {% if event.description %} - * {{ event.description }} + * {{ event.description.replace('\n', '\n * ') }} * {% endif %} * @param {{param_type}} listener diff --git a/chromium/headless/lib/browser/devtools_api/domain_types_h.template b/chromium/headless/lib/browser/devtools_api/domain_types_h.template index 572f0819ef0..bb6d9868192 100644 --- a/chromium/headless/lib/browser/devtools_api/domain_types_h.template +++ b/chromium/headless/lib/browser/devtools_api/domain_types_h.template @@ -23,7 +23,7 @@ namespace {{domain.domain | camelcase_to_hacker_style}} { {% if not (type.type == "object") or not ("properties" in type) %}{% continue %}{% endif %} {% if type.description %} -// {{type.description}} +// {{type.description.replace('\n', '\n// ')}} {% endif %} class HEADLESS_EXPORT {{type.id}} { public: @@ -32,7 +32,7 @@ class HEADLESS_EXPORT {{type.id}} { {% for property in type.properties %} {% if property.description %} - // {{property.description}} + // {{property.description.replace('\n', '\n // ')}} {% endif %} {% if property.optional %} bool Has{{property.name | to_title_case}}() const { return !!{{property.name | camelcase_to_hacker_style}}_; } diff --git a/chromium/headless/lib/browser/headless_browser_context_impl.cc b/chromium/headless/lib/browser/headless_browser_context_impl.cc index 17849e27819..527b31d9d74 100644 --- a/chromium/headless/lib/browser/headless_browser_context_impl.cc +++ b/chromium/headless/lib/browser/headless_browser_context_impl.cc @@ -10,7 +10,6 @@ #include <vector> #include "base/guid.h" -#include "base/memory/ptr_util.h" #include "base/path_service.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/resource_context.h" @@ -103,12 +102,20 @@ HeadlessBrowserContextImpl::~HeadlessBrowserContextImpl() { // Destroy all web contents before shutting down storage partitions. web_contents_map_.clear(); - ShutdownStoragePartitions(); - if (resource_context_) { content::BrowserThread::DeleteSoon(content::BrowserThread::IO, FROM_HERE, resource_context_.release()); } + + ShutdownStoragePartitions(); + + if (url_request_getter_) { + content::BrowserThread::PostTask( + content::BrowserThread::IO, FROM_HERE, + base::BindOnce( + &HeadlessURLRequestContextGetter::NotifyContextShuttingDown, + url_request_getter_)); + } } // static @@ -275,15 +282,14 @@ HeadlessBrowserContextImpl::GetBrowsingDataRemoverDelegate() { net::URLRequestContextGetter* HeadlessBrowserContextImpl::CreateRequestContext( content::ProtocolHandlerMap* protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptors) { - scoped_refptr<HeadlessURLRequestContextGetter> url_request_context_getter( - new HeadlessURLRequestContextGetter( - content::BrowserThread::GetTaskRunnerForThread( - content::BrowserThread::IO), - protocol_handlers, context_options_->TakeProtocolHandlers(), - std::move(request_interceptors), context_options_.get(), - browser_->browser_main_parts()->net_log(), this)); - resource_context_->set_url_request_context_getter(url_request_context_getter); - return url_request_context_getter.get(); + url_request_getter_ = base::MakeRefCounted<HeadlessURLRequestContextGetter>( + content::BrowserThread::GetTaskRunnerForThread( + content::BrowserThread::IO), + protocol_handlers, context_options_->TakeProtocolHandlers(), + std::move(request_interceptors), context_options_.get(), + browser_->net_log(), this); + resource_context_->set_url_request_context_getter(url_request_getter_); + return url_request_getter_.get(); } net::URLRequestContextGetter* @@ -510,9 +516,9 @@ HeadlessBrowserContext* HeadlessBrowserContext::Builder::Build() { // context with mojo bindings. if (!enable_http_and_https_if_mojo_used_) { options_->protocol_handlers_[url::kHttpScheme] = - base::MakeUnique<BlackHoleProtocolHandler>(); + std::make_unique<BlackHoleProtocolHandler>(); options_->protocol_handlers_[url::kHttpsScheme] = - base::MakeUnique<BlackHoleProtocolHandler>(); + std::make_unique<BlackHoleProtocolHandler>(); } } diff --git a/chromium/headless/lib/browser/headless_browser_context_impl.h b/chromium/headless/lib/browser/headless_browser_context_impl.h index d84727c1a5d..1a753a5344f 100644 --- a/chromium/headless/lib/browser/headless_browser_context_impl.h +++ b/chromium/headless/lib/browser/headless_browser_context_impl.h @@ -133,6 +133,7 @@ class HeadlessBrowserContextImpl : public HeadlessBrowserContext, HeadlessBrowserImpl* browser_; // Not owned. std::unique_ptr<HeadlessBrowserContextOptions> context_options_; std::unique_ptr<HeadlessResourceContext> resource_context_; + scoped_refptr<HeadlessURLRequestContextGetter> url_request_getter_; base::FilePath path_; base::Lock observers_lock_; base::ObserverList<Observer> observers_; diff --git a/chromium/headless/lib/browser/headless_browser_impl.cc b/chromium/headless/lib/browser/headless_browser_impl.cc index 88bede99b53..86fc0a336ba 100644 --- a/chromium/headless/lib/browser/headless_browser_impl.cc +++ b/chromium/headless/lib/browser/headless_browser_impl.cc @@ -20,6 +20,7 @@ #include "headless/app/headless_shell_switches.h" #include "headless/lib/browser/headless_browser_context_impl.h" #include "headless/lib/browser/headless_browser_main_parts.h" +#include "headless/lib/browser/headless_net_log.h" #include "headless/lib/browser/headless_web_contents_impl.h" #include "headless/lib/headless_content_main_delegate.h" #include "headless/public/internal/headless_devtools_client_impl.h" @@ -138,6 +139,18 @@ void HeadlessBrowserImpl::set_browser_main_parts( browser_main_parts_ = browser_main_parts; } +void HeadlessBrowserImpl::PreMainMessageLoopRun() { + const base::CommandLine* command_line = + base::CommandLine::ForCurrentProcess(); + if (command_line->HasSwitch(::switches::kLogNetLog)) { + base::FilePath log_path = + command_line->GetSwitchValuePath(::switches::kLogNetLog); + net_log_.reset(new HeadlessNetLog(log_path)); + } else { + net_log_.reset(new net::NetLog()); + } +} + void HeadlessBrowserImpl::RunOnStartCallback() { #if defined(USE_NSS_CERTS) content::BrowserThread::PostTask( diff --git a/chromium/headless/lib/browser/headless_browser_impl.h b/chromium/headless/lib/browser/headless_browser_impl.h index 7f4ec64dc20..1366f83d4b3 100644 --- a/chromium/headless/lib/browser/headless_browser_impl.h +++ b/chromium/headless/lib/browser/headless_browser_impl.h @@ -20,6 +20,10 @@ #include "headless/public/headless_export.h" #include "headless/public/util/moveable_auto_lock.h" +namespace net { +class NetLog; +} // namespace net + namespace ui { class Compositor; } // namespace ui @@ -65,9 +69,11 @@ class HEADLESS_EXPORT HeadlessBrowserImpl : public HeadlessBrowser, void set_browser_main_parts(HeadlessBrowserMainParts* browser_main_parts); HeadlessBrowserMainParts* browser_main_parts() const; + void PreMainMessageLoopRun(); void RunOnStartCallback(); HeadlessBrowser::Options* options() { return &options_; } + net::NetLog* net_log() const { return net_log_.get(); } HeadlessBrowserContext* CreateBrowserContext( HeadlessBrowserContext::Builder* builder); @@ -98,6 +104,7 @@ class HEADLESS_EXPORT HeadlessBrowserImpl : public HeadlessBrowser, protected: base::Callback<void(HeadlessBrowser*)> on_start_callback_; HeadlessBrowser::Options options_; + std::unique_ptr<net::NetLog> net_log_; HeadlessBrowserMainParts* browser_main_parts_; // Not owned. mutable base::Lock browser_contexts_lock_; // Protects |browser_contexts_| diff --git a/chromium/headless/lib/browser/headless_browser_impl_aura.cc b/chromium/headless/lib/browser/headless_browser_impl_aura.cc index ccebd342f9a..fc2392c7b74 100644 --- a/chromium/headless/lib/browser/headless_browser_impl_aura.cc +++ b/chromium/headless/lib/browser/headless_browser_impl_aura.cc @@ -4,6 +4,8 @@ #include "headless/lib/browser/headless_browser_impl.h" +#include <memory> + #include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/web_contents.h" #include "headless/lib/browser/headless_clipboard.h" @@ -24,7 +26,7 @@ void HeadlessBrowserImpl::PlatformInitialize() { // TODO(eseckler): We shouldn't share clipboard contents across WebContents // (or at least BrowserContexts). ui::Clipboard::SetClipboardForCurrentThread( - base::MakeUnique<HeadlessClipboard>()); + std::make_unique<HeadlessClipboard>()); } void HeadlessBrowserImpl::PlatformStart() { @@ -34,7 +36,7 @@ void HeadlessBrowserImpl::PlatformStart() { void HeadlessBrowserImpl::PlatformInitializeWebContents( HeadlessWebContentsImpl* web_contents) { - auto window_tree_host = base::MakeUnique<HeadlessWindowTreeHost>( + auto window_tree_host = std::make_unique<HeadlessWindowTreeHost>( gfx::Rect(), web_contents->begin_frame_control_enabled()); window_tree_host->InitHost(); gfx::NativeWindow parent_window = window_tree_host->window(); diff --git a/chromium/headless/lib/browser/headless_browser_main_parts.cc b/chromium/headless/lib/browser/headless_browser_main_parts.cc index da66fb7f75d..d3a767ecda1 100644 --- a/chromium/headless/lib/browser/headless_browser_main_parts.cc +++ b/chromium/headless/lib/browser/headless_browser_main_parts.cc @@ -4,12 +4,9 @@ #include "headless/lib/browser/headless_browser_main_parts.h" -#include "base/command_line.h" -#include "content/public/common/content_switches.h" #include "headless/lib/browser/headless_browser_context_impl.h" #include "headless/lib/browser/headless_browser_impl.h" #include "headless/lib/browser/headless_devtools.h" -#include "headless/lib/browser/headless_net_log.h" #include "headless/lib/browser/headless_screen.h" namespace headless { @@ -21,15 +18,7 @@ HeadlessBrowserMainParts::HeadlessBrowserMainParts(HeadlessBrowserImpl* browser) HeadlessBrowserMainParts::~HeadlessBrowserMainParts() = default; void HeadlessBrowserMainParts::PreMainMessageLoopRun() { - const base::CommandLine* command_line = - base::CommandLine::ForCurrentProcess(); - if (command_line->HasSwitch(switches::kLogNetLog)) { - base::FilePath log_path = - command_line->GetSwitchValuePath(switches::kLogNetLog); - net_log_.reset(new HeadlessNetLog(log_path)); - } else { - net_log_.reset(new net::NetLog()); - } + browser_->PreMainMessageLoopRun(); if (browser_->options()->DevtoolsServerEnabled()) { StartLocalDevToolsHttpHandler(browser_->options()); diff --git a/chromium/headless/lib/browser/headless_browser_main_parts.h b/chromium/headless/lib/browser/headless_browser_main_parts.h index 78ee2704f41..1a8a1c83a30 100644 --- a/chromium/headless/lib/browser/headless_browser_main_parts.h +++ b/chromium/headless/lib/browser/headless_browser_main_parts.h @@ -11,10 +11,6 @@ #include "content/public/browser/browser_main_parts.h" #include "headless/public/headless_browser.h" -namespace net { -class NetLog; -} // namespace net - namespace headless { class HeadlessBrowserImpl; @@ -31,13 +27,10 @@ class HeadlessBrowserMainParts : public content::BrowserMainParts { void PreMainMessageLoopStart() override; #endif - net::NetLog* net_log() const { return net_log_.get(); } - private: HeadlessBrowserImpl* browser_; // Not owned. bool devtools_http_handler_started_; - std::unique_ptr<net::NetLog> net_log_; DISALLOW_COPY_AND_ASSIGN(HeadlessBrowserMainParts); }; diff --git a/chromium/headless/lib/browser/headless_content_browser_client.cc b/chromium/headless/lib/browser/headless_content_browser_client.cc index 98434626717..f8b93141a96 100644 --- a/chromium/headless/lib/browser/headless_content_browser_client.cc +++ b/chromium/headless/lib/browser/headless_content_browser_client.cc @@ -11,7 +11,6 @@ #include "base/callback.h" #include "base/command_line.h" #include "base/json/json_reader.h" -#include "base/memory/ptr_util.h" #include "base/path_service.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" @@ -124,7 +123,7 @@ HeadlessContentBrowserClient::~HeadlessContentBrowserClient() = default; content::BrowserMainParts* HeadlessContentBrowserClient::CreateBrowserMainParts( const content::MainFunctionParams&) { std::unique_ptr<HeadlessBrowserMainParts> browser_main_parts = - base::MakeUnique<HeadlessBrowserMainParts>(browser_); + std::make_unique<HeadlessBrowserMainParts>(browser_); browser_->set_browser_main_parts(browser_main_parts.get()); return browser_main_parts.release(); } @@ -303,7 +302,7 @@ void HeadlessContentBrowserClient::AllowCertificateError( // was for localhost, then the error was not fatal. bool allow_localhost = base::CommandLine::ForCurrentProcess()->HasSwitch( ::switches::kAllowInsecureLocalhost); - if (allow_localhost && net::IsLocalhost(request_url.host())) { + if (allow_localhost && net::IsLocalhost(request_url)) { callback.Run(content::CERTIFICATE_REQUEST_RESULT_TYPE_CONTINUE); return; } @@ -320,7 +319,7 @@ void HeadlessContentBrowserClient::ResourceDispatcherHostCreated() { } net::NetLog* HeadlessContentBrowserClient::GetNetLog() { - return browser_->browser_main_parts()->net_log(); + return browser_->net_log(); } bool HeadlessContentBrowserClient::AllowGetCookie( diff --git a/chromium/headless/lib/browser/headless_devtools_client_impl.cc b/chromium/headless/lib/browser/headless_devtools_client_impl.cc index 9763565c59b..1c21cd70a16 100644 --- a/chromium/headless/lib/browser/headless_devtools_client_impl.cc +++ b/chromium/headless/lib/browser/headless_devtools_client_impl.cc @@ -144,7 +144,7 @@ void HeadlessDevToolsClientImpl::DispatchProtocolMessage( base::JSONReader::Read(json_message, base::JSON_PARSE_RFC); const base::DictionaryValue* message_dict; if (!message || !message->GetAsDictionary(&message_dict)) { - NOTREACHED() << "Badly formed reply"; + NOTREACHED() << "Badly formed reply " << json_message; return; } @@ -177,7 +177,7 @@ bool HeadlessDevToolsClientImpl::DispatchMessageReply( if (message_dict.GetDictionary("result", &result_dict)) { callback.callback_with_result.Run(*result_dict); } else if (message_dict.GetDictionary("error", &result_dict)) { - auto null_value = base::MakeUnique<base::Value>(); + auto null_value = std::make_unique<base::Value>(); DLOG(ERROR) << "Error in method call result: " << *result_dict; callback.callback_with_result.Run(*null_value); } else { diff --git a/chromium/headless/lib/browser/headless_devtools_manager_delegate.cc b/chromium/headless/lib/browser/headless_devtools_manager_delegate.cc index 553d7159b51..485be57f727 100644 --- a/chromium/headless/lib/browser/headless_devtools_manager_delegate.cc +++ b/chromium/headless/lib/browser/headless_devtools_manager_delegate.cc @@ -50,9 +50,9 @@ std::unique_ptr<base::DictionaryValue> CreateSuccessResponse( int command_id, std::unique_ptr<base::Value> result) { if (!result) - result = base::MakeUnique<base::DictionaryValue>(); + result = std::make_unique<base::DictionaryValue>(); - auto response = base::MakeUnique<base::DictionaryValue>(); + auto response = std::make_unique<base::DictionaryValue>(); response->SetInteger(kIdParam, command_id); response->Set(kResultParam, std::move(result)); return response; @@ -62,11 +62,11 @@ std::unique_ptr<base::DictionaryValue> CreateErrorResponse( int command_id, int error_code, const std::string& error_message) { - auto error_object = base::MakeUnique<base::DictionaryValue>(); + auto error_object = std::make_unique<base::DictionaryValue>(); error_object->SetInteger(kErrorCodeParam, error_code); error_object->SetString(kErrorMessageParam, error_message); - auto response = base::MakeUnique<base::DictionaryValue>(); + auto response = std::make_unique<base::DictionaryValue>(); response->SetInteger(kIdParam, command_id); response->Set(kErrorParam, std::move(error_object)); return response; @@ -82,7 +82,7 @@ std::unique_ptr<base::DictionaryValue> CreateInvalidParamResponse( std::unique_ptr<base::DictionaryValue> CreateBoundsDict( const HeadlessWebContentsImpl* web_contents) { - auto bounds_object = base::MakeUnique<base::DictionaryValue>(); + auto bounds_object = std::make_unique<base::DictionaryValue>(); gfx::Rect bounds = web_contents->web_contents()->GetContainerBounds(); bounds_object->SetInteger("left", bounds.x()); bounds_object->SetInteger("top", bounds.y()); @@ -157,7 +157,7 @@ void OnBeginFrameFinished( bool has_damage, bool main_frame_content_updated, std::unique_ptr<SkBitmap> bitmap) { - auto result = base::MakeUnique<base::DictionaryValue>(); + auto result = std::make_unique<base::DictionaryValue>(); result->SetBoolean("hasDamage", has_damage); result->SetBoolean("mainFrameContentUpdated", main_frame_content_updated); @@ -247,6 +247,15 @@ std::unique_ptr<base::DictionaryValue> ParsePrintSettings( if (const base::Value* margin_right_value = params->FindKey("marginRight")) margin_right_in_inch = margin_right_value->GetDouble(); + if (const base::Value* header_template_value = + params->FindKey("headerTemplate")) { + settings->header_template = header_template_value->GetString(); + } + if (const base::Value* footer_template_value = + params->FindKey("footerTemplate")) { + settings->footer_template = footer_template_value->GetString(); + } + if (margin_top_in_inch < 0) return CreateInvalidParamResponse(command_id, "marginTop"); if (margin_bottom_in_inch < 0) @@ -317,7 +326,7 @@ HeadlessDevToolsManagerDelegate::~HeadlessDevToolsManagerDelegate() = default; bool HeadlessDevToolsManagerDelegate::HandleCommand( content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, base::DictionaryValue* command) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -339,7 +348,7 @@ bool HeadlessDevToolsManagerDelegate::HandleCommand( // handle. find_it = unhandled_command_map_.find(method); if (find_it != unhandled_command_map_.end()) - find_it->second.Run(agent_host, session_id, id_value->GetInt(), params); + find_it->second.Run(agent_host, client, id_value->GetInt(), params); return false; } @@ -349,17 +358,16 @@ bool HeadlessDevToolsManagerDelegate::HandleCommand( return false; auto cmd_result = - find_it->second.Run(agent_host, session_id, id_value->GetInt(), params); + find_it->second.Run(agent_host, client, id_value->GetInt(), params); if (!cmd_result) return false; - agent_host->SendProtocolMessageToClient(session_id, - ToString(std::move(cmd_result))); + client->DispatchProtocolMessage(agent_host, ToString(std::move(cmd_result))); return true; } bool HeadlessDevToolsManagerDelegate::HandleAsyncCommand( content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, base::DictionaryValue* command, const CommandCallback& callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -378,8 +386,7 @@ bool HeadlessDevToolsManagerDelegate::HandleAsyncCommand( const base::DictionaryValue* params = nullptr; command->GetDictionary("params", ¶ms); - find_it->second.Run(agent_host, session_id, id_value->GetInt(), params, - callback); + find_it->second.Run(agent_host, client, id_value->GetInt(), params, callback); return true; } @@ -409,9 +416,9 @@ std::string HeadlessDevToolsManagerDelegate::GetFrontendResource( return content::DevToolsFrontendHost::GetFrontendResource(path).as_string(); } -void HeadlessDevToolsManagerDelegate::SessionDestroyed( +void HeadlessDevToolsManagerDelegate::ClientDetached( content::DevToolsAgentHost* agent_host, - int session_id) { + content::DevToolsAgentHostClient* client) { if (!browser_) return; @@ -424,12 +431,12 @@ void HeadlessDevToolsManagerDelegate::SessionDestroyed( if (!headless_contents) return; - headless_contents->SetBeginFrameEventsEnabled(session_id, false); + headless_contents->SetBeginFrameEventsEnabled(client, false); } void HeadlessDevToolsManagerDelegate::PrintToPDF( content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, int command_id, const base::DictionaryValue* params, const CommandCallback& callback) { @@ -463,7 +470,7 @@ void HeadlessDevToolsManagerDelegate::PrintToPDF( std::unique_ptr<base::DictionaryValue> HeadlessDevToolsManagerDelegate::CreateTarget( content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, int command_id, const base::DictionaryValue* params) { std::string url; @@ -536,7 +543,7 @@ HeadlessDevToolsManagerDelegate::CreateTarget( std::unique_ptr<base::DictionaryValue> HeadlessDevToolsManagerDelegate::CloseTarget( content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, int command_id, const base::DictionaryValue* params) { const base::Value* target_id_value = params->FindKey("targetId"); @@ -560,7 +567,7 @@ HeadlessDevToolsManagerDelegate::CloseTarget( std::unique_ptr<base::DictionaryValue> HeadlessDevToolsManagerDelegate::CreateBrowserContext( content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, int command_id, const base::DictionaryValue* params) { HeadlessBrowserContext* browser_context = @@ -577,7 +584,7 @@ HeadlessDevToolsManagerDelegate::CreateBrowserContext( std::unique_ptr<base::DictionaryValue> HeadlessDevToolsManagerDelegate::DisposeBrowserContext( content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, int command_id, const base::DictionaryValue* params) { const base::Value* browser_context_id_value = @@ -606,7 +613,7 @@ HeadlessDevToolsManagerDelegate::DisposeBrowserContext( std::unique_ptr<base::DictionaryValue> HeadlessDevToolsManagerDelegate::GetWindowForTarget( content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, int command_id, const base::DictionaryValue* params) { const base::Value* target_id_value = params->FindKey("targetId"); @@ -621,7 +628,7 @@ HeadlessDevToolsManagerDelegate::GetWindowForTarget( "No web contents for the given target id"); } - auto result = base::MakeUnique<base::DictionaryValue>(); + auto result = std::make_unique<base::DictionaryValue>(); result->SetInteger("windowId", web_contents->window_id()); result->Set("bounds", CreateBoundsDict(web_contents)); return CreateSuccessResponse(command_id, std::move(result)); @@ -629,7 +636,7 @@ HeadlessDevToolsManagerDelegate::GetWindowForTarget( std::unique_ptr<base::DictionaryValue> HeadlessDevToolsManagerDelegate::Close( content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, int command_id, const base::DictionaryValue* params) { content::BrowserThread::PostTask( @@ -642,7 +649,7 @@ std::unique_ptr<base::DictionaryValue> HeadlessDevToolsManagerDelegate::Close( std::unique_ptr<base::DictionaryValue> HeadlessDevToolsManagerDelegate::GetWindowBounds( content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, int command_id, const base::DictionaryValue* params) { HeadlessWebContentsImpl* web_contents; @@ -655,7 +662,7 @@ HeadlessDevToolsManagerDelegate::GetWindowBounds( "Browser window not found"); } - auto result = base::MakeUnique<base::DictionaryValue>(); + auto result = std::make_unique<base::DictionaryValue>(); result->Set("bounds", CreateBoundsDict(web_contents)); return CreateSuccessResponse(command_id, std::move(result)); } @@ -663,7 +670,7 @@ HeadlessDevToolsManagerDelegate::GetWindowBounds( std::unique_ptr<base::DictionaryValue> HeadlessDevToolsManagerDelegate::SetWindowBounds( content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, int command_id, const base::DictionaryValue* params) { HeadlessWebContentsImpl* web_contents; @@ -744,7 +751,7 @@ HeadlessDevToolsManagerDelegate::SetWindowBounds( std::unique_ptr<base::DictionaryValue> HeadlessDevToolsManagerDelegate::EmulateNetworkConditions( content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, int command_id, const base::DictionaryValue* params) { // Associate NetworkConditions to context @@ -774,7 +781,7 @@ HeadlessDevToolsManagerDelegate::EmulateNetworkConditions( std::unique_ptr<base::DictionaryValue> HeadlessDevToolsManagerDelegate::NetworkDisable( content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, int command_id, const base::DictionaryValue* params) { std::vector<HeadlessBrowserContext*> browser_contexts = @@ -800,7 +807,7 @@ void HeadlessDevToolsManagerDelegate::SetNetworkConditions( std::unique_ptr<base::DictionaryValue> HeadlessDevToolsManagerDelegate::EnableHeadlessExperimental( content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, int command_id, const base::DictionaryValue* params) { content::WebContents* web_contents = agent_host->GetWebContents(); @@ -811,14 +818,14 @@ HeadlessDevToolsManagerDelegate::EnableHeadlessExperimental( HeadlessWebContentsImpl* headless_contents = HeadlessWebContentsImpl::From(browser_.get(), web_contents); - headless_contents->SetBeginFrameEventsEnabled(session_id, true); + headless_contents->SetBeginFrameEventsEnabled(client, true); return CreateSuccessResponse(command_id, nullptr); } std::unique_ptr<base::DictionaryValue> HeadlessDevToolsManagerDelegate::DisableHeadlessExperimental( content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, int command_id, const base::DictionaryValue* params) { content::WebContents* web_contents = agent_host->GetWebContents(); @@ -829,13 +836,13 @@ HeadlessDevToolsManagerDelegate::DisableHeadlessExperimental( HeadlessWebContentsImpl* headless_contents = HeadlessWebContentsImpl::From(browser_.get(), web_contents); - headless_contents->SetBeginFrameEventsEnabled(session_id, false); + headless_contents->SetBeginFrameEventsEnabled(client, false); return CreateSuccessResponse(command_id, nullptr); } void HeadlessDevToolsManagerDelegate::BeginFrame( content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, int command_id, const base::DictionaryValue* params, const CommandCallback& callback) { @@ -861,6 +868,7 @@ void HeadlessDevToolsManagerDelegate::BeginFrame( base::TimeTicks frame_timeticks; base::TimeTicks deadline; base::TimeDelta interval; + bool no_display_updates = false; if (const base::Value* frame_time_value = params->FindKey("frameTime")) { frame_time = base::Time::FromJsTime(frame_time_value->GetDouble()); @@ -895,6 +903,11 @@ void HeadlessDevToolsManagerDelegate::BeginFrame( deadline = frame_timeticks + interval; } + if (const base::Value* no_display_updates_value = + params->FindKey("noDisplayUpdates")) { + no_display_updates = no_display_updates_value->GetBool(); + } + bool capture_screenshot = false; ImageEncoding encoding = ImageEncoding::kPng; int quality = kDefaultScreenshotQuality; @@ -942,7 +955,7 @@ void HeadlessDevToolsManagerDelegate::BeginFrame( } headless_contents->BeginFrame(frame_timeticks, deadline, interval, - capture_screenshot, + no_display_updates, capture_screenshot, base::Bind(&OnBeginFrameFinished, command_id, callback, encoding, quality)); } diff --git a/chromium/headless/lib/browser/headless_devtools_manager_delegate.h b/chromium/headless/lib/browser/headless_devtools_manager_delegate.h index b8fb8a81110..16e0e02a876 100644 --- a/chromium/headless/lib/browser/headless_devtools_manager_delegate.h +++ b/chromium/headless/lib/browser/headless_devtools_manager_delegate.h @@ -42,10 +42,10 @@ class HeadlessDevToolsManagerDelegate // DevToolsManagerDelegate implementation: bool HandleCommand(content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, base::DictionaryValue* command) override; bool HandleAsyncCommand(content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, base::DictionaryValue* command, const CommandCallback& callback) override; scoped_refptr<content::DevToolsAgentHost> CreateNewTarget( @@ -53,68 +53,68 @@ class HeadlessDevToolsManagerDelegate std::string GetDiscoveryPageHTML() override; std::string GetFrontendResource(const std::string& path) override; - void SessionDestroyed(content::DevToolsAgentHost* agent_host, - int session_id) override; + void ClientDetached(content::DevToolsAgentHost* agent_host, + content::DevToolsAgentHostClient* client) override; private: std::unique_ptr<base::DictionaryValue> CreateTarget( content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, int command_id, const base::DictionaryValue* params); std::unique_ptr<base::DictionaryValue> CloseTarget( content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, int command_id, const base::DictionaryValue* params); std::unique_ptr<base::DictionaryValue> CreateBrowserContext( content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, int command_id, const base::DictionaryValue* params); std::unique_ptr<base::DictionaryValue> DisposeBrowserContext( content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, int command_id, const base::DictionaryValue* params); std::unique_ptr<base::DictionaryValue> GetWindowForTarget( content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, int command_id, const base::DictionaryValue* params); std::unique_ptr<base::DictionaryValue> GetWindowBounds( content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, int command_id, const base::DictionaryValue* params); std::unique_ptr<base::DictionaryValue> Close( content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, int command_id, const base::DictionaryValue* params); std::unique_ptr<base::DictionaryValue> SetWindowBounds( content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, int command_id, const base::DictionaryValue* params); std::unique_ptr<base::DictionaryValue> EnableHeadlessExperimental( content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, int command_id, const base::DictionaryValue* params); std::unique_ptr<base::DictionaryValue> DisableHeadlessExperimental( content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, int command_id, const base::DictionaryValue* params); std::unique_ptr<base::DictionaryValue> EmulateNetworkConditions( content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, int command_id, const base::DictionaryValue* params); std::unique_ptr<base::DictionaryValue> NetworkDisable( content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, int command_id, const base::DictionaryValue* params); @@ -123,12 +123,12 @@ class HeadlessDevToolsManagerDelegate HeadlessNetworkConditions conditions); void PrintToPDF(content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, int command_id, const base::DictionaryValue* params, const CommandCallback& callback); void BeginFrame(content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, int command_id, const base::DictionaryValue* params, const CommandCallback& callback); @@ -138,12 +138,12 @@ class HeadlessDevToolsManagerDelegate using CommandMemberCallback = base::Callback<std::unique_ptr<base::DictionaryValue>( content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, int command_id, const base::DictionaryValue* params)>; using AsyncCommandMemberCallback = base::Callback<void(content::DevToolsAgentHost* agent_host, - int session_id, + content::DevToolsAgentHostClient* client, int command_id, const base::DictionaryValue* params, const CommandCallback& callback)>; diff --git a/chromium/headless/lib/browser/headless_net_log.cc b/chromium/headless/lib/browser/headless_net_log.cc index 08a26f68a6d..57f558089f1 100644 --- a/chromium/headless/lib/browser/headless_net_log.cc +++ b/chromium/headless/lib/browser/headless_net_log.cc @@ -4,12 +4,12 @@ #include "headless/lib/browser/headless_net_log.h" +#include <memory> #include <utility> #include "base/bind.h" #include "base/command_line.h" #include "base/files/file_path.h" -#include "base/memory/ptr_util.h" #include "base/values.h" #include "build/build_config.h" #include "content/public/common/content_switches.h" @@ -24,7 +24,7 @@ std::unique_ptr<base::DictionaryValue> GetHeadlessConstants() { net::GetNetConstants(); // Add a dictionary with client information - auto dict = base::MakeUnique<base::DictionaryValue>(); + auto dict = std::make_unique<base::DictionaryValue>(); dict->SetString("name", "headless"); dict->SetString( diff --git a/chromium/headless/lib/browser/headless_print_manager.cc b/chromium/headless/lib/browser/headless_print_manager.cc index e7a816dcb45..d9f5a6fa8a9 100644 --- a/chromium/headless/lib/browser/headless_print_manager.cc +++ b/chromium/headless/lib/browser/headless_print_manager.cc @@ -4,11 +4,11 @@ #include "headless/lib/browser/headless_print_manager.h" +#include <memory> #include <utility> #include <vector> #include "base/base64.h" -#include "base/memory/ptr_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_piece.h" #include "base/strings/string_split.h" @@ -66,8 +66,6 @@ std::string HeadlessPrintManager::PrintResultToString(PrintResult result) { return "Invalid memory handle"; case METAFILE_MAP_ERROR: return "Map to shared memory error"; - case UNEXPECTED_VALID_MEMORY_HANDLE: - return "Unexpected valide memory handle"; case METAFILE_INVALID_HEADER: return "Invalid metafile header"; case METAFILE_GET_DATA_ERROR: @@ -89,7 +87,7 @@ std::unique_ptr<base::DictionaryValue> HeadlessPrintManager::PDFContentsToDictionaryValue(const std::string& data) { std::string base_64_data; base::Base64Encode(data, &base_64_data); - auto result = base::MakeUnique<base::DictionaryValue>(); + auto result = std::make_unique<base::DictionaryValue>(); result->SetString("data", base_64_data); return result; } @@ -198,10 +196,14 @@ HeadlessPrintManager::GetPrintParamsFromSettings( print_settings.SetPrinterPrintableArea(settings.paper_size_in_points, printable_area_device_units, true); - auto print_params = base::MakeUnique<PrintMsg_PrintPages_Params>(); + auto print_params = std::make_unique<PrintMsg_PrintPages_Params>(); printing::RenderParamsFromPrintSettings(print_settings, &print_params->params); print_params->params.document_cookie = printing::PrintSettings::NewCookie(); + print_params->params.header_template = + base::UTF8ToUTF16(settings.header_template); + print_params->params.footer_template = + base::UTF8ToUTF16(settings.footer_template); return print_params; } @@ -238,7 +240,7 @@ bool HeadlessPrintManager::OnMessageReceived( IPC_BEGIN_MESSAGE_MAP(HeadlessPrintManager, message) IPC_MESSAGE_HANDLER(PrintHostMsg_ShowInvalidPrinterSettingsError, OnShowInvalidPrinterSettingsError) - IPC_MESSAGE_HANDLER(PrintHostMsg_DidPrintPage, OnDidPrintPage) + IPC_MESSAGE_HANDLER(PrintHostMsg_DidPrintDocument, OnDidPrintDocument) IPC_MESSAGE_FORWARD_DELAY_REPLY( PrintHostMsg_GetDefaultPrintSettings, &helper, FrameDispatchHelper::OnGetDefaultPrintSettings) @@ -288,41 +290,21 @@ void HeadlessPrintManager::OnPrintingFailed(int cookie) { ReleaseJob(PRINTING_FAILED); } -void HeadlessPrintManager::OnDidGetPrintedPagesCount(int cookie, - int number_pages) { - PrintManager::OnDidGetPrintedPagesCount(cookie, number_pages); - if (!print_params_->pages.empty()) - number_pages_ = print_params_->pages.size(); -} - -void HeadlessPrintManager::OnDidPrintPage( - const PrintHostMsg_DidPrintPage_Params& params) { - const bool metafile_must_be_valid = expecting_first_page_; - expecting_first_page_ = false; - - if (metafile_must_be_valid) { - if (!base::SharedMemory::IsHandleValid(params.metafile_data_handle)) { - ReleaseJob(INVALID_MEMORY_HANDLE); - return; - } - auto shared_buf = - base::MakeUnique<base::SharedMemory>(params.metafile_data_handle, true); - if (!shared_buf->Map(params.data_size)) { - ReleaseJob(METAFILE_MAP_ERROR); - return; - } - data_ = std::string(static_cast<const char*>(shared_buf->memory()), - params.data_size); - } else { - if (base::SharedMemory::IsHandleValid(params.metafile_data_handle)) { - base::SharedMemory::CloseHandle(params.metafile_data_handle); - ReleaseJob(UNEXPECTED_VALID_MEMORY_HANDLE); - return; - } +void HeadlessPrintManager::OnDidPrintDocument( + const PrintHostMsg_DidPrintDocument_Params& params) { + if (!base::SharedMemory::IsHandleValid(params.metafile_data_handle)) { + ReleaseJob(INVALID_MEMORY_HANDLE); + return; } - - if (--number_pages_ == 0) - ReleaseJob(PRINT_SUCCESS); + auto shared_buf = + std::make_unique<base::SharedMemory>(params.metafile_data_handle, true); + if (!shared_buf->Map(params.data_size)) { + ReleaseJob(METAFILE_MAP_ERROR); + return; + } + data_ = std::string(static_cast<const char*>(shared_buf->memory()), + params.data_size); + ReleaseJob(PRINT_SUCCESS); } void HeadlessPrintManager::Reset() { @@ -332,8 +314,6 @@ void HeadlessPrintManager::Reset() { page_ranges_text_.clear(); ignore_invalid_page_ranges_ = false; data_.clear(); - expecting_first_page_ = true; - number_pages_ = 0; } void HeadlessPrintManager::ReleaseJob(PrintResult result) { diff --git a/chromium/headless/lib/browser/headless_print_manager.h b/chromium/headless/lib/browser/headless_print_manager.h index 1671d59d835..f83555b65a8 100644 --- a/chromium/headless/lib/browser/headless_print_manager.h +++ b/chromium/headless/lib/browser/headless_print_manager.h @@ -15,7 +15,7 @@ #include "headless/public/headless_export.h" #include "printing/print_settings.h" -struct PrintHostMsg_DidPrintPage_Params; +struct PrintHostMsg_DidPrintDocument_Params; struct PrintHostMsg_ScriptedPrint_Params; struct PrintMsg_PrintPages_Params; @@ -36,6 +36,8 @@ struct HEADLESS_EXPORT HeadlessPrintSettings { std::string page_ranges; bool ignore_invalid_page_ranges; + std::string header_template; + std::string footer_template; }; class HeadlessPrintManager @@ -48,7 +50,6 @@ class HeadlessPrintManager INVALID_PRINTER_SETTINGS, INVALID_MEMORY_HANDLE, METAFILE_MAP_ERROR, - UNEXPECTED_VALID_MEMORY_HANDLE, METAFILE_INVALID_HEADER, METAFILE_GET_DATA_ERROR, SIMULTANEOUS_PRINT_ACTIVE, @@ -101,8 +102,7 @@ class HeadlessPrintManager IPC::Message* reply_msg); void OnShowInvalidPrinterSettingsError(); void OnPrintingFailed(int cookie) override; - void OnDidGetPrintedPagesCount(int cookie, int number_pages) override; - void OnDidPrintPage(const PrintHostMsg_DidPrintPage_Params& params); + void OnDidPrintDocument(const PrintHostMsg_DidPrintDocument_Params& params); void Reset(); void ReleaseJob(PrintResult result); @@ -114,9 +114,6 @@ class HeadlessPrintManager bool ignore_invalid_page_ranges_ = false; std::string data_; - // Set to true when OnDidPrintPage() should be expecting the first page. - bool expecting_first_page_ = true; - DISALLOW_COPY_AND_ASSIGN(HeadlessPrintManager); }; diff --git a/chromium/headless/lib/browser/headless_printing_unittest.cc b/chromium/headless/lib/browser/headless_printing_unittest.cc index 5cdf858348d..ad7caa7dc59 100644 --- a/chromium/headless/lib/browser/headless_printing_unittest.cc +++ b/chromium/headless/lib/browser/headless_printing_unittest.cc @@ -2,7 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/memory/ptr_util.h" +#include <memory> + #include "base/values.h" #include "headless/lib/browser/headless_devtools_manager_delegate.h" #include "headless/lib/browser/headless_print_manager.h" @@ -16,7 +17,7 @@ TEST(ParsePrintSettingsTest, Landscape) { HeadlessPrintSettings settings; EXPECT_FALSE(settings.landscape); - auto params = base::MakeUnique<base::DictionaryValue>(); + auto params = std::make_unique<base::DictionaryValue>(); params->SetBoolean("landscape", true); std::unique_ptr<base::DictionaryValue> response = ParsePrintSettings(0, params.get(), &settings); @@ -28,7 +29,7 @@ TEST(ParsePrintSettingsTest, HeaderFooter) { HeadlessPrintSettings settings; EXPECT_FALSE(settings.display_header_footer); - auto params = base::MakeUnique<base::DictionaryValue>(); + auto params = std::make_unique<base::DictionaryValue>(); params->SetBoolean("displayHeaderFooter", true); std::unique_ptr<base::DictionaryValue> response = ParsePrintSettings(0, params.get(), &settings); @@ -40,7 +41,7 @@ TEST(ParsePrintSettingsTest, PrintBackground) { HeadlessPrintSettings settings; EXPECT_FALSE(settings.should_print_backgrounds); - auto params = base::MakeUnique<base::DictionaryValue>(); + auto params = std::make_unique<base::DictionaryValue>(); params->SetBoolean("printBackground", true); std::unique_ptr<base::DictionaryValue> response = ParsePrintSettings(0, params.get(), &settings); @@ -52,7 +53,7 @@ TEST(ParsePrintSettingsTest, Scale) { HeadlessPrintSettings settings; EXPECT_DOUBLE_EQ(1, settings.scale); - auto params = base::MakeUnique<base::DictionaryValue>(); + auto params = std::make_unique<base::DictionaryValue>(); params->SetDouble("scale", 0.5); std::unique_ptr<base::DictionaryValue> response = ParsePrintSettings(0, params.get(), &settings); @@ -72,7 +73,7 @@ TEST(ParsePrintSettingsTest, PageRanges) { HeadlessPrintSettings settings; EXPECT_EQ("", settings.page_ranges); - auto params = base::MakeUnique<base::DictionaryValue>(); + auto params = std::make_unique<base::DictionaryValue>(); params->SetString("pageRanges", "abcd"); params->SetBoolean("ignoreInvalidPageRanges", true); std::unique_ptr<base::DictionaryValue> response = @@ -88,7 +89,7 @@ TEST(ParsePrintSettingsTest, PageRanges) { TEST(ParsePrintSettingsTest, Paper) { HeadlessPrintSettings settings; - auto params = base::MakeUnique<base::DictionaryValue>(); + auto params = std::make_unique<base::DictionaryValue>(); std::unique_ptr<base::DictionaryValue> response = ParsePrintSettings(0, params.get(), &settings); EXPECT_EQ(printing::kLetterWidthInch * printing::kPointsPerInch, @@ -120,7 +121,7 @@ TEST(ParsePrintSettingsTest, Paper) { TEST(ParsePrintSettingsTest, Margin) { HeadlessPrintSettings settings; - auto params = base::MakeUnique<base::DictionaryValue>(); + auto params = std::make_unique<base::DictionaryValue>(); std::unique_ptr<base::DictionaryValue> response = ParsePrintSettings(0, params.get(), &settings); int default_margin = diff --git a/chromium/headless/lib/browser/headless_quota_permission_context.cc b/chromium/headless/lib/browser/headless_quota_permission_context.cc index b75f01bcf42..89b0266dabb 100644 --- a/chromium/headless/lib/browser/headless_quota_permission_context.cc +++ b/chromium/headless/lib/browser/headless_quota_permission_context.cc @@ -4,7 +4,7 @@ #include "headless/lib/browser/headless_quota_permission_context.h" -#include "storage/common/quota/quota_types.h" +#include "third_party/WebKit/common/quota/quota_types.mojom.h" namespace headless { @@ -14,7 +14,7 @@ void HeadlessQuotaPermissionContext::RequestQuotaPermission( const content::StorageQuotaParams& params, int render_process_id, const PermissionCallback& callback) { - if (params.storage_type != storage::kStorageTypePersistent) { + if (params.storage_type != blink::mojom::StorageType::kPersistent) { // For now we only support requesting quota with this interface // for Persistent storage type. callback.Run(QUOTA_PERMISSION_RESPONSE_DISALLOW); diff --git a/chromium/headless/lib/browser/headless_url_request_context_getter.cc b/chromium/headless/lib/browser/headless_url_request_context_getter.cc index 9df02187acc..92ea5b01d3b 100644 --- a/chromium/headless/lib/browser/headless_url_request_context_getter.cc +++ b/chromium/headless/lib/browser/headless_url_request_context_getter.cc @@ -8,7 +8,6 @@ #include <utility> #include <vector> -#include "base/memory/ptr_util.h" #include "base/task_scheduler/post_task.h" #include "build/build_config.h" #include "components/cookie_config/cookie_store_util.h" @@ -21,6 +20,9 @@ #include "headless/lib/browser/headless_network_delegate.h" #include "net/cookies/cookie_store.h" #include "net/dns/mapped_host_resolver.h" +#include "net/http/http_auth_handler_factory.h" +#include "net/http/http_auth_preferences.h" +#include "net/http/http_auth_scheme.h" #include "net/http/http_transaction_factory.h" #include "net/http/http_util.h" #include "net/proxy/proxy_service.h" @@ -85,6 +87,10 @@ HeadlessURLRequestContextGetter::~HeadlessURLRequestContextGetter() { net::URLRequestContext* HeadlessURLRequestContextGetter::GetURLRequestContext() { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + + if (shut_down_) + return nullptr; + if (!url_request_context_) { net::URLRequestContextBuilder builder; @@ -117,13 +123,13 @@ HeadlessURLRequestContextGetter::GetURLRequestContext() { content::CookieStoreConfig cookie_config( headless_browser_context_->GetPath().Append( FILE_PATH_LITERAL("Cookies")), - content::CookieStoreConfig::PERSISTANT_SESSION_COOKIES, NULL); + false, true, NULL); cookie_config.crypto_delegate = cookie_config::GetCookieCryptoDelegate(); std::unique_ptr<net::CookieStore> cookie_store = CreateCookieStore(cookie_config); std::unique_ptr<net::ChannelIDService> channel_id_service = - base::MakeUnique<net::ChannelIDService>( + std::make_unique<net::ChannelIDService>( new net::DefaultChannelIDStore(nullptr)); cookie_store->SetChannelIDServiceID(channel_id_service->GetUniqueID()); @@ -147,18 +153,30 @@ HeadlessURLRequestContextGetter::GetURLRequestContext() { { base::AutoLock lock(lock_); builder.set_network_delegate( - base::MakeUnique<HeadlessNetworkDelegate>(headless_browser_context_)); + std::make_unique<HeadlessNetworkDelegate>(headless_browser_context_)); } + std::unique_ptr<net::HostResolver> host_resolver( + net::HostResolver::CreateDefaultResolver(net_log_)); + if (!host_resolver_rules_.empty()) { - std::unique_ptr<net::HostResolver> host_resolver( - net::HostResolver::CreateDefaultResolver(net_log_)); std::unique_ptr<net::MappedHostResolver> mapped_host_resolver( new net::MappedHostResolver(std::move(host_resolver))); mapped_host_resolver->SetRulesFromString(host_resolver_rules_); - builder.set_host_resolver(std::move(mapped_host_resolver)); + host_resolver = std::move(mapped_host_resolver); } + net::HttpAuthPreferences* prefs(new net::HttpAuthPreferences()); + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + prefs->SetServerWhitelist( + command_line->GetSwitchValueASCII(switches::kAuthServerWhitelist)); + std::unique_ptr<net::HttpAuthHandlerRegistryFactory> factory = + net::HttpAuthHandlerRegistryFactory::CreateDefault(host_resolver.get()); + factory->SetHttpAuthPreferences(net::kNegotiateAuthScheme, + std::move(prefs)); + builder.SetHttpAuthHandlerFactory(std::move(factory)); + builder.set_host_resolver(std::move(host_resolver)); + // Extra headers are required for network emulation and are removed in // DevToolsNetworkTransaction. If a protocol handler is set for http or // https, then it is likely that the HttpTransactionFactoryCallback will @@ -201,4 +219,11 @@ void HeadlessURLRequestContextGetter::OnHeadlessBrowserContextDestruct() { headless_browser_context_ = nullptr; } +void HeadlessURLRequestContextGetter::NotifyContextShuttingDown() { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + shut_down_ = true; + net::URLRequestContextGetter::NotifyContextShuttingDown(); + url_request_context_ = nullptr; // deletes it +} + } // namespace headless diff --git a/chromium/headless/lib/browser/headless_url_request_context_getter.h b/chromium/headless/lib/browser/headless_url_request_context_getter.h index 1fb71c9f48a..50d799bd542 100644 --- a/chromium/headless/lib/browser/headless_url_request_context_getter.h +++ b/chromium/headless/lib/browser/headless_url_request_context_getter.h @@ -52,6 +52,8 @@ class HeadlessURLRequestContextGetter // HeadlessBrowserContext::Observer implementation: void OnHeadlessBrowserContextDestruct() override; + void NotifyContextShuttingDown(); + protected: ~HeadlessURLRequestContextGetter() override; @@ -75,6 +77,8 @@ class HeadlessURLRequestContextGetter base::Lock lock_; // Protects |headless_browser_context_|. HeadlessBrowserContextImpl* headless_browser_context_; // Not owned. + bool shut_down_ = false; + DISALLOW_COPY_AND_ASSIGN(HeadlessURLRequestContextGetter); }; diff --git a/chromium/headless/lib/browser/headless_web_contents_impl.cc b/chromium/headless/lib/browser/headless_web_contents_impl.cc index cc0c7509625..37229bb50fe 100644 --- a/chromium/headless/lib/browser/headless_web_contents_impl.cc +++ b/chromium/headless/lib/browser/headless_web_contents_impl.cc @@ -4,13 +4,13 @@ #include "headless/lib/browser/headless_web_contents_impl.h" +#include <memory> #include <string> #include <utility> #include <vector> #include "base/bind.h" #include "base/json/json_writer.h" -#include "base/memory/ptr_util.h" #include "base/memory/weak_ptr.h" #include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" @@ -243,7 +243,7 @@ std::unique_ptr<HeadlessWebContentsImpl> HeadlessWebContentsImpl::Create( if (builder->tab_sockets_allowed_) { headless_web_contents->headless_tab_socket_ = - base::MakeUnique<HeadlessTabSocketImpl>( + std::make_unique<HeadlessTabSocketImpl>( headless_web_contents->web_contents_.get()); headless_web_contents->inject_mojo_services_into_isolated_world_ = true; @@ -277,7 +277,7 @@ HeadlessWebContentsImpl::CreateForChildContents( child->mojo_services_ = parent->mojo_services_; if (parent->headless_tab_socket_) { child->headless_tab_socket_ = - base::MakeUnique<HeadlessTabSocketImpl>(child_contents); + std::make_unique<HeadlessTabSocketImpl>(child_contents); child->inject_mojo_services_into_isolated_world_ = parent->inject_mojo_services_into_isolated_world_; } @@ -536,37 +536,40 @@ void HeadlessWebContentsImpl::OnNeedsExternalBeginFrames( "needs_begin_frames", needs_begin_frames); needs_external_begin_frames_ = needs_begin_frames; - for (int session_id : begin_frame_events_enabled_sessions_) - SendNeedsBeginFramesEvent(session_id); + for (content::DevToolsAgentHostClient* client : + begin_frame_events_enabled_clients_) { + SendNeedsBeginFramesEvent(client); + } } -void HeadlessWebContentsImpl::SetBeginFrameEventsEnabled(int session_id, - bool enabled) { +void HeadlessWebContentsImpl::SetBeginFrameEventsEnabled( + content::DevToolsAgentHostClient* client, + bool enabled) { TRACE_EVENT2("headless", - "HeadlessWebContentsImpl::SetBeginFrameEventsEnabled", - "session_id", session_id, "enabled", enabled); + "HeadlessWebContentsImpl::SetBeginFrameEventsEnabled", "client", + client, "enabled", enabled); if (enabled) { - if (!base::ContainsValue(begin_frame_events_enabled_sessions_, - session_id)) { - begin_frame_events_enabled_sessions_.push_back(session_id); + if (!base::ContainsValue(begin_frame_events_enabled_clients_, client)) { + begin_frame_events_enabled_clients_.push_back(client); // We only need to send an event if BeginFrames are needed, as clients // assume that they are not needed by default. if (needs_external_begin_frames_) - SendNeedsBeginFramesEvent(session_id); + SendNeedsBeginFramesEvent(client); } } else { - begin_frame_events_enabled_sessions_.remove(session_id); + begin_frame_events_enabled_clients_.remove(client); } } -void HeadlessWebContentsImpl::SendNeedsBeginFramesEvent(int session_id) { +void HeadlessWebContentsImpl::SendNeedsBeginFramesEvent( + content::DevToolsAgentHostClient* client) { TRACE_EVENT2("headless", "HeadlessWebContentsImpl::SendNeedsBeginFramesEvent", - "session_id", session_id, "needs_begin_frames", + "client", client, "needs_begin_frames", needs_external_begin_frames_); DCHECK(agent_host_); - auto params = base::MakeUnique<base::DictionaryValue>(); + auto params = std::make_unique<base::DictionaryValue>(); params->SetBoolean("needsBeginFrames", needs_external_begin_frames_); base::DictionaryValue event; @@ -575,7 +578,7 @@ void HeadlessWebContentsImpl::SendNeedsBeginFramesEvent(int session_id) { std::string json_result; CHECK(base::JSONWriter::Write(event, &json_result)); - agent_host_->SendProtocolMessageToClient(session_id, json_result); + client->DispatchProtocolMessage(agent_host_.get(), json_result); } void HeadlessWebContentsImpl::DidReceiveCompositorFrame() { @@ -590,12 +593,14 @@ void HeadlessWebContentsImpl::DidReceiveCompositorFrame() { base::DictionaryValue event; event.SetString("method", "HeadlessExperimental.mainFrameReadyForScreenshots"); - event.Set("params", base::MakeUnique<base::DictionaryValue>()); + event.Set("params", std::make_unique<base::DictionaryValue>()); std::string json_result; CHECK(base::JSONWriter::Write(event, &json_result)); - for (int session_id : begin_frame_events_enabled_sessions_) - agent_host_->SendProtocolMessageToClient(session_id, json_result); + for (content::DevToolsAgentHostClient* client : + begin_frame_events_enabled_clients_) { + client->DispatchProtocolMessage(agent_host_.get(), json_result); + } } // Set main_frame_content_updated on pending frames that the display hasn't @@ -615,7 +620,7 @@ void HeadlessWebContentsImpl::PendingFrameReadbackComplete( "headless", "HeadlessWebContentsImpl::PendingFrameReadbackComplete", "sequence_number", pending_frame->sequence_number, "response", response); if (response == content::READBACK_SUCCESS) { - pending_frame->bitmap = base::MakeUnique<SkBitmap>(bitmap); + pending_frame->bitmap = std::make_unique<SkBitmap>(bitmap); } else { LOG(WARNING) << "Readback from surface failed with response " << response; } @@ -635,6 +640,7 @@ void HeadlessWebContentsImpl::BeginFrame( const base::TimeTicks& frame_timeticks, const base::TimeTicks& deadline, const base::TimeDelta& interval, + bool animate_only, bool capture_screenshot, const FrameFinishedCallback& frame_finished_callback) { DCHECK(begin_frame_control_enabled_); @@ -643,7 +649,7 @@ void HeadlessWebContentsImpl::BeginFrame( uint64_t sequence_number = begin_frame_sequence_number_++; - auto pending_frame = base::MakeUnique<PendingFrame>(); + auto pending_frame = std::make_unique<PendingFrame>(); pending_frame->sequence_number = sequence_number; pending_frame->callback = frame_finished_callback; @@ -666,9 +672,12 @@ void HeadlessWebContentsImpl::BeginFrame( ui::Compositor* compositor = browser()->PlatformGetCompositor(this); DCHECK(compositor); - compositor->IssueExternalBeginFrame(viz::BeginFrameArgs::Create( + auto args = viz::BeginFrameArgs::Create( BEGINFRAME_FROM_HERE, begin_frame_source_id_, sequence_number, - frame_timeticks, deadline, interval, viz::BeginFrameArgs::NORMAL)); + frame_timeticks, deadline, interval, viz::BeginFrameArgs::NORMAL); + args.animate_only = animate_only; + + compositor->IssueExternalBeginFrame(args); } HeadlessWebContents::Builder::Builder( diff --git a/chromium/headless/lib/browser/headless_web_contents_impl.h b/chromium/headless/lib/browser/headless_web_contents_impl.h index a4e06e025ae..dbd8ac949d0 100644 --- a/chromium/headless/lib/browser/headless_web_contents_impl.h +++ b/chromium/headless/lib/browser/headless_web_contents_impl.h @@ -27,6 +27,7 @@ class SkBitmap; namespace content { class DevToolsAgentHost; +class DevToolsAgentHostClient; class WebContents; } @@ -140,7 +141,8 @@ class HEADLESS_EXPORT HeadlessWebContentsImpl return needs_external_begin_frames_; } - void SetBeginFrameEventsEnabled(int session_id, bool enabled); + void SetBeginFrameEventsEnabled(content::DevToolsAgentHostClient* client, + bool enabled); using FrameFinishedCallback = base::Callback<void(bool /* has_damage */, @@ -149,6 +151,7 @@ class HEADLESS_EXPORT HeadlessWebContentsImpl void BeginFrame(const base::TimeTicks& frame_timeticks, const base::TimeTicks& deadline, const base::TimeDelta& interval, + bool animate_only, bool capture_screenshot, const FrameFinishedCallback& frame_finished_callback); bool HasPendingFrame() const { return !pending_frames_.empty(); } @@ -167,7 +170,7 @@ class HEADLESS_EXPORT HeadlessWebContentsImpl const MojoService::ServiceFactoryCallback& service_factory, mojo::ScopedMessagePipeHandle handle); - void SendNeedsBeginFramesEvent(int session_id); + void SendNeedsBeginFramesEvent(content::DevToolsAgentHostClient* client); void PendingFrameReadbackComplete(PendingFrame* pending_frame, const SkBitmap& bitmap, content::ReadbackResponse response); @@ -176,7 +179,8 @@ class HEADLESS_EXPORT HeadlessWebContentsImpl uint64_t begin_frame_sequence_number_ = viz::BeginFrameArgs::kStartingFrameNumber; bool begin_frame_control_enabled_ = false; - std::list<int> begin_frame_events_enabled_sessions_; + std::list<content::DevToolsAgentHostClient*> + begin_frame_events_enabled_clients_; bool needs_external_begin_frames_ = false; std::list<std::unique_ptr<PendingFrame>> pending_frames_; bool first_compositor_frame_received_ = false; diff --git a/chromium/headless/lib/frame_id_browsertest.cc b/chromium/headless/lib/frame_id_browsertest.cc index 11253124ac4..4a491f01d3d 100644 --- a/chromium/headless/lib/frame_id_browsertest.cc +++ b/chromium/headless/lib/frame_id_browsertest.cc @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <memory> + #include "base/bind.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" @@ -83,7 +85,7 @@ class FrameIdTest : public HeadlessAsyncDevTooledBrowserTest, devtools_client_->GetRuntime()->Enable(); // Enabling the runtime domain will send us the current context. - run_loop_ = base::MakeUnique<base::RunLoop>( + run_loop_ = std::make_unique<base::RunLoop>( base::RunLoop::Type::kNestableTasksAllowed); run_loop_->Run(); run_loop_ = nullptr; @@ -106,7 +108,7 @@ class FrameIdTest : public HeadlessAsyncDevTooledBrowserTest, devtools_client_->GetPage()->AddObserver(this); - run_loop_ = base::MakeUnique<base::RunLoop>( + run_loop_ = std::make_unique<base::RunLoop>( base::RunLoop::Type::kNestableTasksAllowed); devtools_client_->GetPage()->Enable(run_loop_->QuitClosure()); run_loop_->Run(); diff --git a/chromium/headless/lib/headless_browser_browsertest.cc b/chromium/headless/lib/headless_browser_browsertest.cc index 0ed54b6303a..565b06e386e 100644 --- a/chromium/headless/lib/headless_browser_browsertest.cc +++ b/chromium/headless/lib/headless_browser_browsertest.cc @@ -7,7 +7,6 @@ #include "base/command_line.h" #include "base/files/file_enumerator.h" #include "base/files/file_util.h" -#include "base/memory/ptr_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/threading/thread_restrictions.h" @@ -262,7 +261,7 @@ IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, HttpProtocolHandler) { const std::string kResponseBody = "<p>HTTP response body</p>"; ProtocolHandlerMap protocol_handlers; protocol_handlers[url::kHttpScheme] = - base::MakeUnique<TestProtocolHandler>(kResponseBody); + std::make_unique<TestProtocolHandler>(kResponseBody); HeadlessBrowserContext* browser_context = browser() @@ -290,7 +289,7 @@ IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, HttpsProtocolHandler) { const std::string kResponseBody = "<p>HTTPS response body</p>"; ProtocolHandlerMap protocol_handlers; protocol_handlers[url::kHttpsScheme] = - base::MakeUnique<TestProtocolHandler>(kResponseBody); + std::make_unique<TestProtocolHandler>(kResponseBody); HeadlessBrowserContext* browser_context = browser() @@ -483,7 +482,7 @@ IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, ReadCookiesInProtocolHandler) { net::CookieList sent_cookies; ProtocolHandlerMap protocol_handlers; protocol_handlers[url::kHttpsScheme] = - base::MakeUnique<ProtocolHandlerWithCookies>(&sent_cookies); + std::make_unique<ProtocolHandlerWithCookies>(&sent_cookies); HeadlessBrowserContext* browser_context = browser() @@ -830,7 +829,7 @@ class TraceHelper : public tracing::ExperimentalObserver { : browser_test_(browser_test), target_(target), client_(HeadlessDevToolsClient::Create()), - tracing_data_(base::MakeUnique<base::ListValue>()) { + tracing_data_(std::make_unique<base::ListValue>()) { EXPECT_FALSE(target_->IsAttached()); target_->AttachClient(client_.get()); EXPECT_TRUE(target_->IsAttached()); diff --git a/chromium/headless/lib/headless_browser_context_browsertest.cc b/chromium/headless/lib/headless_browser_context_browsertest.cc index a40b10a78f6..34e235d8a6f 100644 --- a/chromium/headless/lib/headless_browser_context_browsertest.cc +++ b/chromium/headless/lib/headless_browser_context_browsertest.cc @@ -5,7 +5,6 @@ #include <memory> #include "base/files/scoped_temp_dir.h" -#include "base/memory/ptr_util.h" #include "base/strings/stringprintf.h" #include "base/threading/thread_restrictions.h" #include "content/public/browser/render_view_host.h" @@ -157,7 +156,7 @@ IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, ContextProtocolHandler) { const std::string kResponseBody = "<p>HTTP response body</p>"; ProtocolHandlerMap protocol_handlers; protocol_handlers[url::kHttpScheme] = - base::MakeUnique<TestProtocolHandler>(kResponseBody); + std::make_unique<TestProtocolHandler>(kResponseBody); // Load a page which doesn't actually exist, but which is fetched by our // custom protocol handler. diff --git a/chromium/headless/lib/headless_content_main_delegate.cc b/chromium/headless/lib/headless_content_main_delegate.cc index 30e19faeec4..3e034ad8d34 100644 --- a/chromium/headless/lib/headless_content_main_delegate.cc +++ b/chromium/headless/lib/headless_content_main_delegate.cc @@ -4,6 +4,7 @@ #include "headless/lib/headless_content_main_delegate.h" +#include <memory> #include <utility> #include "base/base_switches.h" @@ -104,6 +105,12 @@ bool HeadlessContentMainDelegate::BasicStartupComplete(int* exit_code) { } } + // Headless uses a software output device which will cause us to fall back to + // software compositing anyway, but only after attempting and failing to + // initialize GPU compositing. We disable GPU compositing here explicitly to + // preempt this attempt. + command_line->AppendSwitch(switches::kDisableGpuCompositing); + SetContentClient(&content_client_); return false; } @@ -340,7 +347,7 @@ void HeadlessContentMainDelegate::InitializeResourceBundle() { content::ContentBrowserClient* HeadlessContentMainDelegate::CreateContentBrowserClient() { browser_client_ = - base::MakeUnique<HeadlessContentBrowserClient>(browser_.get()); + std::make_unique<HeadlessContentBrowserClient>(browser_.get()); return browser_client_.get(); } #endif // !defined(CHROME_MULTIPLE_DLL_CHILD) @@ -348,13 +355,13 @@ HeadlessContentMainDelegate::CreateContentBrowserClient() { #if !defined(CHROME_MULTIPLE_DLL_BROWSER) content::ContentRendererClient* HeadlessContentMainDelegate::CreateContentRendererClient() { - renderer_client_ = base::MakeUnique<HeadlessContentRendererClient>(); + renderer_client_ = std::make_unique<HeadlessContentRendererClient>(); return renderer_client_.get(); } content::ContentUtilityClient* HeadlessContentMainDelegate::CreateContentUtilityClient() { - utility_client_ = base::MakeUnique<HeadlessContentUtilityClient>( + utility_client_ = std::make_unique<HeadlessContentUtilityClient>( browser_->options()->user_agent); return utility_client_.get(); } diff --git a/chromium/headless/lib/headless_devtools_client_browsertest.cc b/chromium/headless/lib/headless_devtools_client_browsertest.cc index 44d8061bea6..e3993ee9ff8 100644 --- a/chromium/headless/lib/headless_devtools_client_browsertest.cc +++ b/chromium/headless/lib/headless_devtools_client_browsertest.cc @@ -1128,7 +1128,7 @@ class DevToolsHeaderStrippingTest : public HeadlessAsyncDevTooledBrowserTest, const std::string kResponseBody = "<p>HTTP response body</p>"; ProtocolHandlerMap protocol_handlers; protocol_handlers[url::kHttpScheme] = - base::MakeUnique<TestProtocolHandler>(kResponseBody); + std::make_unique<TestProtocolHandler>(kResponseBody); test_handler_ = static_cast<TestProtocolHandler*>( protocol_handlers[url::kHttpScheme].get()); return protocol_handlers; diff --git a/chromium/headless/lib/renderer/headless_content_renderer_client.cc b/chromium/headless/lib/renderer/headless_content_renderer_client.cc index edde26667f8..8fabc7a6e2d 100644 --- a/chromium/headless/lib/renderer/headless_content_renderer_client.cc +++ b/chromium/headless/lib/renderer/headless_content_renderer_client.cc @@ -4,7 +4,8 @@ #include "headless/lib/renderer/headless_content_renderer_client.h" -#include "base/memory/ptr_util.h" +#include <memory> + #include "headless/lib/renderer/headless_render_frame_controller_impl.h" #include "printing/features/features.h" @@ -23,7 +24,7 @@ void HeadlessContentRendererClient::RenderFrameCreated( content::RenderFrame* render_frame) { #if BUILDFLAG(ENABLE_BASIC_PRINTING) new printing::PrintRenderFrameHelper( - render_frame, base::MakeUnique<HeadlessPrintRenderFrameHelperDelegate>()); + render_frame, std::make_unique<HeadlessPrintRenderFrameHelperDelegate>()); #endif new HeadlessRenderFrameControllerImpl(render_frame); } diff --git a/chromium/headless/lib/virtual_time_browsertest.cc b/chromium/headless/lib/virtual_time_browsertest.cc index 7a0a6a6059f..61f15d23985 100644 --- a/chromium/headless/lib/virtual_time_browsertest.cc +++ b/chromium/headless/lib/virtual_time_browsertest.cc @@ -7,7 +7,6 @@ #include "base/strings/stringprintf.h" #include "content/public/test/browser_test.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_devtools_client.h" #include "headless/public/util/testing/test_in_memory_protocol_handler.h" @@ -23,7 +22,6 @@ namespace headless { class VirtualTimeBrowserTest : public HeadlessAsyncDevTooledBrowserTest, public emulation::ExperimentalObserver, - public page::ExperimentalObserver, public runtime::Observer { public: void SetInitialURL(const std::string& initial_url) { @@ -32,19 +30,11 @@ class VirtualTimeBrowserTest : public HeadlessAsyncDevTooledBrowserTest, void RunDevTooledTest() override { devtools_client_->GetEmulation()->GetExperimental()->AddObserver(this); - devtools_client_->GetPage()->GetExperimental()->AddObserver(this); devtools_client_->GetRuntime()->AddObserver(this); - - devtools_client_->GetPage()->Enable(base::Bind( - &VirtualTimeBrowserTest::PageEnabled, base::Unretained(this))); - devtools_client_->GetRuntime()->Enable(base::Bind( + devtools_client_->GetRuntime()->Enable(base::BindRepeating( &VirtualTimeBrowserTest::RuntimeEnabled, base::Unretained(this))); } - void PageEnabled() { - page_enabled = true; - MaybeSetVirtualTimePolicy(); - } void RuntimeEnabled() { runtime_enabled = true; @@ -52,7 +42,7 @@ class VirtualTimeBrowserTest : public HeadlessAsyncDevTooledBrowserTest, } virtual void MaybeSetVirtualTimePolicy() { - if (!page_enabled || !runtime_enabled) + if (!runtime_enabled) return; // To avoid race conditions start with virtual time paused. @@ -60,8 +50,10 @@ class VirtualTimeBrowserTest : public HeadlessAsyncDevTooledBrowserTest, emulation::SetVirtualTimePolicyParams::Builder() .SetPolicy(emulation::VirtualTimePolicy::PAUSE) .Build(), - base::Bind(&VirtualTimeBrowserTest::SetVirtualTimePolicyDone, - base::Unretained(this))); + base::BindRepeating(&VirtualTimeBrowserTest::SetVirtualTimePolicyDone, + base::Unretained(this))); + + SetAfterLoadVirtualTimePolicy(); } void SetVirtualTimePolicyDone( @@ -71,18 +63,13 @@ class VirtualTimeBrowserTest : public HeadlessAsyncDevTooledBrowserTest, devtools_client_->GetPage()->Navigate(initial_url_); } - void OnFrameStartedLoading( - const page::FrameStartedLoadingParams& params) override { - if (initial_load_seen_) - return; - initial_load_seen_ = true; - // The navigation is underway, so allow virtual time to advance while - // network fetches are not pending. + virtual void SetAfterLoadVirtualTimePolicy() { devtools_client_->GetEmulation()->GetExperimental()->SetVirtualTimePolicy( emulation::SetVirtualTimePolicyParams::Builder() .SetPolicy( emulation::VirtualTimePolicy::PAUSE_IF_NETWORK_FETCHES_PENDING) .SetBudget(5000) + .SetWaitForNavigation(true) .Build()); } @@ -99,7 +86,6 @@ class VirtualTimeBrowserTest : public HeadlessAsyncDevTooledBrowserTest, std::string initial_url_; std::vector<std::string> log_; bool initial_load_seen_ = false; - bool page_enabled = false; bool runtime_enabled = false; }; @@ -114,14 +100,18 @@ class VirtualTimeObserverTest : public VirtualTimeBrowserTest { // emulation::Observer implementation: void OnVirtualTimeBudgetExpired( const emulation::VirtualTimeBudgetExpiredParams& params) override { - std::vector<std::string> expected_log = {"step1", - "Advanced to 100ms", + std::vector<std::string> expected_log = {"Paused @ 0ms", + "Advanced to 10ms", + "step1", + "Advanced to 110ms", "step2", - "Paused @ 100ms", - "Advanced to 200ms", + "Paused @ 110ms", + "Advanced to 120ms", + "Advanced to 210ms", "step3", - "Paused @ 200ms", - "Advanced to 300ms", + "Paused @ 210ms", + "Advanced to 220ms", + "Advanced to 310ms", "step4", "pass"}; // Note after the PASS step there are a number of virtual time advances, but @@ -160,19 +150,14 @@ class MaxVirtualTimeTaskStarvationCountTest : public VirtualTimeBrowserTest { .spec()); } - void OnFrameStartedLoading( - const page::FrameStartedLoadingParams& params) override { - if (initial_load_seen_) - return; - initial_load_seen_ = true; - // The navigation is underway, so allow virtual time to advance while - // network fetches are not pending. + void SetAfterLoadVirtualTimePolicy() override { devtools_client_->GetEmulation()->GetExperimental()->SetVirtualTimePolicy( emulation::SetVirtualTimePolicyParams::Builder() .SetPolicy( emulation::VirtualTimePolicy::PAUSE_IF_NETWORK_FETCHES_PENDING) - .SetBudget(4000) + .SetBudget(4001) .SetMaxVirtualTimeTaskStarvationCount(100) + .SetWaitForNavigation(true) .Build()); } @@ -249,10 +234,10 @@ class FrameDetatchWithPendingResourceLoadVirtualTimeTest if (url.spec() == "http://test.com/style.css") { // Detach the iframe but leave the css resource fetch hanging. browser()->BrowserMainThread()->PostTask( - FROM_HERE, - base::Bind(&FrameDetatchWithPendingResourceLoadVirtualTimeTest:: - DetatchIFrame, - base::Unretained(this))); + FROM_HERE, base::BindRepeating( + &FrameDetatchWithPendingResourceLoadVirtualTimeTest:: + DetatchIFrame, + base::Unretained(this))); } else { complete_request.Run(); } @@ -292,19 +277,13 @@ class VirtualTimeLocalStorageTest : public VirtualTimeBrowserTest { .spec()); } - void OnFrameStartedLoading( - const page::FrameStartedLoadingParams& params) override { - if (initial_load_seen_) - return; - initial_load_seen_ = true; - // The navigation is underway, so allow virtual time to advance while - // network fetches are not pending. + void SetAfterLoadVirtualTimePolicy() override { devtools_client_->GetEmulation()->GetExperimental()->SetVirtualTimePolicy( emulation::SetVirtualTimePolicyParams::Builder() .SetPolicy( emulation::VirtualTimePolicy::PAUSE_IF_NETWORK_FETCHES_PENDING) - .SetBudget(4001) - .SetMaxVirtualTimeTaskStarvationCount(100) + .SetBudget(5000) + .SetWaitForNavigation(true) .Build()); } @@ -317,10 +296,7 @@ class VirtualTimeLocalStorageTest : public VirtualTimeBrowserTest { std::string count_string = (*params.GetArgs())[0]->GetValue()->GetString(); int count; ASSERT_TRUE(base::StringToInt(count_string, &count)) << count_string; - // We don't care what exact number |count| has as long as it's not too small - // or too large. - EXPECT_GT(count, 100); - EXPECT_LT(count, 1000); + EXPECT_EQ(count, 400); console_log_seen_ = true; } @@ -347,19 +323,13 @@ class VirtualTimeSessionStorageTest : public VirtualTimeBrowserTest { .spec()); } - void OnFrameStartedLoading( - const page::FrameStartedLoadingParams& params) override { - if (initial_load_seen_) - return; - initial_load_seen_ = true; - // The navigation is underway, so allow virtual time to advance while - // network fetches are not pending. + void SetAfterLoadVirtualTimePolicy() override { devtools_client_->GetEmulation()->GetExperimental()->SetVirtualTimePolicy( emulation::SetVirtualTimePolicyParams::Builder() .SetPolicy( emulation::VirtualTimePolicy::PAUSE_IF_NETWORK_FETCHES_PENDING) - .SetBudget(4001) - .SetMaxVirtualTimeTaskStarvationCount(100) + .SetBudget(5000) + .SetWaitForNavigation(true) .Build()); } @@ -372,10 +342,7 @@ class VirtualTimeSessionStorageTest : public VirtualTimeBrowserTest { std::string count_string = (*params.GetArgs())[0]->GetValue()->GetString(); int count; ASSERT_TRUE(base::StringToInt(count_string, &count)) << count_string; - // We don't care what exact number |count| has as long as it's not too small - // or too large. - EXPECT_GT(count, 100); - EXPECT_LT(count, 1000); + EXPECT_EQ(count, 400); console_log_seen_ = true; } @@ -410,6 +377,23 @@ class DeferredLoadDoesntBlockVirtualTimeTest : public VirtualTimeBrowserTest { HEADLESS_ASYNC_DEVTOOLED_TEST_F(DeferredLoadDoesntBlockVirtualTimeTest); +class Http404DoesntBlockVirtualTimeTest : public VirtualTimeBrowserTest { + public: + Http404DoesntBlockVirtualTimeTest() { + EXPECT_TRUE(embedded_test_server()->Start()); + SetInitialURL(embedded_test_server()->GetURL("/NoSuchFile.html").spec()); + } + + // emulation::Observer implementation: + void OnVirtualTimeBudgetExpired( + const emulation::VirtualTimeBudgetExpiredParams& params) override { + // The video should not block virtual time. + FinishAsynchronousTest(); + } +}; + +HEADLESS_ASYNC_DEVTOOLED_TEST_F(Http404DoesntBlockVirtualTimeTest); + class RedirectVirtualTimeTest : public VirtualTimeBrowserTest { public: RedirectVirtualTimeTest() { SetInitialURL("http://test.com/index.html"); } @@ -569,8 +553,9 @@ class VirtualTimeAndHistoryNavigationTest : public VirtualTimeBrowserTest { if (step_ < test_commands_.size()) { devtools_client_->GetRuntime()->Evaluate( test_commands_[step_++], - base::Bind(&VirtualTimeAndHistoryNavigationTest::OnEvaluateResult, - base::Unretained(this))); + base::BindRepeating( + &VirtualTimeAndHistoryNavigationTest::OnEvaluateResult, + base::Unretained(this))); } else { FinishAsynchronousTest(); } @@ -599,4 +584,136 @@ class VirtualTimeAndHistoryNavigationTest : public VirtualTimeBrowserTest { HEADLESS_ASYNC_DEVTOOLED_TEST_F(VirtualTimeAndHistoryNavigationTest); +namespace { +static constexpr char kIndexHtmlWithScript[] = R"( +<html> +<body> +<script src="/large.js"></script> +</body> +</html> +)"; + +static constexpr char kLargeDotJS[] = R"( +(function() { +var setTitle = function(newTitle) { + document.title = newTitle; +}; +%s +setTitle('Test PASS'); +})(); +)"; + +} // namespace + +class PendingScriptVirtualTimeTest : public VirtualTimeBrowserTest { + public: + PendingScriptVirtualTimeTest() { + SetInitialURL("http://test.com/index.html"); + } + + ProtocolHandlerMap GetProtocolHandlers() override { + ProtocolHandlerMap protocol_handlers; + std::unique_ptr<TestInMemoryProtocolHandler> http_handler( + new TestInMemoryProtocolHandler(browser()->BrowserIOThread(), nullptr)); + http_handler_ = http_handler.get(); + http_handler_->InsertResponse("http://test.com/index.html", + {kIndexHtmlWithScript, "text/html"}); + // We want to pad |kLargeDotJS| out with some dummy code which is parsed + // asynchronously to make sure the virtual_time_pauser in PendingScript + // actually does something. We construct a large number of long unused + // function declarations which seems to trigger the desired code path. + std::string dummy; + dummy.reserve(1024 * 1024 * 4); + for (int i = 0; i < 1024; i++) { + dummy.append(base::StringPrintf("var i%d=function(){return '", i)); + dummy.append(1024, 'A'); + dummy.append("';}\n"); + } + large_js_ = base::StringPrintf(kLargeDotJS, dummy.c_str()); + http_handler_->InsertResponse( + "http://test.com/large.js", + {large_js_.c_str(), "application/javascript"}); + protocol_handlers[url::kHttpScheme] = std::move(http_handler); + return protocol_handlers; + } + + void RunDevTooledTest() override { + http_handler_->SetHeadlessBrowserContext(browser_context_); + VirtualTimeBrowserTest::RunDevTooledTest(); + } + + void OnVirtualTimeBudgetExpired( + const emulation::VirtualTimeBudgetExpiredParams& params) override { + devtools_client_->GetRuntime()->Evaluate( + "document.title", + base::BindRepeating(&PendingScriptVirtualTimeTest::OnEvaluateResult, + base::Unretained(this))); + } + + void OnEvaluateResult(std::unique_ptr<runtime::EvaluateResult> result) { + EXPECT_EQ("Test PASS", result->GetResult()->GetValue()->GetString()); + FinishAsynchronousTest(); + } + TestInMemoryProtocolHandler* http_handler_; // NOT OWNED + std::string large_js_; +}; + +HEADLESS_ASYNC_DEVTOOLED_TEST_F(PendingScriptVirtualTimeTest); + +namespace { +static constexpr char kResourceErrorLoop[] = R"( +<html> +<script> +var counter = 1; +</script> +<img src="1" onerror="this.src='' + ++counter;"> +</html> +)"; +} + +class VirtualTimeAndResourceErrorLoopTest : public VirtualTimeBrowserTest { + public: + VirtualTimeAndResourceErrorLoopTest() { SetInitialURL("http://foo.com/"); } + + ProtocolHandlerMap GetProtocolHandlers() override { + ProtocolHandlerMap protocol_handlers; + std::unique_ptr<TestInMemoryProtocolHandler> http_handler( + new TestInMemoryProtocolHandler(browser()->BrowserIOThread(), nullptr)); + http_handler_ = http_handler.get(); + http_handler->InsertResponse("http://foo.com/", + {kResourceErrorLoop, "text/html"}); + protocol_handlers[url::kHttpScheme] = std::move(http_handler); + return protocol_handlers; + } + + void RunDevTooledTest() override { + http_handler_->SetHeadlessBrowserContext(browser_context_); + VirtualTimeBrowserTest::RunDevTooledTest(); + } + + void SetAfterLoadVirtualTimePolicy() override { + devtools_client_->GetEmulation()->GetExperimental()->SetVirtualTimePolicy( + emulation::SetVirtualTimePolicyParams::Builder() + .SetPolicy( + emulation::VirtualTimePolicy::PAUSE_IF_NETWORK_FETCHES_PENDING) + .SetBudget(5000) + .SetMaxVirtualTimeTaskStarvationCount(1000000) // Prevent flakes. + .SetWaitForNavigation(true) + .Build()); + } + + // emulation::Observer implementation: + void OnVirtualTimeBudgetExpired( + const emulation::VirtualTimeBudgetExpiredParams& params) override { + // The budget is 5000 virtual ms. The resources are delivered with 10 + // virtual ms delay, so we should have 500 urls. + EXPECT_EQ(500u, http_handler_->urls_requested().size()); + FinishAsynchronousTest(); + } + + TestInMemoryProtocolHandler* http_handler_; // NOT OWNED +}; + +HEADLESS_ASYNC_DEVTOOLED_TEST_F(VirtualTimeAndResourceErrorLoopTest); + } // namespace headless diff --git a/chromium/headless/public/internal/value_conversions.h b/chromium/headless/public/internal/value_conversions.h index 7f218b42da9..c9685d08fbe 100644 --- a/chromium/headless/public/internal/value_conversions.h +++ b/chromium/headless/public/internal/value_conversions.h @@ -7,7 +7,6 @@ #include <memory> -#include "base/memory/ptr_util.h" #include "headless/public/util/error_reporter.h" namespace headless { @@ -32,22 +31,22 @@ struct FromValue { // partially specialize vector types. template <typename T> std::unique_ptr<base::Value> ToValueImpl(int value, T*) { - return base::MakeUnique<base::Value>(value); + return std::make_unique<base::Value>(value); } template <typename T> std::unique_ptr<base::Value> ToValueImpl(double value, T*) { - return base::MakeUnique<base::Value>(value); + return std::make_unique<base::Value>(value); } template <typename T> std::unique_ptr<base::Value> ToValueImpl(bool value, T*) { - return base::MakeUnique<base::Value>(value); + return std::make_unique<base::Value>(value); } template <typename T> std::unique_ptr<base::Value> ToValueImpl(const std::string& value, T*) { - return base::MakeUnique<base::Value>(value); + return std::make_unique<base::Value>(value); } template <typename T> diff --git a/chromium/headless/public/util/DEPS b/chromium/headless/public/util/DEPS index 5fc6a7b9a6a..d3da832dafd 100644 --- a/chromium/headless/public/util/DEPS +++ b/chromium/headless/public/util/DEPS @@ -1,6 +1,8 @@ specific_include_rules = { "compositor_controller_browsertest.cc": [ "+cc/base/switches.h", + "+components/viz/common/switches.h", + "+third_party/skia/include", ] } diff --git a/chromium/headless/public/util/compositor_controller.cc b/chromium/headless/public/util/compositor_controller.cc index 2bc803c8532..a41af6bcaab 100644 --- a/chromium/headless/public/util/compositor_controller.cc +++ b/chromium/headless/public/util/compositor_controller.cc @@ -4,11 +4,12 @@ #include "headless/public/util/compositor_controller.h" +#include <memory> + #include "base/base64.h" #include "base/bind.h" #include "base/cancelable_callback.h" #include "base/logging.h" -#include "base/memory/ptr_util.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/trace_event.h" @@ -87,7 +88,8 @@ class CompositorController::AnimationBeginFrameTask // posted above. compositor_controller_->BeginFrame( base::Bind(&AnimationBeginFrameTask::BeginFrameComplete, - weak_ptr_factory_.GetWeakPtr())); + weak_ptr_factory_.GetWeakPtr()), + !compositor_controller_->update_display_for_animations_); } void BeginFrameComplete(std::unique_ptr<BeginFrameResult>) { @@ -112,14 +114,16 @@ CompositorController::CompositorController( HeadlessDevToolsClient* devtools_client, VirtualTimeController* virtual_time_controller, base::TimeDelta animation_begin_frame_interval, - base::TimeDelta wait_for_compositor_ready_begin_frame_delay) + base::TimeDelta wait_for_compositor_ready_begin_frame_delay, + bool update_display_for_animations) : task_runner_(std::move(task_runner)), devtools_client_(devtools_client), virtual_time_controller_(virtual_time_controller), - animation_task_(base::MakeUnique<AnimationBeginFrameTask>(this)), + animation_task_(std::make_unique<AnimationBeginFrameTask>(this)), animation_begin_frame_interval_(animation_begin_frame_interval), wait_for_compositor_ready_begin_frame_delay_( wait_for_compositor_ready_begin_frame_delay), + update_display_for_animations_(update_display_for_animations), weak_ptr_factory_(this) { devtools_client_->GetHeadlessExperimental()->GetExperimental()->AddObserver( this); @@ -142,6 +146,7 @@ CompositorController::~CompositorController() { void CompositorController::PostBeginFrame( const base::Callback<void(std::unique_ptr<BeginFrameResult>)>& begin_frame_complete_callback, + bool no_display_updates, std::unique_ptr<ScreenshotParams> screenshot) { // In certain nesting situations, we should not issue a BeginFrame immediately // - for example, issuing a new BeginFrame within a BeginFrameCompleted or @@ -151,12 +156,13 @@ void CompositorController::PostBeginFrame( FROM_HERE, base::Bind(&CompositorController::BeginFrame, weak_ptr_factory_.GetWeakPtr(), begin_frame_complete_callback, - base::Passed(&screenshot))); + no_display_updates, base::Passed(&screenshot))); } void CompositorController::BeginFrame( const base::Callback<void(std::unique_ptr<BeginFrameResult>)>& begin_frame_complete_callback, + bool no_display_updates, std::unique_ptr<ScreenshotParams> screenshot) { DCHECK(!begin_frame_complete_callback_); begin_frame_complete_callback_ = begin_frame_complete_callback; @@ -180,6 +186,8 @@ void CompositorController::BeginFrame( params_builder.SetInterval( animation_begin_frame_interval_.InMillisecondsF()); + params_builder.SetNoDisplayUpdates(no_display_updates); + // TODO(eseckler): Set time fields. This requires obtaining the absolute // virtual time stamp. if (screenshot) @@ -228,6 +236,8 @@ void CompositorController::OnNeedsBeginFramesChanged( void CompositorController::OnMainFrameReadyForScreenshots( const MainFrameReadyForScreenshotsParams& params) { + TRACE_EVENT0("headless", + "CompositorController::OnMainFrameReadyForScreenshots"); main_frame_ready_ = true; // If a WaitForCompositorReadyBeginFrame is still scheduled, skip it. @@ -392,9 +402,11 @@ void CompositorController::CaptureScreenshot( // animation BeginFrame for the current virtual time pause. animation_task_->CompositorControllerIssuingScreenshotBeginFrame(); + const bool no_display_updates = false; PostBeginFrame( base::Bind(&CompositorController::CaptureScreenshotBeginFrameComplete, weak_ptr_factory_.GetWeakPtr()), + no_display_updates, ScreenshotParams::Builder() .SetFormat(format) .SetQuality(quality) diff --git a/chromium/headless/public/util/compositor_controller.h b/chromium/headless/public/util/compositor_controller.h index 09012a4b377..e2857d132bd 100644 --- a/chromium/headless/public/util/compositor_controller.h +++ b/chromium/headless/public/util/compositor_controller.h @@ -36,12 +36,17 @@ class HEADLESS_EXPORT CompositorController // |wait_for_compositor_ready_begin_frame_delay| is the real time delay // between BeginFrames that are sent while waiting for the main frame // compositor to become ready (real time). + // If |update_display_for_animations| is false, animation BeginFrames will not + // commit or draw visual updates to the display. This can be used to reduce + // the overhead of such BeginFrames in the common case that screenshots will + // be taken from separate BeginFrames. CompositorController( scoped_refptr<base::SequencedTaskRunner> task_runner, HeadlessDevToolsClient* devtools_client, VirtualTimeController* virtual_time_controller, base::TimeDelta animation_begin_frame_interval, - base::TimeDelta wait_for_compositor_ready_begin_frame_delay); + base::TimeDelta wait_for_compositor_ready_begin_frame_delay, + bool update_display_for_animations = true); ~CompositorController() override; // Issues BeginFrames until the main frame's compositor has completed @@ -89,12 +94,14 @@ class HEADLESS_EXPORT CompositorController void PostBeginFrame( const base::Callback<void(std::unique_ptr<BeginFrameResult>)>& begin_frame_complete_callback, + bool no_display_updates = false, std::unique_ptr<ScreenshotParams> screenshot = nullptr); // Issues a BeginFrame synchronously and runs |begin_frame_complete_callback| // when done. Should not be called again until |begin_frame_complete_callback| // was run. void BeginFrame(const base::Callback<void(std::unique_ptr<BeginFrameResult>)>& begin_frame_complete_callback, + bool no_display_updates = false, std::unique_ptr<ScreenshotParams> screenshot = nullptr); // Runs the |begin_frame_complete_callback_| and the |idle_callback_| if set. void BeginFrameComplete(std::unique_ptr<BeginFrameResult>); @@ -127,6 +134,7 @@ class HEADLESS_EXPORT CompositorController base::CancelableClosure wait_for_compositor_ready_begin_frame_task_; base::TimeDelta animation_begin_frame_interval_; base::TimeDelta wait_for_compositor_ready_begin_frame_delay_; + bool update_display_for_animations_; bool needs_begin_frames_ = false; bool main_frame_ready_ = false; base::Time last_begin_frame_time_ = base::Time::UnixEpoch(); diff --git a/chromium/headless/public/util/compositor_controller_browsertest.cc b/chromium/headless/public/util/compositor_controller_browsertest.cc index 5169490626e..5a7ec4bce55 100644 --- a/chromium/headless/public/util/compositor_controller_browsertest.cc +++ b/chromium/headless/public/util/compositor_controller_browsertest.cc @@ -4,10 +4,13 @@ #include "headless/public/util/compositor_controller.h" +#include <memory> + #include "base/bind.h" #include "base/command_line.h" #include "build/build_config.h" #include "cc/base/switches.h" +#include "components/viz/common/switches.h" #include "content/public/common/content_switches.h" #include "content/public/test/browser_test.h" #include "headless/public/devtools/domains/runtime.h" @@ -16,6 +19,9 @@ #include "headless/public/util/virtual_time_controller.h" #include "headless/test/headless_browser_test.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "third_party/skia/include/core/SkColor.h" +#include "ui/gfx/codec/png_codec.h" namespace headless { @@ -23,47 +29,130 @@ namespace headless { #if !defined(OS_MACOSX) namespace { + static constexpr base::TimeDelta kAnimationFrameInterval = base::TimeDelta::FromMilliseconds(16); static constexpr base::TimeDelta kWaitForCompositorReadyFrameDelay = base::TimeDelta::FromMilliseconds(20); + +class BeginFrameCounter : HeadlessDevToolsClient::RawProtocolListener { + public: + BeginFrameCounter(HeadlessDevToolsClient* client) : client_(client) { + client_->SetRawProtocolListener(this); + } + + ~BeginFrameCounter() override { client_->SetRawProtocolListener(nullptr); } + + bool OnProtocolMessage(const std::string& devtools_agent_host_id, + const std::string& json_message, + const base::DictionaryValue& parsed_message) override { + const base::Value* id_value = parsed_message.FindKey("id"); + if (!id_value) + return false; + + const base::DictionaryValue* result_dict; + if (parsed_message.GetDictionary("result", &result_dict)) { + bool main_frame_content_updated; + if (result_dict->GetBoolean("mainFrameContentUpdated", + &main_frame_content_updated)) { + ++begin_frame_count_; + if (main_frame_content_updated) + ++main_frame_update_count_; + } + } + return false; + } + + int begin_frame_count() const { return begin_frame_count_; } + int main_frame_update_count() const { return main_frame_update_count_; } + + private: + HeadlessDevToolsClient* client_; // NOT OWNED. + int begin_frame_count_ = 0; + int main_frame_update_count_ = 0; +}; + +bool DecodePNG(std::string png_data, SkBitmap* bitmap) { + return gfx::PNGCodec::Decode( + reinterpret_cast<unsigned const char*>(png_data.data()), png_data.size(), + bitmap); +} + } // namespace class CompositorControllerBrowserTest - : public HeadlessAsyncDevTooledBrowserTest { + : public HeadlessAsyncDevTooledBrowserTest, + public ::testing::WithParamInterface<bool> { public: + void SetUp() override { + EnablePixelOutput(); + if (GetParam()) { + UseSoftwareCompositing(); + SetUpWithoutGPU(); + } else { + HeadlessAsyncDevTooledBrowserTest::SetUp(); + } + } + void SetUpCommandLine(base::CommandLine* command_line) override { HeadlessAsyncDevTooledBrowserTest::SetUpCommandLine(command_line); + // See bit.ly/headless-rendering for why we use these flags. command_line->AppendSwitch(cc::switches::kRunAllCompositorStagesBeforeDraw); command_line->AppendSwitch(switches::kDisableNewContentRenderingTimeout); + command_line->AppendSwitch(cc::switches::kDisableCheckerImaging); + command_line->AppendSwitch(cc::switches::kDisableThreadedAnimation); + command_line->AppendSwitch(switches::kDisableThreadedScrolling); } bool GetEnableBeginFrameControl() override { return true; } void RunDevTooledTest() override { + begin_frame_counter_ = + base::MakeUnique<BeginFrameCounter>(devtools_client_.get()); virtual_time_controller_ = - base::MakeUnique<VirtualTimeController>(devtools_client_.get()); + std::make_unique<VirtualTimeController>(devtools_client_.get()); + const bool update_display_for_animations = false; compositor_controller_ = base::MakeUnique<CompositorController>( browser()->BrowserMainThread(), devtools_client_.get(), virtual_time_controller_.get(), kAnimationFrameInterval, - kWaitForCompositorReadyFrameDelay); + kWaitForCompositorReadyFrameDelay, update_display_for_animations); + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce(&CompositorControllerBrowserTest::WaitForReady, + base::Unretained(this)), + base::TimeDelta::FromSeconds(1)); + } + + void WaitForReady() { compositor_controller_->WaitForCompositorReady( - base::Bind(&CompositorControllerBrowserTest::OnCompositorReady, - base::Unretained(this))); + base::BindRepeating(&CompositorControllerBrowserTest::OnCompositorReady, + base::Unretained(this))); + } + + virtual void OnCompositorReadyExpectations() { + // The renderer's first CompositorFrame may or may not have been included in + // a BeginFrame result. + main_frame_update_count_after_ready_ = + begin_frame_counter_->main_frame_update_count(); + EXPECT_GE(1, main_frame_update_count_after_ready_); } void OnCompositorReady() { - // Request animation frames in the main frame. + OnCompositorReadyExpectations(); + + // Request animation frames in the main frame. Each frame changes the body + // background color. devtools_client_->GetRuntime()->Evaluate( "window.rafCount = 0;" "function onRaf(timestamp) {" " window.rafCount++;" + " document.body.style.backgroundColor = '#' + window.rafCount * 100;" " window.requestAnimationFrame(onRaf);" "};" "window.requestAnimationFrame(onRaf);", - base::Bind(&CompositorControllerBrowserTest::OnRafReady, - base::Unretained(this))); + base::BindRepeating(&CompositorControllerBrowserTest::OnRafReady, + base::Unretained(this))); } void OnRafReady(std::unique_ptr<runtime::EvaluateResult> result) { @@ -73,16 +162,23 @@ class CompositorControllerBrowserTest virtual_time_controller_->GrantVirtualTimeBudget( emulation::VirtualTimePolicy::ADVANCE, kNumFrames * kAnimationFrameInterval, base::Bind([]() {}), - base::Bind(&CompositorControllerBrowserTest::OnVirtualTimeBudgetExpired, - base::Unretained(this))); + base::BindRepeating( + &CompositorControllerBrowserTest::OnVirtualTimeBudgetExpired, + base::Unretained(this))); } void OnVirtualTimeBudgetExpired() { + // Even though the rAF made a change to the frame's background color, no + // further CompositorFrames should have been produced for animations, + // because update_display_for_animations is false. + EXPECT_EQ(main_frame_update_count_after_ready_, + begin_frame_counter_->main_frame_update_count()); + // Get animation frame count. devtools_client_->GetRuntime()->Evaluate( "window.rafCount", - base::Bind(&CompositorControllerBrowserTest::OnGetRafCount, - base::Unretained(this))); + base::BindRepeating(&CompositorControllerBrowserTest::OnGetRafCount, + base::Unretained(this))); } void OnGetRafCount(std::unique_ptr<runtime::EvaluateResult> result) { @@ -90,20 +186,73 @@ class CompositorControllerBrowserTest EXPECT_FALSE(result->HasExceptionDetails()); EXPECT_EQ(kNumFrames, result->GetResult()->GetValue()->GetInt()); + + compositor_controller_->CaptureScreenshot( + headless_experimental::ScreenshotParamsFormat::PNG, 100, + base::BindRepeating(&CompositorControllerBrowserTest::OnScreenshot, + base::Unretained(this))); + } + + void OnScreenshot(const std::string& screenshot_data) { + EXPECT_LT(0U, screenshot_data.length()); + + if (screenshot_data.length()) { + SkBitmap result_bitmap; + EXPECT_TRUE(DecodePNG(screenshot_data, &result_bitmap)); + + EXPECT_EQ(800, result_bitmap.width()); + EXPECT_EQ(600, result_bitmap.height()); + SkColor actual_color = result_bitmap.getColor(200, 200); + // Screenshot was the fourth frame, so background color should be #400. + SkColor expected_color = SkColorSetRGB(0x44, 0x00, 0x00); + EXPECT_EQ(expected_color, actual_color); + } + FinishAsynchronousTest(); } - private: + protected: static constexpr int kNumFrames = 3; + std::unique_ptr<BeginFrameCounter> begin_frame_counter_; std::unique_ptr<VirtualTimeController> virtual_time_controller_; std::unique_ptr<CompositorController> compositor_controller_; + int main_frame_update_count_after_ready_ = 0; }; /* static */ constexpr int CompositorControllerBrowserTest::kNumFrames; -HEADLESS_ASYNC_DEVTOOLED_TEST_F(CompositorControllerBrowserTest); +HEADLESS_ASYNC_DEVTOOLED_TEST_P(CompositorControllerBrowserTest); + +// Instantiate test case for both software and gpu compositing modes. +INSTANTIATE_TEST_CASE_P(CompositorControllerBrowserTests, + CompositorControllerBrowserTest, + ::testing::Bool()); + +class CompositorControllerSurfaceSyncBrowserTest + : public CompositorControllerBrowserTest { + public: + void SetUpCommandLine(base::CommandLine* command_line) override { + CompositorControllerBrowserTest::SetUpCommandLine(command_line); + command_line->AppendSwitch(switches::kEnableSurfaceSynchronization); + } + + void OnCompositorReadyExpectations() override { + CompositorControllerBrowserTest::OnCompositorReadyExpectations(); + // With surface sync enabled, we should have waited for the renderer's + // CompositorFrame in the first BeginFrame. + EXPECT_EQ(1, begin_frame_counter_->begin_frame_count()); + EXPECT_EQ(1, begin_frame_counter_->main_frame_update_count()); + } +}; + +HEADLESS_ASYNC_DEVTOOLED_TEST_P(CompositorControllerSurfaceSyncBrowserTest); + +// Instantiate test case for both software and gpu compositing modes. +INSTANTIATE_TEST_CASE_P(CompositorControllerSurfaceSyncBrowserTests, + CompositorControllerSurfaceSyncBrowserTest, + ::testing::Bool()); #endif // !defined(OS_MACOSX) diff --git a/chromium/headless/public/util/compositor_controller_unittest.cc b/chromium/headless/public/util/compositor_controller_unittest.cc index 33aa032de0c..8eb04f11ec3 100644 --- a/chromium/headless/public/util/compositor_controller_unittest.cc +++ b/chromium/headless/public/util/compositor_controller_unittest.cc @@ -4,10 +4,11 @@ #include "headless/public/util/compositor_controller.h" +#include <memory> + #include "base/base64.h" #include "base/bind.h" #include "base/json/json_writer.h" -#include "base/memory/ptr_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" #include "base/test/test_simple_task_runner.h" @@ -50,7 +51,7 @@ class TestVirtualTimeController : public VirtualTimeController { class CompositorControllerTest : public ::testing::Test { protected: - CompositorControllerTest() { + CompositorControllerTest(bool update_display_for_animations = true) { task_runner_ = base::MakeRefCounted<base::TestSimpleTaskRunner>(); client_.SetTaskRunnerForTests(task_runner_); mock_host_ = base::MakeRefCounted<MockDevToolsAgentHost>(); @@ -59,14 +60,15 @@ class CompositorControllerTest : public ::testing::Test { EXPECT_CALL(*mock_host_, AttachClient(&client_)); client_.AttachToHost(mock_host_.get()); virtual_time_controller_ = - base::MakeUnique<TestVirtualTimeController>(&client_); + std::make_unique<TestVirtualTimeController>(&client_); EXPECT_CALL(*virtual_time_controller_, ScheduleRepeatingTask(_, kAnimationFrameInterval)) .WillOnce(testing::SaveArg<0>(&task_)); ExpectHeadlessExperimentalEnable(); - controller_ = base::MakeUnique<CompositorController>( + controller_ = std::make_unique<CompositorController>( task_runner_, &client_, virtual_time_controller_.get(), - kAnimationFrameInterval, kWaitForCompositorReadyFrameDelay); + kAnimationFrameInterval, kWaitForCompositorReadyFrameDelay, + update_display_for_animations); EXPECT_NE(nullptr, task_); } @@ -101,14 +103,16 @@ class CompositorControllerTest : public ::testing::Test { next_begin_frame_time_ = virtual_time; } - void ExpectBeginFrame(std::unique_ptr<headless_experimental::ScreenshotParams> + void ExpectBeginFrame(bool no_display_updates = false, + std::unique_ptr<headless_experimental::ScreenshotParams> screenshot_params = nullptr) { last_command_id_ += 2; base::DictionaryValue params; auto builder = std::move(headless_experimental::BeginFrameParams::Builder() .SetFrameTime(next_begin_frame_time_.ToJsTime()) - .SetInterval(kAnimationFrameInterval.InMillisecondsF())); + .SetInterval(kAnimationFrameInterval.InMillisecondsF()) + .SetNoDisplayUpdates(no_display_updates)); if (screenshot_params) builder.SetScreenshot(std::move(screenshot_params)); // Subsequent BeginFrames should have a later timestamp. @@ -183,7 +187,7 @@ TEST_F(CompositorControllerTest, WaitForCompositorReady) { // Shouldn't send any commands yet as no needsBeginFrames event was sent yet. bool ready = false; controller_->WaitForCompositorReady( - base::Bind([](bool* ready) { *ready = true; }, &ready)); + base::BindRepeating([](bool* ready) { *ready = true; }, &ready)); EXPECT_FALSE(ready); // Sends BeginFrames with delay while they are needed. @@ -244,7 +248,7 @@ TEST_F(CompositorControllerTest, CaptureScreenshot) { bool done = false; controller_->CaptureScreenshot( headless_experimental::ScreenshotParamsFormat::PNG, 100, - base::Bind( + base::BindRepeating( [](bool* done, const std::string& screenshot_data) { *done = true; EXPECT_EQ("test", screenshot_data); @@ -254,10 +258,10 @@ TEST_F(CompositorControllerTest, CaptureScreenshot) { EXPECT_TRUE(task_runner_->HasPendingTask()); ExpectVirtualTime(0, 0); ExpectBeginFrame( - headless_experimental::ScreenshotParams::Builder() - .SetFormat(headless_experimental::ScreenshotParamsFormat::PNG) - .SetQuality(100) - .Build()); + false, headless_experimental::ScreenshotParams::Builder() + .SetFormat(headless_experimental::ScreenshotParamsFormat::PNG) + .SetQuality(100) + .Build()); task_runner_->RunPendingTasks(); std::string base64; @@ -270,7 +274,7 @@ TEST_F(CompositorControllerTest, CaptureScreenshot) { TEST_F(CompositorControllerTest, WaitForMainFrameContentUpdate) { bool updated = false; controller_->WaitForMainFrameContentUpdate( - base::Bind([](bool* updated) { *updated = true; }, &updated)); + base::BindRepeating([](bool* updated) { *updated = true; }, &updated)); EXPECT_FALSE(updated); // Sends BeginFrames while they are needed. @@ -324,7 +328,7 @@ TEST_F(CompositorControllerTest, WaitForMainFrameContentUpdate) { TEST_F(CompositorControllerTest, SendsAnimationFrames) { bool can_continue = false; - auto continue_callback = base::Bind( + auto continue_callback = base::BindRepeating( [](bool* can_continue) { *can_continue = true; }, &can_continue); // Task doesn't block virtual time request. @@ -371,7 +375,7 @@ TEST_F(CompositorControllerTest, SendsAnimationFrames) { TEST_F(CompositorControllerTest, SkipsAnimationFrameForScreenshots) { bool can_continue = false; - auto continue_callback = base::Bind( + auto continue_callback = base::BindRepeating( [](bool* can_continue) { *can_continue = true; }, &can_continue); SendMainFrameReadyForScreenshotsEvent(); @@ -386,15 +390,15 @@ TEST_F(CompositorControllerTest, SkipsAnimationFrameForScreenshots) { controller_->CaptureScreenshot( headless_experimental::ScreenshotParamsFormat::PNG, 100, - base::Bind([](const std::string&) {})); + base::BindRepeating([](const std::string&) {})); EXPECT_TRUE(task_runner_->HasPendingTask()); ExpectVirtualTime(0, 0); ExpectBeginFrame( - headless_experimental::ScreenshotParams::Builder() - .SetFormat(headless_experimental::ScreenshotParamsFormat::PNG) - .SetQuality(100) - .Build()); + false, headless_experimental::ScreenshotParams::Builder() + .SetFormat(headless_experimental::ScreenshotParamsFormat::PNG) + .SetQuality(100) + .Build()); task_runner_->RunPendingTasks(); EXPECT_TRUE(can_continue); @@ -404,7 +408,7 @@ TEST_F(CompositorControllerTest, SkipsAnimationFrameForScreenshots) { TEST_F(CompositorControllerTest, PostponesAnimationFrameWhenBudgetExpired) { bool can_continue = false; - auto continue_callback = base::Bind( + auto continue_callback = base::BindRepeating( [](bool* can_continue) { *can_continue = true; }, &can_continue); SendNeedsBeginFramesEvent(true); @@ -438,7 +442,7 @@ TEST_F(CompositorControllerTest, TEST_F(CompositorControllerTest, SkipsAnimationFrameWhenBudgetExpiredAndScreenshotWasTaken) { bool can_continue = false; - auto continue_callback = base::Bind( + auto continue_callback = base::BindRepeating( [](bool* can_continue) { *can_continue = true; }, &can_continue); SendMainFrameReadyForScreenshotsEvent(); @@ -459,15 +463,15 @@ TEST_F(CompositorControllerTest, controller_->CaptureScreenshot( headless_experimental::ScreenshotParamsFormat::PNG, 100, - base::Bind([](const std::string&) {})); + base::BindRepeating([](const std::string&) {})); EXPECT_TRUE(task_runner_->HasPendingTask()); ExpectVirtualTime(0, 0); ExpectBeginFrame( - headless_experimental::ScreenshotParams::Builder() - .SetFormat(headless_experimental::ScreenshotParamsFormat::PNG) - .SetQuality(100) - .Build()); + false, headless_experimental::ScreenshotParams::Builder() + .SetFormat(headless_experimental::ScreenshotParamsFormat::PNG) + .SetQuality(100) + .Build()); task_runner_->RunPendingTasks(); // Sends a BeginFrame when more virtual time budget is requested. @@ -480,7 +484,8 @@ TEST_F(CompositorControllerTest, TEST_F(CompositorControllerTest, WaitUntilIdle) { bool idle = false; - auto idle_callback = base::Bind([](bool* idle) { *idle = true; }, &idle); + auto idle_callback = + base::BindRepeating([](bool* idle) { *idle = true; }, &idle); SendNeedsBeginFramesEvent(true); EXPECT_FALSE(task_runner_->HasPendingTask()); @@ -491,7 +496,7 @@ TEST_F(CompositorControllerTest, WaitUntilIdle) { idle = false; // Send a BeginFrame. - task_->IntervalElapsed(kAnimationFrameInterval, base::Bind([]() {})); + task_->IntervalElapsed(kAnimationFrameInterval, base::BindRepeating([]() {})); EXPECT_TRUE(task_runner_->HasPendingTask()); ExpectVirtualTime(0, 0); @@ -508,4 +513,67 @@ TEST_F(CompositorControllerTest, WaitUntilIdle) { idle = false; } +class CompositorControllerNoDisplayUpdateTest + : public CompositorControllerTest { + protected: + CompositorControllerNoDisplayUpdateTest() : CompositorControllerTest(false) {} +}; + +TEST_F(CompositorControllerNoDisplayUpdateTest, + SkipsDisplayUpdateOnlyForAnimationFrames) { + bool can_continue = false; + auto continue_callback = base::BindRepeating( + [](bool* can_continue) { *can_continue = true; }, &can_continue); + + // Wait for update BeginFrames update display. + SendNeedsBeginFramesEvent(true); + controller_->WaitForMainFrameContentUpdate(base::BindRepeating([]() {})); + EXPECT_TRUE(task_runner_->HasPendingTask()); + ExpectVirtualTime(1000, 0); + ExpectBeginFrame(); + task_runner_->RunPendingTasks(); + + SendMainFrameReadyForScreenshotsEvent(); + EXPECT_FALSE(task_runner_->HasPendingTask()); + + SendBeginFrameReply(true, true, std::string()); + EXPECT_FALSE(task_runner_->HasPendingTask()); + + // Sends an animation BeginFrame without display update after interval + // elapsed. + task_->IntervalElapsed(kAnimationFrameInterval, continue_callback); + EXPECT_FALSE(can_continue); + + EXPECT_TRUE(task_runner_->HasPendingTask()); + ExpectVirtualTime(1000, kAnimationFrameInterval.InMillisecondsF()); + ExpectBeginFrame(true); + task_runner_->RunPendingTasks(); + + // Lets virtual time continue after BeginFrame was completed. + SendBeginFrameReply(false, false, std::string()); + EXPECT_FALSE(task_runner_->HasPendingTask()); + EXPECT_TRUE(can_continue); + can_continue = false; + + // Screenshots update display. + task_->IntervalElapsed(kAnimationFrameInterval, continue_callback); + EXPECT_FALSE(can_continue); + + controller_->CaptureScreenshot( + headless_experimental::ScreenshotParamsFormat::PNG, 100, + base::BindRepeating([](const std::string&) {})); + + EXPECT_TRUE(task_runner_->HasPendingTask()); + ExpectVirtualTime(1000, kAnimationFrameInterval.InMillisecondsF() * 2); + ExpectBeginFrame( + false, headless_experimental::ScreenshotParams::Builder() + .SetFormat(headless_experimental::ScreenshotParamsFormat::PNG) + .SetQuality(100) + .Build()); + task_runner_->RunPendingTasks(); + + EXPECT_TRUE(can_continue); + can_continue = false; +} + } // namespace headless diff --git a/chromium/headless/public/util/deterministic_dispatcher_test.cc b/chromium/headless/public/util/deterministic_dispatcher_test.cc index 5b769800ec8..17fdbf00e96 100644 --- a/chromium/headless/public/util/deterministic_dispatcher_test.cc +++ b/chromium/headless/public/util/deterministic_dispatcher_test.cc @@ -8,7 +8,6 @@ #include <string> #include <vector> -#include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" @@ -154,7 +153,7 @@ TEST_F(DeterministicDispatcherTest, NavigationBlocksUrlRequests) { ¬ifications)); base::Closure navigation_done_closure; deterministic_dispatcher_->NavigationRequested( - base::MakeUnique<NavigationRequestForTest>(&navigation_done_closure)); + std::make_unique<NavigationRequestForTest>(&navigation_done_closure)); std::unique_ptr<FakeManagedDispatchURLRequestJob> job2( new FakeManagedDispatchURLRequestJob(deterministic_dispatcher_.get(), 2, ¬ifications)); diff --git a/chromium/headless/public/util/deterministic_http_protocol_handler.cc b/chromium/headless/public/util/deterministic_http_protocol_handler.cc index 84cc84875be..0ed79e94863 100644 --- a/chromium/headless/public/util/deterministic_http_protocol_handler.cc +++ b/chromium/headless/public/util/deterministic_http_protocol_handler.cc @@ -4,8 +4,9 @@ #include "headless/public/util/deterministic_http_protocol_handler.h" +#include <memory> + #include "base/macros.h" -#include "base/memory/ptr_util.h" #include "headless/public/headless_browser_context.h" #include "headless/public/util/deterministic_dispatcher.h" #include "headless/public/util/generic_url_request_job.h" @@ -65,7 +66,7 @@ net::URLRequestJob* DeterministicHttpProtocolHandler::MaybeCreateJob( } return new GenericURLRequestJob( request, network_delegate, deterministic_dispatcher_, - base::MakeUnique<HttpURLFetcher>(url_request_context_.get()), + std::make_unique<HttpURLFetcher>(url_request_context_.get()), nop_delegate_.get(), headless_browser_context_); } diff --git a/chromium/headless/public/util/expedited_dispatcher.cc b/chromium/headless/public/util/expedited_dispatcher.cc index 1fe445cca88..831819b1f67 100644 --- a/chromium/headless/public/util/expedited_dispatcher.cc +++ b/chromium/headless/public/util/expedited_dispatcher.cc @@ -26,13 +26,13 @@ void ExpeditedDispatcher::JobFailed(ManagedDispatchURLRequestJob* job, net::Error error) { io_thread_task_runner_->PostTask( FROM_HERE, base::Bind(&ManagedDispatchURLRequestJob::OnStartError, - base::Unretained(job), error)); + job->GetWeakPtr(), error)); } void ExpeditedDispatcher::DataReady(ManagedDispatchURLRequestJob* job) { io_thread_task_runner_->PostTask( FROM_HERE, base::Bind(&ManagedDispatchURLRequestJob::OnHeadersComplete, - base::Unretained(job))); + job->GetWeakPtr())); } void ExpeditedDispatcher::JobDeleted(ManagedDispatchURLRequestJob*) {} diff --git a/chromium/headless/public/util/expedited_dispatcher_test.cc b/chromium/headless/public/util/expedited_dispatcher_test.cc index 05571f6df02..96c3ccf4137 100644 --- a/chromium/headless/public/util/expedited_dispatcher_test.cc +++ b/chromium/headless/public/util/expedited_dispatcher_test.cc @@ -8,7 +8,6 @@ #include <string> #include <vector> -#include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" @@ -111,7 +110,7 @@ TEST_F(ExpeditedDispatcherTest, NavigationDoesNotBlockUrlRequests) { ¬ifications)); base::Closure navigation_done_closure; expedited_dispatcher_->NavigationRequested( - base::MakeUnique<NavigationRequestForTest>(&navigation_done_closure)); + std::make_unique<NavigationRequestForTest>(&navigation_done_closure)); std::unique_ptr<FakeManagedDispatchURLRequestJob> job2( new FakeManagedDispatchURLRequestJob(expedited_dispatcher_.get(), 2, ¬ifications)); diff --git a/chromium/headless/public/util/generic_url_request_job.cc b/chromium/headless/public/util/generic_url_request_job.cc index e865fae2f50..8095d94c345 100644 --- a/chromium/headless/public/util/generic_url_request_job.cc +++ b/chromium/headless/public/util/generic_url_request_job.cc @@ -143,6 +143,34 @@ void GenericURLRequestJob::OnFetchComplete( body_size_ = body_size; load_timing_info_ = load_timing_info; + // Save any cookies from the response. + if (!(request_->load_flags() & net::LOAD_DO_NOT_SAVE_COOKIES) && + request_->context()->cookie_store()) { + net::CookieOptions options; + options.set_include_httponly(); + + base::Time response_date; + if (!response_headers_->GetDateValue(&response_date)) + response_date = base::Time(); + options.set_server_time(response_date); + + // Set all cookies, without waiting for them to be set. Any subsequent read + // will see the combined result of all cookie operation. + const base::StringPiece name("Set-Cookie"); + std::string cookie_line; + size_t iter = 0; + while (response_headers_->EnumerateHeader(&iter, name, &cookie_line)) { + std::unique_ptr<net::CanonicalCookie> cookie = + net::CanonicalCookie::Create(final_url, cookie_line, + base::Time::Now(), options); + if (!cookie || !CanSetCookie(*cookie, &options)) + continue; + request_->context()->cookie_store()->SetCanonicalCookieAsync( + std::move(cookie), final_url.SchemeIsCryptographic(), + !options.exclude_httponly(), net::CookieStore::SetCookiesCallback()); + } + } + DispatchHeadersComplete(); delegate_->OnResourceLoadComplete(this, final_url, response_headers_, body_, 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 777837d4b03..d1188b54777 100644 --- a/chromium/headless/public/util/generic_url_request_job_test.cc +++ b/chromium/headless/public/util/generic_url_request_job_test.cc @@ -10,7 +10,6 @@ #include "base/json/json_reader.h" #include "base/json/json_writer.h" -#include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" @@ -28,7 +27,11 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +using testing::AllOf; +using testing::ElementsAre; +using testing::Eq; using testing::NotNull; +using testing::Property; using testing::_; std::ostream& operator<<(std::ostream& os, const base::DictionaryValue& value) { @@ -157,7 +160,7 @@ class MockProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler { net::NetworkDelegate* network_delegate) const override { return new GenericURLRequestJob( request, network_delegate, dispatcher_, - base::MakeUnique<MockFetcher>(fetch_request_, received_post_data_, + std::make_unique<MockFetcher>(fetch_request_, received_post_data_, json_fetch_reply_map_, on_request_callback_), job_delegate_, nullptr); @@ -210,7 +213,7 @@ class GenericURLRequestJobTest : public testing::Test { TRAFFIC_ANNOTATION_FOR_TESTS)); request->set_method("POST"); request->set_upload(net::ElementsUploadDataStream::CreateWithReader( - base::MakeUnique<net::UploadBytesElementReader>(post_data.data(), + std::make_unique<net::UploadBytesElementReader>(post_data.data(), post_data.size()), 0)); request->Start(); @@ -292,7 +295,7 @@ TEST_F(GenericURLRequestJobTest, BasicPostRequestParams) { std::string post_data = "lorem ipsom"; request->set_upload(net::ElementsUploadDataStream::CreateWithReader( - base::MakeUnique<net::UploadBytesElementReader>(post_data.data(), + std::make_unique<net::UploadBytesElementReader>(post_data.data(), post_data.size()), 0)); request->Start(); @@ -338,7 +341,7 @@ TEST_F(GenericURLRequestJobTest, LargePostData) { post_data[i] = i & 127; request->set_upload(net::ElementsUploadDataStream::CreateWithReader( - base::MakeUnique<net::UploadBytesElementReader>(&post_data[0], + std::make_unique<net::UploadBytesElementReader>(&post_data[0], post_data.size()), 0)); request->Start(); @@ -520,6 +523,27 @@ TEST_F(GenericURLRequestJobTest, RequestWithCookies) { EXPECT_THAT(fetch_request_, MatchesJson(expected_request_json)); } +TEST_F(GenericURLRequestJobTest, ResponseWithCookies) { + std::string reply = R"( + { + "url": "https://example.com", + "data": "Reply", + "headers": { + "Set-Cookie": "A=foobar; path=/; " + } + })"; + + std::unique_ptr<net::URLRequest> request( + CreateAndCompleteGetJob(GURL("https://example.com"), reply)); + + EXPECT_THAT(*cookie_store_.cookies(), + ElementsAre(AllOf( + Property(&net::CanonicalCookie::Name, Eq("A")), + Property(&net::CanonicalCookie::Value, Eq("foobar")), + Property(&net::CanonicalCookie::Domain, Eq("example.com")), + Property(&net::CanonicalCookie::Path, Eq("/"))))); +} + TEST_F(GenericURLRequestJobTest, OnResourceLoadFailed) { EXPECT_CALL(job_delegate_, OnResourceLoadFailed(_, net::ERR_ADDRESS_UNREACHABLE)); @@ -662,7 +686,7 @@ TEST_F(GenericURLRequestJobTest, GetPostDataAsync) { json_fetch_reply_map_[url.spec()] = json_reply; request->set_upload(net::ElementsUploadDataStream::CreateWithReader( - base::MakeUnique<ByteAtATimeUploadElementReader>("payload"), 0)); + std::make_unique<ByteAtATimeUploadElementReader>("payload"), 0)); request->Start(); base::RunLoop().RunUntilIdle(); @@ -695,7 +719,7 @@ TEST_F(GenericURLRequestJobTest, LargePostDataNotByteReader) { post_data.at(i) = i & 127; request->set_upload(net::ElementsUploadDataStream::CreateWithReader( - base::MakeUnique<ByteAtATimeUploadElementReader>(post_data), 0)); + std::make_unique<ByteAtATimeUploadElementReader>(post_data), 0)); request->Start(); base::RunLoop().RunUntilIdle(); @@ -728,13 +752,13 @@ TEST_F(GenericURLRequestJobTest, PostWithMultipleElements) { std::vector<std::unique_ptr<net::UploadElementReader>> element_readers; element_readers.push_back( - base::MakeUnique<ByteAtATimeUploadElementReader>("Does ")); + std::make_unique<ByteAtATimeUploadElementReader>("Does ")); element_readers.push_back( - base::MakeUnique<ByteAtATimeUploadElementReader>("this ")); + std::make_unique<ByteAtATimeUploadElementReader>("this ")); element_readers.push_back( - base::MakeUnique<ByteAtATimeUploadElementReader>("work?")); + std::make_unique<ByteAtATimeUploadElementReader>("work?")); - request->set_upload(base::MakeUnique<net::ElementsUploadDataStream>( + request->set_upload(std::make_unique<net::ElementsUploadDataStream>( std::move(element_readers), 0)); request->Start(); base::RunLoop().RunUntilIdle(); diff --git a/chromium/headless/public/util/http_url_fetcher.cc b/chromium/headless/public/util/http_url_fetcher.cc index 0e83ebb970f..7354aa7f28a 100644 --- a/chromium/headless/public/util/http_url_fetcher.cc +++ b/chromium/headless/public/util/http_url_fetcher.cc @@ -4,6 +4,8 @@ #include "headless/public/util/http_url_fetcher.h" +#include <memory> + #include "headless/public/util/generic_url_request_job.h" #include "net/base/elements_upload_data_stream.h" #include "net/base/io_buffer.h" @@ -107,7 +109,7 @@ HttpURLFetcher::Delegate::Delegate( if (!post_data.empty()) { request_->set_upload(net::ElementsUploadDataStream::CreateWithReader( - base::MakeUnique<net::UploadBytesElementReader>(post_data.data(), + std::make_unique<net::UploadBytesElementReader>(post_data.data(), post_data.size()), 0)); } diff --git a/chromium/headless/public/util/managed_dispatch_url_request_job.cc b/chromium/headless/public/util/managed_dispatch_url_request_job.cc index 2f79373af0d..0d3eeb55996 100644 --- a/chromium/headless/public/util/managed_dispatch_url_request_job.cc +++ b/chromium/headless/public/util/managed_dispatch_url_request_job.cc @@ -13,7 +13,8 @@ ManagedDispatchURLRequestJob::ManagedDispatchURLRequestJob( net::NetworkDelegate* network_delegate, URLRequestDispatcher* url_request_dispatcher) : net::URLRequestJob(request, network_delegate), - url_request_dispatcher_(url_request_dispatcher) { + url_request_dispatcher_(url_request_dispatcher), + weak_ptr_factory_(this) { url_request_dispatcher_->JobCreated(this); } diff --git a/chromium/headless/public/util/managed_dispatch_url_request_job.h b/chromium/headless/public/util/managed_dispatch_url_request_job.h index c76e943261d..1dff14953bf 100644 --- a/chromium/headless/public/util/managed_dispatch_url_request_job.h +++ b/chromium/headless/public/util/managed_dispatch_url_request_job.h @@ -6,6 +6,7 @@ #define HEADLESS_PUBLIC_UTIL_MANAGED_DISPATCH_URL_REQUEST_JOB_H_ #include "base/macros.h" +#include "base/memory/weak_ptr.h" #include "headless/public/headless_export.h" #include "net/base/net_errors.h" #include "net/url_request/url_request.h" @@ -35,6 +36,10 @@ class HEADLESS_EXPORT ManagedDispatchURLRequestJob : public net::URLRequestJob { // Virtual for FakeManagedDispatchURLRequestJob. virtual void OnStartError(net::Error error); + base::WeakPtr<ManagedDispatchURLRequestJob> GetWeakPtr() { + return weak_ptr_factory_.GetWeakPtr(); + } + protected: // net::URLRequestJob implementation: void Kill() override; @@ -54,6 +59,8 @@ class HEADLESS_EXPORT ManagedDispatchURLRequestJob : public net::URLRequestJob { using URLRequestJob::NotifyHeadersComplete; using URLRequestJob::NotifyStartError; + base::WeakPtrFactory<ManagedDispatchURLRequestJob> weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(ManagedDispatchURLRequestJob); }; diff --git a/chromium/headless/public/util/testing/generic_url_request_mocks.cc b/chromium/headless/public/util/testing/generic_url_request_mocks.cc index 9c20668d5d9..7d4d2e79afe 100644 --- a/chromium/headless/public/util/testing/generic_url_request_mocks.cc +++ b/chromium/headless/public/util/testing/generic_url_request_mocks.cc @@ -50,7 +50,7 @@ void MockCookieStore::SetCanonicalCookieAsync( bool secure_source, bool can_modify_httponly, SetCookiesCallback callback) { - CHECK(false); + cookies_.push_back(std::move(*cookie)); } void MockCookieStore::GetCookiesWithOptionsAsync( diff --git a/chromium/headless/public/util/testing/test_in_memory_protocol_handler.cc b/chromium/headless/public/util/testing/test_in_memory_protocol_handler.cc index 8883fb1d107..769ee3f31b7 100644 --- a/chromium/headless/public/util/testing/test_in_memory_protocol_handler.cc +++ b/chromium/headless/public/util/testing/test_in_memory_protocol_handler.cc @@ -4,7 +4,8 @@ #include "headless/public/util/testing/test_in_memory_protocol_handler.h" -#include "base/memory/ptr_util.h" +#include <memory> + #include "headless/public/util/expedited_dispatcher.h" #include "headless/public/util/generic_url_request_job.h" #include "headless/public/util/url_fetcher.h" @@ -21,10 +22,20 @@ class TestInMemoryProtocolHandler::MockURLFetcher : public URLFetcher { void StartFetch(const Request* request, ResultListener* result_listener) override { GURL url = request->GetURLRequest()->url(); - DCHECK_EQ("GET", request->GetURLRequest()->method()); + const std::string& method = request->GetURLRequest()->method(); + if (method == "POST" || method == "PUT") { + request->GetPostData(); + } else if (method == "GET") { + // Do nothing. + } else { + DCHECK(false) << "Method " << method << " is not supported. Probably."; + } std::string devtools_frame_id = request->GetDevToolsFrameId(); - DCHECK_NE(devtools_frame_id, "") << " For url " << url; + // Note |devtools_frame_id| can sometimes be empty if called during context + // shutdown. This isn't a big deal because code should avoid performing net + // operations during shutdown. + protocol_handler_->methods_requested_.push_back(method); protocol_handler_->RegisterUrl(url.spec(), devtools_frame_id); if (protocol_handler_->request_deferrer()) { @@ -113,7 +124,7 @@ net::URLRequestJob* TestInMemoryProtocolHandler::MaybeCreateJob( net::NetworkDelegate* network_delegate) const { return new GenericURLRequestJob( request, network_delegate, dispatcher_.get(), - base::MakeUnique<MockURLFetcher>( + std::make_unique<MockURLFetcher>( const_cast<TestInMemoryProtocolHandler*>(this)), test_delegate_.get(), headless_browser_context_); } diff --git a/chromium/headless/public/util/testing/test_in_memory_protocol_handler.h b/chromium/headless/public/util/testing/test_in_memory_protocol_handler.h index b3265725097..92a7fa256c6 100644 --- a/chromium/headless/public/util/testing/test_in_memory_protocol_handler.h +++ b/chromium/headless/public/util/testing/test_in_memory_protocol_handler.h @@ -65,6 +65,10 @@ class TestInMemoryProtocolHandler return urls_requested_; } + const std::vector<std::string>& methods_requested() const { + return methods_requested_; + } + private: const Response* GetResponse(const std::string& url) const; @@ -86,6 +90,7 @@ class TestInMemoryProtocolHandler HeadlessBrowserContext* headless_browser_context_; std::map<std::string, std::string> url_to_devtools_frame_id_; std::vector<std::string> urls_requested_; + std::vector<std::string> methods_requested_; RequestDeferrer* request_deferrer_; // NOT OWNED. scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner_; diff --git a/chromium/headless/public/util/throttled_dispatcher.cc b/chromium/headless/public/util/throttled_dispatcher.cc index 0e767605568..2ce0a9d532a 100644 --- a/chromium/headless/public/util/throttled_dispatcher.cc +++ b/chromium/headless/public/util/throttled_dispatcher.cc @@ -30,7 +30,7 @@ void ThrottledDispatcher::ResumeRequests() { for (ManagedDispatchURLRequestJob* job : paused_jobs_) { io_thread_task_runner_->PostTask( FROM_HERE, base::Bind(&ManagedDispatchURLRequestJob::OnHeadersComplete, - base::Unretained(job))); + job->GetWeakPtr())); } paused_jobs_.clear(); } @@ -42,7 +42,7 @@ void ThrottledDispatcher::DataReady(ManagedDispatchURLRequestJob* job) { } else { io_thread_task_runner_->PostTask( FROM_HERE, base::Bind(&ManagedDispatchURLRequestJob::OnHeadersComplete, - base::Unretained(job))); + job->GetWeakPtr())); } } diff --git a/chromium/headless/public/util/virtual_time_controller_test.cc b/chromium/headless/public/util/virtual_time_controller_test.cc index 483a99bc21a..33fcccc4e9f 100644 --- a/chromium/headless/public/util/virtual_time_controller_test.cc +++ b/chromium/headless/public/util/virtual_time_controller_test.cc @@ -4,8 +4,9 @@ #include "headless/public/util/virtual_time_controller.h" +#include <memory> + #include "base/bind.h" -#include "base/memory/ptr_util.h" #include "base/memory/ref_counted.h" #include "base/strings/stringprintf.h" #include "base/test/test_simple_task_runner.h" @@ -31,7 +32,7 @@ class VirtualTimeControllerTest : public ::testing::Test { EXPECT_CALL(*mock_host_, IsAttached()).WillOnce(Return(false)); EXPECT_CALL(*mock_host_, AttachClient(&client_)); client_.AttachToHost(mock_host_.get()); - controller_ = base::MakeUnique<VirtualTimeController>(&client_, 0); + controller_ = std::make_unique<VirtualTimeController>(&client_, 0); } ~VirtualTimeControllerTest() override = default; @@ -78,7 +79,7 @@ class VirtualTimeControllerTest : public ::testing::Test { }; TEST_F(VirtualTimeControllerTest, AdvancesTimeWithoutTasks) { - controller_ = base::MakeUnique<VirtualTimeController>(&client_, 1000); + controller_ = std::make_unique<VirtualTimeController>(&client_, 1000); EXPECT_CALL(*mock_host_, DispatchProtocolMessage( |