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

Side by Side Diff: chrome/renderer/automation/automation_renderer_helper.cc

Issue 14977013: Delete Automation[Tab/Renderer]Helper and users. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: update now that 202087 is committed Created 7 years, 7 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/renderer/automation/automation_renderer_helper.h"
6
7 #include <algorithm>
8
9 #include "base/basictypes.h"
10 #include "base/json/json_writer.h"
11 #include "base/stringprintf.h"
12 #include "base/strings/string_split.h"
13 #include "base/utf_string_conversions.h"
14 #include "base/values.h"
15 #include "chrome/common/automation_events.h"
16 #include "chrome/common/automation_messages.h"
17 #include "content/public/renderer/render_view.h"
18 #include "content/public/renderer/v8_value_converter.h"
19 #include "ipc/ipc_channel.h"
20 #include "ipc/ipc_message.h"
21 #include "skia/ext/platform_canvas.h"
22 #include "third_party/WebKit/Source/Platform/chromium/public/WebSize.h"
23 #include "third_party/WebKit/Source/Platform/chromium/public/WebURL.h"
24 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
25 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScriptSource.h"
27 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
28 #include "ui/gfx/codec/png_codec.h"
29 #include "ui/gfx/point.h"
30 #include "ui/gfx/rect.h"
31 #include "v8/include/v8.h"
32 #include "webkit/glue/webkit_glue.h"
33
34 #if !defined(NO_TCMALLOC) && (defined(OS_LINUX) || defined(OS_CHROMEOS))
35 #include "third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h"
36 #endif // !defined(NO_TCMALLOC) && (defined(OS_LINUX) || defined(OS_CHROMEOS))
37
38 using WebKit::WebFrame;
39 using WebKit::WebSize;
40 using WebKit::WebURL;
41 using WebKit::WebView;
42
43 AutomationRendererHelper::AutomationRendererHelper(
44 content::RenderView* render_view)
45 : content::RenderViewObserver(render_view) {
46 }
47
48 AutomationRendererHelper::~AutomationRendererHelper() { }
49
50 bool AutomationRendererHelper::SnapshotEntirePage(
51 WebView* view,
52 std::vector<unsigned char>* png_data,
53 std::string* error_msg) {
54 WebFrame* frame = view->mainFrame();
55 WebSize old_size = view->size();
56 WebSize new_size = frame->contentsSize();
57 WebSize old_scroll = frame->scrollOffset();
58 bool fixed_layout_enabled = view->isFixedLayoutModeEnabled();
59 WebSize fixed_size = view->fixedLayoutSize();
60
61 frame->setCanHaveScrollbars(false);
62 view->setFixedLayoutSize(old_size);
63 view->enableFixedLayoutMode(true);
64 view->resize(new_size);
65 view->layout();
66 frame->setScrollOffset(frame->minimumScrollOffset());
67
68 skia::RefPtr<SkCanvas> canvas = skia::AdoptRef(
69 skia::CreatePlatformCanvas(new_size.width, new_size.height, true));
70
71 view->paint(webkit_glue::ToWebCanvas(canvas.get()),
72 gfx::Rect(0, 0, new_size.width, new_size.height));
73
74 frame->setCanHaveScrollbars(true);
75 view->setFixedLayoutSize(fixed_size);
76 view->enableFixedLayoutMode(fixed_layout_enabled);
77 view->resize(old_size);
78 view->layout();
79 frame->setScrollOffset(old_scroll);
80
81 const SkBitmap& bmp = skia::GetTopDevice(*canvas)->accessBitmap(false);
82 SkAutoLockPixels lock_pixels(bmp);
83 // EncodeBGRA uses FORMAT_SkBitmap, which doesn't work on windows for some
84 // cases dealing with transparency. See crbug.com/96317. Use FORMAT_BGRA.
85 bool encode_success = gfx::PNGCodec::Encode(
86 reinterpret_cast<unsigned char*>(bmp.getPixels()),
87 gfx::PNGCodec::FORMAT_BGRA,
88 gfx::Size(bmp.width(), bmp.height()),
89 bmp.rowBytes(),
90 true, // discard_transparency
91 std::vector<gfx::PNGCodec::Comment>(),
92 png_data);
93 if (!encode_success)
94 *error_msg = "failed to encode image as png";
95 return encode_success;
96 }
97
98 void AutomationRendererHelper::OnSnapshotEntirePage() {
99 std::vector<unsigned char> png_data;
100 std::string error_msg;
101 bool success = false;
102 if (render_view()->GetWebView()) {
103 success = SnapshotEntirePage(
104 render_view()->GetWebView(), &png_data, &error_msg);
105 } else {
106 error_msg = "cannot snapshot page because webview is null";
107 }
108
109 // Check that the image is not too large, allowing a 1kb buffer for other
110 // message data.
111 if (success && png_data.size() > IPC::Channel::kMaximumMessageSize - 1024) {
112 png_data.clear();
113 success = false;
114 error_msg = "image is too large to be transferred over ipc";
115 }
116 Send(new AutomationMsg_SnapshotEntirePageACK(
117 routing_id(), success, png_data, error_msg));
118 }
119
120 namespace {
121
122 scoped_ptr<base::Value> EvaluateScriptInFrame(WebFrame* web_frame,
123 const std::string& script) {
124 v8::HandleScope handle_scope;
125 v8::Local<v8::Value> result = v8::Local<v8::Value>::New(
126 web_frame->executeScriptAndReturnValue(
127 WebKit::WebScriptSource(UTF8ToUTF16(script))));
128 if (!result.IsEmpty()) {
129 v8::Local<v8::Context> context = web_frame->mainWorldScriptContext();
130 v8::Context::Scope context_scope(context);
131 scoped_ptr<content::V8ValueConverter> converter(
132 content::V8ValueConverter::create());
133 return scoped_ptr<base::Value>(converter->FromV8Value(result, context));
134 } else {
135 return scoped_ptr<base::Value>(base::Value::CreateNullValue());
136 }
137 }
138
139 WebFrame* FrameFromXPath(WebView* view, const string16& frame_xpath) {
140 WebFrame* frame = view->mainFrame();
141 if (frame_xpath.empty())
142 return frame;
143
144 std::vector<string16> xpaths;
145 base::SplitString(frame_xpath, '\n', &xpaths);
146 for (std::vector<string16>::const_iterator i = xpaths.begin();
147 frame && i != xpaths.end(); ++i) {
148 frame = frame->findChildByExpression(*i);
149 }
150 return frame;
151 }
152
153 bool EvaluateScriptChainHelper(
154 WebView* web_view,
155 const std::string& script,
156 const std::string& frame_xpath,
157 scoped_ptr<base::DictionaryValue>* result,
158 std::string* error_msg) {
159 WebFrame* web_frame = FrameFromXPath(web_view, UTF8ToUTF16(frame_xpath));
160 if (!web_frame) {
161 *error_msg = "Failed to locate frame by xpath: " + frame_xpath;
162 return false;
163 }
164 scoped_ptr<base::Value> script_value =
165 EvaluateScriptInFrame(web_frame, script);
166 base::DictionaryValue* dict;
167 if (!script_value.get() || !script_value->GetAsDictionary(&dict)) {
168 *error_msg = "Script did not return an object";
169 return false;
170 }
171 base::Value* error_value;
172 if (dict->Get("error", &error_value)) {
173 base::JSONWriter::Write(error_value, error_msg);
174 return false;
175 }
176 result->reset(static_cast<base::DictionaryValue*>(script_value.release()));
177 return true;
178 }
179
180 } // namespace
181
182 bool AutomationRendererHelper::EvaluateScriptChain(
183 const std::vector<ScriptEvaluationRequest>& script_chain,
184 scoped_ptr<base::DictionaryValue>* result,
185 std::string* error_msg) {
186 CHECK(!script_chain.empty());
187 WebView* web_view = render_view()->GetWebView();
188 scoped_ptr<base::DictionaryValue> temp_result;
189 for (size_t i = 0; i < script_chain.size(); ++i) {
190 std::string args_utf8 = "null";
191 if (temp_result.get())
192 base::JSONWriter::Write(temp_result.get(), &args_utf8);
193 std::string wrapper_script = base::StringPrintf(
194 "(function(){return %s\n}).apply(null, [%s])",
195 script_chain[i].script.c_str(), args_utf8.c_str());
196 if (!EvaluateScriptChainHelper(web_view, wrapper_script,
197 script_chain[i].frame_xpath,
198 &temp_result, error_msg)) {
199 return false;
200 }
201 }
202 std::string result_str;
203 base::JSONWriter::Write(temp_result.get(), &result_str);
204 result->reset(temp_result.release());
205 return true;
206 }
207
208 bool AutomationRendererHelper::ProcessMouseEvent(
209 const AutomationMouseEvent& event,
210 std::string* error_msg) {
211 WebView* web_view = render_view()->GetWebView();
212 if (!web_view) {
213 *error_msg = "Failed to process mouse event because webview does not exist";
214 return false;
215 }
216 WebKit::WebMouseEvent mouse_event = event.mouse_event;
217 if (!event.location_script_chain.empty()) {
218 scoped_ptr<base::DictionaryValue> result;
219 if (!EvaluateScriptChain(event.location_script_chain, &result, error_msg))
220 return false;
221 int x, y;
222 if (!result->GetInteger("x", &x) ||
223 !result->GetInteger("y", &y)) {
224 *error_msg = "Script did not return an (x,y) location";
225 return false;
226 }
227 mouse_event.x = x;
228 mouse_event.y = y;
229 }
230 Send(new AutomationMsg_WillProcessMouseEventAt(
231 routing_id(),
232 gfx::Point(mouse_event.x, mouse_event.y)));
233 web_view->handleInputEvent(mouse_event);
234 return true;
235 }
236
237 #if !defined(NO_TCMALLOC) && (defined(OS_LINUX) || defined(OS_CHROMEOS))
238 void AutomationRendererHelper::OnHeapProfilerDump(const std::string& reason) {
239 if (!::IsHeapProfilerRunning()) {
240 return;
241 }
242 ::HeapProfilerDump(reason.c_str());
243 }
244 #endif // !defined(NO_TCMALLOC) && (defined(OS_LINUX) || defined(OS_CHROMEOS))
245
246 bool AutomationRendererHelper::OnMessageReceived(const IPC::Message& message) {
247 bool handled = true;
248 bool deserialize_success = true;
249 IPC_BEGIN_MESSAGE_MAP_EX(AutomationRendererHelper, message,
250 deserialize_success)
251 IPC_MESSAGE_HANDLER(AutomationMsg_SnapshotEntirePage, OnSnapshotEntirePage)
252 #if !defined(NO_TCMALLOC) && (defined(OS_LINUX) || defined(OS_CHROMEOS))
253 IPC_MESSAGE_HANDLER(AutomationMsg_HeapProfilerDump, OnHeapProfilerDump)
254 #endif // !defined(NO_TCMALLOC) && (defined(OS_LINUX) || defined(OS_CHROMEOS))
255 IPC_MESSAGE_HANDLER(AutomationMsg_ProcessMouseEvent, OnProcessMouseEvent)
256 IPC_MESSAGE_UNHANDLED(handled = false)
257 IPC_END_MESSAGE_MAP_EX()
258 if (!deserialize_success) {
259 LOG(ERROR) << "Failed to deserialize an IPC message";
260 }
261 return handled;
262 }
263
264 void AutomationRendererHelper::WillPerformClientRedirect(
265 WebFrame* frame, const WebURL& from, const WebURL& to, double interval,
266 double fire_time) {
267 Send(new AutomationMsg_WillPerformClientRedirect(
268 routing_id(), frame->identifier(), interval));
269 }
270
271 void AutomationRendererHelper::DidCancelClientRedirect(WebFrame* frame) {
272 Send(new AutomationMsg_DidCompleteOrCancelClientRedirect(
273 routing_id(), frame->identifier()));
274 }
275
276 void AutomationRendererHelper::DidCompleteClientRedirect(
277 WebFrame* frame, const WebURL& from) {
278 Send(new AutomationMsg_DidCompleteOrCancelClientRedirect(
279 routing_id(), frame->identifier()));
280 }
281
282 void AutomationRendererHelper::OnProcessMouseEvent(
283 const AutomationMouseEvent& event) {
284 std::string error_msg;
285 bool success = ProcessMouseEvent(event, &error_msg);
286 Send(new AutomationMsg_ProcessMouseEventACK(
287 routing_id(), success, error_msg));
288 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698