| Index: headless/lib/browser/headless_devtools_manager_delegate.cc
|
| diff --git a/headless/lib/browser/headless_devtools_manager_delegate.cc b/headless/lib/browser/headless_devtools_manager_delegate.cc
|
| index 77c7e54c02fdf90565c9929d7ff8609ed891df1f..1be2c696618d3b67b18d6e7e8c2820e3a2a59b2f 100644
|
| --- a/headless/lib/browser/headless_devtools_manager_delegate.cc
|
| +++ b/headless/lib/browser/headless_devtools_manager_delegate.cc
|
| @@ -10,6 +10,7 @@
|
| #include "content/public/browser/browser_thread.h"
|
| #include "content/public/browser/devtools_agent_host.h"
|
| #include "content/public/browser/devtools_frontend_host.h"
|
| +#include "content/public/browser/render_widget_host_view.h"
|
| #include "content/public/browser/web_contents.h"
|
| #include "headless/grit/headless_lib_resources.h"
|
| #include "headless/lib/browser/headless_browser_context_impl.h"
|
| @@ -68,6 +69,19 @@ std::unique_ptr<base::DictionaryValue> CreateInvalidParamResponse(
|
| base::StringPrintf("Missing or invalid '%s' parameter", param.c_str()));
|
| }
|
|
|
| +std::unique_ptr<base::DictionaryValue> CreateBoundsDict(
|
| + const HeadlessWebContentsImpl* web_contents) {
|
| + auto bounds_object = base::MakeUnique<base::DictionaryValue>();
|
| + gfx::Rect bounds =
|
| + web_contents->web_contents()->GetRenderWidgetHostView()->GetViewBounds();
|
| + bounds_object->SetInteger("left", bounds.x());
|
| + bounds_object->SetInteger("top", bounds.y());
|
| + bounds_object->SetInteger("width", bounds.width());
|
| + bounds_object->SetInteger("height", bounds.height());
|
| + bounds_object->SetString("windowState", web_contents->window_state());
|
| + return bounds_object;
|
| +}
|
| +
|
| #if BUILDFLAG(ENABLE_BASIC_PRINTING)
|
| void PDFCreated(
|
| const content::DevToolsManagerDelegate::CommandCallback& callback,
|
| @@ -169,6 +183,15 @@ HeadlessDevToolsManagerDelegate::HeadlessDevToolsManagerDelegate(
|
| command_map_["Target.disposeBrowserContext"] =
|
| base::Bind(&HeadlessDevToolsManagerDelegate::DisposeBrowserContext,
|
| base::Unretained(this));
|
| + command_map_["Browser.getWindowForTarget"] =
|
| + base::Bind(&HeadlessDevToolsManagerDelegate::GetWindowForTarget,
|
| + base::Unretained(this));
|
| + command_map_["Browser.getWindowBounds"] =
|
| + base::Bind(&HeadlessDevToolsManagerDelegate::GetWindowBounds,
|
| + base::Unretained(this));
|
| + command_map_["Browser.setWindowBounds"] =
|
| + base::Bind(&HeadlessDevToolsManagerDelegate::SetWindowBounds,
|
| + base::Unretained(this));
|
|
|
| async_command_map_["Page.printToPDF"] = base::Bind(
|
| &HeadlessDevToolsManagerDelegate::PrintToPDF, base::Unretained(this));
|
| @@ -193,6 +216,11 @@ base::DictionaryValue* HeadlessDevToolsManagerDelegate::HandleCommand(
|
| if (find_it == command_map_.end())
|
| return nullptr;
|
|
|
| + // Handle Browser domain commands only from Browser DevToolsAgentHost.
|
| + if (method.find("Browser.") == 0 &&
|
| + agent_host->GetType() != content::DevToolsAgentHost::kTypeBrowser)
|
| + return nullptr;
|
| +
|
| const base::DictionaryValue* params = nullptr;
|
| command->GetDictionary("params", ¶ms);
|
| auto cmd_result = find_it->second.Run(id, params);
|
| @@ -378,4 +406,116 @@ HeadlessDevToolsManagerDelegate::DisposeBrowserContext(
|
| return CreateSuccessResponse(command_id, std::move(result));
|
| }
|
|
|
| +std::unique_ptr<base::DictionaryValue>
|
| +HeadlessDevToolsManagerDelegate::GetWindowForTarget(
|
| + int command_id,
|
| + const base::DictionaryValue* params) {
|
| + std::string target_id;
|
| + if (!params->GetString("targetId", &target_id))
|
| + return CreateInvalidParamResponse(command_id, "targetId");
|
| +
|
| + HeadlessWebContentsImpl* web_contents = HeadlessWebContentsImpl::From(
|
| + browser_->GetWebContentsForDevToolsAgentHostId(target_id));
|
| + if (!web_contents) {
|
| + return CreateErrorResponse(command_id, kErrorServerError,
|
| + "No web contents for the given target id");
|
| + }
|
| +
|
| + auto result = base::MakeUnique<base::DictionaryValue>();
|
| + result->SetInteger("windowId", web_contents->window_id());
|
| + result->Set("bounds", CreateBoundsDict(web_contents));
|
| + return CreateSuccessResponse(command_id, std::move(result));
|
| +}
|
| +
|
| +std::unique_ptr<base::DictionaryValue>
|
| +HeadlessDevToolsManagerDelegate::GetWindowBounds(
|
| + int command_id,
|
| + const base::DictionaryValue* params) {
|
| + int window_id;
|
| + if (!params->GetInteger("windowId", &window_id))
|
| + return CreateInvalidParamResponse(command_id, "windowId");
|
| + HeadlessWebContentsImpl* web_contents =
|
| + browser_->GetWebContentsForWindowId(window_id);
|
| + if (!web_contents) {
|
| + return CreateErrorResponse(command_id, kErrorServerError,
|
| + "Browser window not found");
|
| + }
|
| +
|
| + auto result = base::MakeUnique<base::DictionaryValue>();
|
| + result->Set("bounds", CreateBoundsDict(web_contents));
|
| + return CreateSuccessResponse(command_id, std::move(result));
|
| +}
|
| +
|
| +std::unique_ptr<base::DictionaryValue>
|
| +HeadlessDevToolsManagerDelegate::SetWindowBounds(
|
| + int command_id,
|
| + const base::DictionaryValue* params) {
|
| + int window_id;
|
| + if (!params->GetInteger("windowId", &window_id))
|
| + return CreateInvalidParamResponse(command_id, "windowId");
|
| + HeadlessWebContentsImpl* web_contents =
|
| + browser_->GetWebContentsForWindowId(window_id);
|
| + if (!web_contents) {
|
| + return CreateErrorResponse(command_id, kErrorServerError,
|
| + "Browser window not found");
|
| + }
|
| +
|
| + const base::Value* value = nullptr;
|
| + const base::DictionaryValue* bounds_dict = nullptr;
|
| + if (!params->Get("bounds", &value) || !value->GetAsDictionary(&bounds_dict))
|
| + return CreateInvalidParamResponse(command_id, "bounds");
|
| +
|
| + std::string window_state;
|
| + if (!bounds_dict->GetString("windowState", &window_state)) {
|
| + window_state = "normal";
|
| + } else if (window_state != "normal" && window_state != "minimized" &&
|
| + window_state != "maximized" && window_state != "fullscreen") {
|
| + return CreateInvalidParamResponse(command_id, "windowState");
|
| + }
|
| +
|
| + // Compute updated bounds when window state is normal.
|
| + bool set_bounds = false;
|
| + gfx::Rect bounds =
|
| + web_contents->web_contents()->GetRenderWidgetHostView()->GetViewBounds();
|
| + int left, top, width, height;
|
| + if (bounds_dict->GetInteger("left", &left)) {
|
| + bounds.set_x(left);
|
| + set_bounds = true;
|
| + }
|
| + if (bounds_dict->GetInteger("top", &top)) {
|
| + bounds.set_y(top);
|
| + set_bounds = true;
|
| + }
|
| + if (bounds_dict->GetInteger("width", &width)) {
|
| + if (width < 0)
|
| + return CreateInvalidParamResponse(command_id, "width");
|
| + bounds.set_width(width);
|
| + set_bounds = true;
|
| + }
|
| + if (bounds_dict->GetInteger("height", &height)) {
|
| + if (height < 0)
|
| + return CreateInvalidParamResponse(command_id, "height");
|
| + bounds.set_height(height);
|
| + set_bounds = true;
|
| + }
|
| +
|
| + if (set_bounds && window_state != "normal") {
|
| + return CreateErrorResponse(
|
| + command_id, kErrorServerError,
|
| + "The 'minimized', 'maximized' and 'fullscreen' states cannot be "
|
| + "combined with 'left', 'top', 'width' or 'height'");
|
| + }
|
| +
|
| + if (set_bounds && web_contents->window_state() != "normal") {
|
| + return CreateErrorResponse(
|
| + command_id, kErrorServerError,
|
| + "To resize minimized/maximized/fullscreen window, restore it to normal "
|
| + "state first.");
|
| + }
|
| +
|
| + web_contents->set_window_state(window_state);
|
| + web_contents->web_contents()->GetRenderWidgetHostView()->SetBounds(bounds);
|
| + return CreateSuccessResponse(command_id, nullptr);
|
| +}
|
| +
|
| } // namespace headless
|
|
|