Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Side by Side Diff: headless/lib/browser/headless_devtools_manager_delegate.cc

Issue 2780433002: add print to pdf for headless (Closed)
Patch Set: improve comments as suggested Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "headless/lib/browser/headless_devtools_manager_delegate.h" 5 #include "headless/lib/browser/headless_devtools_manager_delegate.h"
6 6
7 #include <string> 7 #include <string>
8 #include <utility> 8 #include <utility>
9 9
10 #include "content/public/browser/browser_thread.h" 10 #include "content/public/browser/browser_thread.h"
11 #include "content/public/browser/devtools_agent_host.h" 11 #include "content/public/browser/devtools_agent_host.h"
12 #include "content/public/browser/devtools_frontend_host.h" 12 #include "content/public/browser/devtools_frontend_host.h"
13 #include "content/public/browser/web_contents.h" 13 #include "content/public/browser/web_contents.h"
14 #include "headless/grit/headless_lib_resources.h" 14 #include "headless/grit/headless_lib_resources.h"
15 #include "headless/lib/browser/headless_browser_context_impl.h" 15 #include "headless/lib/browser/headless_browser_context_impl.h"
16 #include "headless/lib/browser/headless_browser_impl.h" 16 #include "headless/lib/browser/headless_browser_impl.h"
17 #include "headless/lib/browser/headless_print_manager.h"
17 #include "headless/lib/browser/headless_web_contents_impl.h" 18 #include "headless/lib/browser/headless_web_contents_impl.h"
18 #include "headless/public/devtools/domains/target.h" 19 #include "headless/public/devtools/domains/target.h"
19 #include "ui/base/resource/resource_bundle.h" 20 #include "ui/base/resource/resource_bundle.h"
20 21
21 namespace headless { 22 namespace headless {
22 23
23 namespace { 24 namespace {
24 const char kIdParam[] = "id"; 25 const char kIdParam[] = "id";
25 const char kResultParam[] = "result"; 26 const char kResultParam[] = "result";
26 const char kErrorParam[] = "error"; 27 const char kErrorParam[] = "error";
27 const char kErrorCodeParam[] = "code"; 28 const char kErrorCodeParam[] = "code";
28 const char kErrorMessageParam[] = "message"; 29 const char kErrorMessageParam[] = "message";
29 30
30 // JSON RPC 2.0 spec: http://www.jsonrpc.org/specification#error_object 31 // JSON RPC 2.0 spec: http://www.jsonrpc.org/specification#error_object
31 enum Error { 32 enum Error {
32 kErrorInvalidParam = -32602, 33 kErrorInvalidParam = -32602,
33 kErrorServerError = -32000 34 kErrorServerError = -32000
34 }; 35 };
35 36
36 std::unique_ptr<base::DictionaryValue> CreateSuccessResponse( 37 std::unique_ptr<base::DictionaryValue> CreateSuccessResponse(
37 int command_id, 38 int command_id,
38 std::unique_ptr<base::Value> result) { 39 std::unique_ptr<base::Value> result) {
39 if (!result) 40 if (!result)
40 result.reset(new base::DictionaryValue()); 41 result = base::MakeUnique<base::DictionaryValue>();
41 42
42 std::unique_ptr<base::DictionaryValue> response(new base::DictionaryValue()); 43 auto response = base::MakeUnique<base::DictionaryValue>();
43 response->SetInteger(kIdParam, command_id); 44 response->SetInteger(kIdParam, command_id);
44 response->Set(kResultParam, std::move(result)); 45 response->Set(kResultParam, std::move(result));
45 return response; 46 return response;
46 } 47 }
47 48
48 std::unique_ptr<base::DictionaryValue> CreateErrorResponse( 49 std::unique_ptr<base::DictionaryValue> CreateErrorResponse(
49 int command_id, 50 int command_id,
50 int error_code, 51 int error_code,
51 const std::string& error_message) { 52 const std::string& error_message) {
52 std::unique_ptr<base::DictionaryValue> error_object( 53 auto error_object = base::MakeUnique<base::DictionaryValue>();
53 new base::DictionaryValue());
54 error_object->SetInteger(kErrorCodeParam, error_code); 54 error_object->SetInteger(kErrorCodeParam, error_code);
55 error_object->SetString(kErrorMessageParam, error_message); 55 error_object->SetString(kErrorMessageParam, error_message);
56 56
57 std::unique_ptr<base::DictionaryValue> response(new base::DictionaryValue()); 57 auto response = base::MakeUnique<base::DictionaryValue>();
58 response->SetInteger(kIdParam, command_id);
58 response->Set(kErrorParam, std::move(error_object)); 59 response->Set(kErrorParam, std::move(error_object));
59 return response; 60 return response;
60 } 61 }
61 62
62 std::unique_ptr<base::DictionaryValue> CreateInvalidParamResponse( 63 std::unique_ptr<base::DictionaryValue> CreateInvalidParamResponse(
63 int command_id, 64 int command_id,
64 const std::string& param) { 65 const std::string& param) {
65 return CreateErrorResponse( 66 return CreateErrorResponse(
66 command_id, kErrorInvalidParam, 67 command_id, kErrorInvalidParam,
67 base::StringPrintf("Missing or invalid '%s' parameter", param.c_str())); 68 base::StringPrintf("Missing or invalid '%s' parameter", param.c_str()));
68 } 69 }
70
71 void PDFCreated(
72 const content::DevToolsManagerDelegate::CommandCallback& callback,
73 int command_id,
74 printing::HeadlessPrintManager::PrintResult print_result,
75 const std::string& data) {
76 std::unique_ptr<base::DictionaryValue> response;
77 if (print_result == printing::HeadlessPrintManager::PRINT_SUCCESS) {
78 response = CreateSuccessResponse(
79 command_id,
80 printing::HeadlessPrintManager::PDFContentsToDictionaryValue(data));
81 } else {
82 response = CreateErrorResponse(
83 command_id, kErrorServerError,
84 printing::HeadlessPrintManager::PrintResultToString(print_result));
85 }
86 callback.Run(std::move(response));
87 }
88
69 } // namespace 89 } // namespace
70 90
71 HeadlessDevToolsManagerDelegate::HeadlessDevToolsManagerDelegate( 91 HeadlessDevToolsManagerDelegate::HeadlessDevToolsManagerDelegate(
72 base::WeakPtr<HeadlessBrowserImpl> browser) 92 base::WeakPtr<HeadlessBrowserImpl> browser)
73 : browser_(std::move(browser)) { 93 : browser_(std::move(browser)) {
74 command_map_["Target.createTarget"] = base::Bind( 94 command_map_["Target.createTarget"] = base::Bind(
75 &HeadlessDevToolsManagerDelegate::CreateTarget, base::Unretained(this)); 95 &HeadlessDevToolsManagerDelegate::CreateTarget, base::Unretained(this));
76 command_map_["Target.closeTarget"] = base::Bind( 96 command_map_["Target.closeTarget"] = base::Bind(
77 &HeadlessDevToolsManagerDelegate::CloseTarget, base::Unretained(this)); 97 &HeadlessDevToolsManagerDelegate::CloseTarget, base::Unretained(this));
78 command_map_["Target.createBrowserContext"] = 98 command_map_["Target.createBrowserContext"] =
79 base::Bind(&HeadlessDevToolsManagerDelegate::CreateBrowserContext, 99 base::Bind(&HeadlessDevToolsManagerDelegate::CreateBrowserContext,
80 base::Unretained(this)); 100 base::Unretained(this));
81 command_map_["Target.disposeBrowserContext"] = 101 command_map_["Target.disposeBrowserContext"] =
82 base::Bind(&HeadlessDevToolsManagerDelegate::DisposeBrowserContext, 102 base::Bind(&HeadlessDevToolsManagerDelegate::DisposeBrowserContext,
83 base::Unretained(this)); 103 base::Unretained(this));
104
105 async_command_map_["Page.printToPDF"] = base::Bind(
106 &HeadlessDevToolsManagerDelegate::PrintToPDF, base::Unretained(this));
84 } 107 }
85 108
86 HeadlessDevToolsManagerDelegate::~HeadlessDevToolsManagerDelegate() {} 109 HeadlessDevToolsManagerDelegate::~HeadlessDevToolsManagerDelegate() {}
87 110
88 base::DictionaryValue* HeadlessDevToolsManagerDelegate::HandleCommand( 111 base::DictionaryValue* HeadlessDevToolsManagerDelegate::HandleCommand(
89 content::DevToolsAgentHost* agent_host, 112 content::DevToolsAgentHost* agent_host,
90 base::DictionaryValue* command) { 113 base::DictionaryValue* command) {
91 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 114 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
92 115
93 if (!browser_) 116 if (!browser_)
94 return nullptr; 117 return nullptr;
95 118
96 int id; 119 int id;
97 std::string method; 120 std::string method;
98 if (!command->GetInteger("id", &id) || !command->GetString("method", &method)) 121 if (!command->GetInteger("id", &id) || !command->GetString("method", &method))
99 return nullptr; 122 return nullptr;
100 123
101 auto find_it = command_map_.find(method); 124 auto find_it = command_map_.find(method);
102 if (find_it == command_map_.end()) 125 if (find_it == command_map_.end())
103 return nullptr; 126 return nullptr;
104 127
105 const base::DictionaryValue* params = nullptr; 128 const base::DictionaryValue* params = nullptr;
106 command->GetDictionary("params", &params); 129 command->GetDictionary("params", &params);
107 auto cmd_result = find_it->second.Run(id, params); 130 auto cmd_result = find_it->second.Run(id, params);
108 return cmd_result.release(); 131 return cmd_result.release();
109 } 132 }
110 133
134 bool HeadlessDevToolsManagerDelegate::HandleAsyncCommand(
135 content::DevToolsAgentHost* agent_host,
136 base::DictionaryValue* command,
137 const CommandCallback& callback) {
138 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
139
140 if (!browser_)
141 return false;
142
143 int id;
144 std::string method;
145 if (!command->GetInteger("id", &id) || !command->GetString("method", &method))
146 return false;
147
148 auto find_it = async_command_map_.find(method);
149 if (find_it == async_command_map_.end())
150 return false;
151
152 const base::DictionaryValue* params = nullptr;
153 command->GetDictionary("params", &params);
154 find_it->second.Run(agent_host, id, params, callback);
155 return true;
156 }
157
111 scoped_refptr<content::DevToolsAgentHost> 158 scoped_refptr<content::DevToolsAgentHost>
112 HeadlessDevToolsManagerDelegate::CreateNewTarget(const GURL& url) { 159 HeadlessDevToolsManagerDelegate::CreateNewTarget(const GURL& url) {
113 HeadlessBrowserContext* context = browser_->GetDefaultBrowserContext(); 160 HeadlessBrowserContext* context = browser_->GetDefaultBrowserContext();
114 HeadlessWebContentsImpl* web_contents_impl = HeadlessWebContentsImpl::From( 161 HeadlessWebContentsImpl* web_contents_impl = HeadlessWebContentsImpl::From(
115 context->CreateWebContentsBuilder() 162 context->CreateWebContentsBuilder()
116 .SetInitialURL(url) 163 .SetInitialURL(url)
117 .SetWindowSize(browser_->options()->window_size) 164 .SetWindowSize(browser_->options()->window_size)
118 .Build()); 165 .Build());
119 return content::DevToolsAgentHost::GetOrCreateFor( 166 return content::DevToolsAgentHost::GetOrCreateFor(
120 web_contents_impl->web_contents()); 167 web_contents_impl->web_contents());
121 } 168 }
122 169
123 std::string HeadlessDevToolsManagerDelegate::GetDiscoveryPageHTML() { 170 std::string HeadlessDevToolsManagerDelegate::GetDiscoveryPageHTML() {
124 return ResourceBundle::GetSharedInstance() 171 return ResourceBundle::GetSharedInstance()
125 .GetRawDataResource(IDR_HEADLESS_LIB_DEVTOOLS_DISCOVERY_PAGE) 172 .GetRawDataResource(IDR_HEADLESS_LIB_DEVTOOLS_DISCOVERY_PAGE)
126 .as_string(); 173 .as_string();
127 } 174 }
128 175
129 std::string HeadlessDevToolsManagerDelegate::GetFrontendResource( 176 std::string HeadlessDevToolsManagerDelegate::GetFrontendResource(
130 const std::string& path) { 177 const std::string& path) {
131 return content::DevToolsFrontendHost::GetFrontendResource(path).as_string(); 178 return content::DevToolsFrontendHost::GetFrontendResource(path).as_string();
132 } 179 }
133 180
181 void HeadlessDevToolsManagerDelegate::PrintToPDF(
182 content::DevToolsAgentHost* agent_host,
183 int command_id,
184 const base::DictionaryValue* params,
185 const CommandCallback& callback) {
186 content::WebContents* web_contents = agent_host->GetWebContents();
187 content::RenderFrameHost* rfh = web_contents->GetMainFrame();
188
189 printing::HeadlessPrintManager::FromWebContents(web_contents)
190 ->GetPDFContents(rfh, base::Bind(&PDFCreated, callback, command_id));
191 }
192
134 std::unique_ptr<base::DictionaryValue> 193 std::unique_ptr<base::DictionaryValue>
135 HeadlessDevToolsManagerDelegate::CreateTarget( 194 HeadlessDevToolsManagerDelegate::CreateTarget(
136 int command_id, 195 int command_id,
137 const base::DictionaryValue* params) { 196 const base::DictionaryValue* params) {
138 std::string url; 197 std::string url;
139 std::string browser_context_id; 198 std::string browser_context_id;
140 int width = browser_->options()->window_size.width(); 199 int width = browser_->options()->window_size.width();
141 int height = browser_->options()->window_size.height(); 200 int height = browser_->options()->window_size.height();
142 if (!params || !params->GetString("url", &url)) 201 if (!params || !params->GetString("url", &url))
143 return CreateInvalidParamResponse(command_id, "url"); 202 return CreateInvalidParamResponse(command_id, "url");
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 289
231 std::unique_ptr<base::Value> result( 290 std::unique_ptr<base::Value> result(
232 target::DisposeBrowserContextResult::Builder() 291 target::DisposeBrowserContextResult::Builder()
233 .SetSuccess(success) 292 .SetSuccess(success)
234 .Build() 293 .Build()
235 ->Serialize()); 294 ->Serialize());
236 return CreateSuccessResponse(command_id, std::move(result)); 295 return CreateSuccessResponse(command_id, std::move(result));
237 } 296 }
238 297
239 } // namespace headless 298 } // namespace headless
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698