OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "content/browser/devtools/protocol/page_handler.h" | 5 #include "content/browser/devtools/protocol/page_handler.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/base64.h" | 9 #include "base/base64.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/strings/string16.h" | 11 #include "base/strings/string16.h" |
12 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
13 #include "base/threading/worker_pool.h" | 13 #include "base/threading/worker_pool.h" |
14 #include "content/browser/devtools/protocol/color_picker.h" | 14 #include "content/browser/devtools/protocol/color_picker.h" |
15 #include "content/browser/renderer_host/render_view_host_impl.h" | 15 #include "content/browser/renderer_host/render_widget_host_impl.h" |
16 #include "content/browser/renderer_host/render_widget_host_view_base.h" | 16 #include "content/browser/renderer_host/render_widget_host_view_base.h" |
17 #include "content/browser/web_contents/web_contents_impl.h" | 17 #include "content/browser/web_contents/web_contents_impl.h" |
18 #include "content/common/view_messages.h" | 18 #include "content/common/view_messages.h" |
19 #include "content/public/browser/browser_thread.h" | 19 #include "content/public/browser/browser_thread.h" |
20 #include "content/public/browser/javascript_dialog_manager.h" | 20 #include "content/public/browser/javascript_dialog_manager.h" |
21 #include "content/public/browser/navigation_controller.h" | 21 #include "content/public/browser/navigation_controller.h" |
22 #include "content/public/browser/navigation_entry.h" | 22 #include "content/public/browser/navigation_entry.h" |
| 23 #include "content/public/browser/notification_service.h" |
| 24 #include "content/public/browser/notification_types.h" |
23 #include "content/public/browser/storage_partition.h" | 25 #include "content/public/browser/storage_partition.h" |
24 #include "content/public/browser/web_contents_delegate.h" | 26 #include "content/public/browser/web_contents_delegate.h" |
25 #include "content/public/common/referrer.h" | 27 #include "content/public/common/referrer.h" |
26 #include "third_party/WebKit/public/platform/WebScreenInfo.h" | 28 #include "third_party/WebKit/public/platform/WebScreenInfo.h" |
27 #include "third_party/skia/include/core/SkBitmap.h" | 29 #include "third_party/skia/include/core/SkBitmap.h" |
28 #include "ui/base/page_transition_types.h" | 30 #include "ui/base/page_transition_types.h" |
29 #include "ui/gfx/codec/jpeg_codec.h" | 31 #include "ui/gfx/codec/jpeg_codec.h" |
30 #include "ui/gfx/codec/png_codec.h" | 32 #include "ui/gfx/codec/png_codec.h" |
31 #include "ui/gfx/geometry/size_conversions.h" | 33 #include "ui/gfx/geometry/size_conversions.h" |
32 #include "ui/snapshot/snapshot.h" | 34 #include "ui/snapshot/snapshot.h" |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 color_picker_(new ColorPicker(base::Bind( | 101 color_picker_(new ColorPicker(base::Bind( |
100 &PageHandler::OnColorPicked, base::Unretained(this)))), | 102 &PageHandler::OnColorPicked, base::Unretained(this)))), |
101 host_(nullptr), | 103 host_(nullptr), |
102 screencast_listener_(nullptr), | 104 screencast_listener_(nullptr), |
103 weak_factory_(this) { | 105 weak_factory_(this) { |
104 } | 106 } |
105 | 107 |
106 PageHandler::~PageHandler() { | 108 PageHandler::~PageHandler() { |
107 } | 109 } |
108 | 110 |
109 void PageHandler::SetRenderViewHost(RenderViewHostImpl* host) { | 111 void PageHandler::SetRenderFrameHost(RenderFrameHostImpl* host) { |
110 if (host_ == host) | 112 if (host_ == host) |
111 return; | 113 return; |
112 | 114 |
113 color_picker_->SetRenderViewHost(host); | 115 RenderWidgetHostImpl* widget_host = |
| 116 host_ ? host_->GetRenderWidgetHost() : nullptr; |
| 117 if (widget_host) { |
| 118 registrar_.Remove( |
| 119 this, |
| 120 content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED, |
| 121 content::Source<RenderWidgetHost>(widget_host)); |
| 122 } |
| 123 |
114 host_ = host; | 124 host_ = host; |
| 125 widget_host = host_ ? host_->GetRenderWidgetHost() : nullptr; |
| 126 color_picker_->SetRenderWidgetHost(widget_host); |
| 127 |
| 128 if (widget_host) { |
| 129 registrar_.Add( |
| 130 this, |
| 131 content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED, |
| 132 content::Source<RenderWidgetHost>(widget_host)); |
| 133 } |
115 } | 134 } |
116 | 135 |
117 void PageHandler::SetClient(scoped_ptr<Client> client) { | 136 void PageHandler::SetClient(scoped_ptr<Client> client) { |
118 client_.swap(client); | 137 client_.swap(client); |
119 } | 138 } |
120 | 139 |
121 void PageHandler::Detached() { | 140 void PageHandler::Detached() { |
122 Disable(); | 141 Disable(); |
123 } | 142 } |
124 | 143 |
125 void PageHandler::OnSwapCompositorFrame( | 144 void PageHandler::OnSwapCompositorFrame( |
126 const cc::CompositorFrameMetadata& frame_metadata) { | 145 const cc::CompositorFrameMetadata& frame_metadata) { |
127 last_compositor_frame_metadata_ = has_compositor_frame_metadata_ ? | 146 last_compositor_frame_metadata_ = has_compositor_frame_metadata_ ? |
128 next_compositor_frame_metadata_ : frame_metadata; | 147 next_compositor_frame_metadata_ : frame_metadata; |
129 next_compositor_frame_metadata_ = frame_metadata; | 148 next_compositor_frame_metadata_ = frame_metadata; |
130 has_compositor_frame_metadata_ = true; | 149 has_compositor_frame_metadata_ = true; |
131 | 150 |
132 if (screencast_enabled_) | 151 if (screencast_enabled_) |
133 InnerSwapCompositorFrame(); | 152 InnerSwapCompositorFrame(); |
134 color_picker_->OnSwapCompositorFrame(); | 153 color_picker_->OnSwapCompositorFrame(); |
135 } | 154 } |
136 | 155 |
137 void PageHandler::OnVisibilityChanged(bool visible) { | 156 void PageHandler::Observe(int type, |
| 157 const NotificationSource& source, |
| 158 const NotificationDetails& details) { |
138 if (!screencast_enabled_) | 159 if (!screencast_enabled_) |
139 return; | 160 return; |
| 161 DCHECK(type == content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED); |
| 162 bool visible = *Details<bool>(details).ptr(); |
140 NotifyScreencastVisibility(visible); | 163 NotifyScreencastVisibility(visible); |
141 } | 164 } |
142 | 165 |
143 void PageHandler::DidAttachInterstitialPage() { | 166 void PageHandler::DidAttachInterstitialPage() { |
144 if (!enabled_) | 167 if (!enabled_) |
145 return; | 168 return; |
146 client_->InterstitialShown(InterstitialShownParams::Create()); | 169 client_->InterstitialShown(InterstitialShownParams::Create()); |
147 } | 170 } |
148 | 171 |
149 void PageHandler::DidDetachInterstitialPage() { | 172 void PageHandler::DidDetachInterstitialPage() { |
(...skipping 16 matching lines...) Expand all Loading... |
166 screencast_enabled_ = false; | 189 screencast_enabled_ = false; |
167 color_picker_->SetEnabled(false); | 190 color_picker_->SetEnabled(false); |
168 if (screencast_listener_) | 191 if (screencast_listener_) |
169 screencast_listener_->ScreencastEnabledChanged(); | 192 screencast_listener_->ScreencastEnabledChanged(); |
170 return Response::FallThrough(); | 193 return Response::FallThrough(); |
171 } | 194 } |
172 | 195 |
173 Response PageHandler::Reload(const bool* ignoreCache, | 196 Response PageHandler::Reload(const bool* ignoreCache, |
174 const std::string* script_to_evaluate_on_load, | 197 const std::string* script_to_evaluate_on_load, |
175 const std::string* script_preprocessor) { | 198 const std::string* script_preprocessor) { |
176 if (!host_) | 199 WebContentsImpl* web_contents = GetWebContents(); |
| 200 if (!web_contents) |
177 return Response::InternalError("Could not connect to view"); | 201 return Response::InternalError("Could not connect to view"); |
178 | 202 |
179 WebContents* web_contents = WebContents::FromRenderViewHost(host_); | |
180 if (!web_contents) | |
181 return Response::InternalError("No WebContents to reload"); | |
182 | |
183 // Handle in browser only if it is crashed. | 203 // Handle in browser only if it is crashed. |
184 if (!web_contents->IsCrashed()) | 204 if (!web_contents->IsCrashed()) |
185 return Response::FallThrough(); | 205 return Response::FallThrough(); |
186 | 206 |
187 web_contents->GetController().Reload(false); | 207 web_contents->GetController().Reload(false); |
188 return Response::OK(); | 208 return Response::OK(); |
189 } | 209 } |
190 | 210 |
191 Response PageHandler::Navigate(const std::string& url, | 211 Response PageHandler::Navigate(const std::string& url, |
192 FrameId* frame_id) { | 212 FrameId* frame_id) { |
193 GURL gurl(url); | 213 GURL gurl(url); |
194 if (!gurl.is_valid()) | 214 if (!gurl.is_valid()) |
195 return Response::InternalError("Cannot navigate to invalid URL"); | 215 return Response::InternalError("Cannot navigate to invalid URL"); |
196 | 216 |
197 if (!host_) | 217 WebContentsImpl* web_contents = GetWebContents(); |
| 218 if (!web_contents) |
198 return Response::InternalError("Could not connect to view"); | 219 return Response::InternalError("Could not connect to view"); |
199 | 220 |
200 WebContents* web_contents = WebContents::FromRenderViewHost(host_); | |
201 if (!web_contents) | |
202 return Response::InternalError("No WebContents to navigate"); | |
203 | |
204 web_contents->GetController() | 221 web_contents->GetController() |
205 .LoadURL(gurl, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); | 222 .LoadURL(gurl, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); |
206 return Response::FallThrough(); | 223 return Response::FallThrough(); |
207 } | 224 } |
208 | 225 |
209 Response PageHandler::GetNavigationHistory(int* current_index, | 226 Response PageHandler::GetNavigationHistory(int* current_index, |
210 NavigationEntries* entries) { | 227 NavigationEntries* entries) { |
211 if (!host_) | 228 WebContentsImpl* web_contents = GetWebContents(); |
| 229 if (!web_contents) |
212 return Response::InternalError("Could not connect to view"); | 230 return Response::InternalError("Could not connect to view"); |
213 | 231 |
214 WebContents* web_contents = WebContents::FromRenderViewHost(host_); | |
215 if (!web_contents) | |
216 return Response::InternalError("No WebContents to navigate"); | |
217 | |
218 NavigationController& controller = web_contents->GetController(); | 232 NavigationController& controller = web_contents->GetController(); |
219 *current_index = controller.GetCurrentEntryIndex(); | 233 *current_index = controller.GetCurrentEntryIndex(); |
220 for (int i = 0; i != controller.GetEntryCount(); ++i) { | 234 for (int i = 0; i != controller.GetEntryCount(); ++i) { |
221 entries->push_back(NavigationEntry::Create() | 235 entries->push_back(NavigationEntry::Create() |
222 ->set_id(controller.GetEntryAtIndex(i)->GetUniqueID()) | 236 ->set_id(controller.GetEntryAtIndex(i)->GetUniqueID()) |
223 ->set_url(controller.GetEntryAtIndex(i)->GetURL().spec()) | 237 ->set_url(controller.GetEntryAtIndex(i)->GetURL().spec()) |
224 ->set_title( | 238 ->set_title( |
225 base::UTF16ToUTF8(controller.GetEntryAtIndex(i)->GetTitle()))); | 239 base::UTF16ToUTF8(controller.GetEntryAtIndex(i)->GetTitle()))); |
226 } | 240 } |
227 return Response::OK(); | 241 return Response::OK(); |
228 } | 242 } |
229 | 243 |
230 Response PageHandler::NavigateToHistoryEntry(int entry_id) { | 244 Response PageHandler::NavigateToHistoryEntry(int entry_id) { |
231 if (!host_) | 245 WebContentsImpl* web_contents = GetWebContents(); |
| 246 if (!web_contents) |
232 return Response::InternalError("Could not connect to view"); | 247 return Response::InternalError("Could not connect to view"); |
233 | 248 |
234 WebContents* web_contents = WebContents::FromRenderViewHost(host_); | |
235 if (!web_contents) | |
236 return Response::InternalError("No WebContents to navigate"); | |
237 | |
238 NavigationController& controller = web_contents->GetController(); | 249 NavigationController& controller = web_contents->GetController(); |
239 for (int i = 0; i != controller.GetEntryCount(); ++i) { | 250 for (int i = 0; i != controller.GetEntryCount(); ++i) { |
240 if (controller.GetEntryAtIndex(i)->GetUniqueID() == entry_id) { | 251 if (controller.GetEntryAtIndex(i)->GetUniqueID() == entry_id) { |
241 controller.GoToIndex(i); | 252 controller.GoToIndex(i); |
242 return Response::OK(); | 253 return Response::OK(); |
243 } | 254 } |
244 } | 255 } |
245 | 256 |
246 return Response::InvalidParams("No entry with passed id"); | 257 return Response::InvalidParams("No entry with passed id"); |
247 } | 258 } |
248 | 259 |
249 Response PageHandler::CaptureScreenshot(DevToolsCommandId command_id) { | 260 Response PageHandler::CaptureScreenshot(DevToolsCommandId command_id) { |
250 if (!host_ || !host_->GetView()) | 261 if (!host_ || !host_->GetRenderWidgetHost()) |
251 return Response::InternalError("Could not connect to view"); | 262 return Response::InternalError("Could not connect to view"); |
252 | 263 |
253 host_->GetSnapshotFromBrowser( | 264 host_->GetRenderWidgetHost()->GetSnapshotFromBrowser( |
254 base::Bind(&PageHandler::ScreenshotCaptured, | 265 base::Bind(&PageHandler::ScreenshotCaptured, |
255 weak_factory_.GetWeakPtr(), command_id)); | 266 weak_factory_.GetWeakPtr(), command_id)); |
256 return Response::OK(); | 267 return Response::OK(); |
257 } | 268 } |
258 | 269 |
259 Response PageHandler::CanScreencast(bool* result) { | 270 Response PageHandler::CanScreencast(bool* result) { |
260 #if defined(OS_ANDROID) | 271 #if defined(OS_ANDROID) |
261 *result = true; | 272 *result = true; |
262 #else | 273 #else |
263 *result = false; | 274 *result = false; |
264 #endif // defined(OS_ANDROID) | 275 #endif // defined(OS_ANDROID) |
265 return Response::OK(); | 276 return Response::OK(); |
266 } | 277 } |
267 | 278 |
268 Response PageHandler::StartScreencast(const std::string* format, | 279 Response PageHandler::StartScreencast(const std::string* format, |
269 const int* quality, | 280 const int* quality, |
270 const int* max_width, | 281 const int* max_width, |
271 const int* max_height) { | 282 const int* max_height) { |
272 if (!host_) | 283 RenderWidgetHostImpl* widget_host = |
| 284 host_ ? host_->GetRenderWidgetHost() : nullptr; |
| 285 if (!widget_host) |
273 return Response::InternalError("Could not connect to view"); | 286 return Response::InternalError("Could not connect to view"); |
274 | 287 |
275 screencast_enabled_ = true; | 288 screencast_enabled_ = true; |
276 screencast_format_ = format ? *format : kPng; | 289 screencast_format_ = format ? *format : kPng; |
277 screencast_quality_ = quality ? *quality : kDefaultScreenshotQuality; | 290 screencast_quality_ = quality ? *quality : kDefaultScreenshotQuality; |
278 if (screencast_quality_ < 0 || screencast_quality_ > 100) | 291 if (screencast_quality_ < 0 || screencast_quality_ > 100) |
279 screencast_quality_ = kDefaultScreenshotQuality; | 292 screencast_quality_ = kDefaultScreenshotQuality; |
280 screencast_max_width_ = max_width ? *max_width : -1; | 293 screencast_max_width_ = max_width ? *max_width : -1; |
281 screencast_max_height_ = max_height ? *max_height : -1; | 294 screencast_max_height_ = max_height ? *max_height : -1; |
282 | 295 |
283 bool visible = !host_->is_hidden(); | 296 bool visible = !widget_host->is_hidden(); |
284 NotifyScreencastVisibility(visible); | 297 NotifyScreencastVisibility(visible); |
285 if (visible) { | 298 if (visible) { |
286 if (has_compositor_frame_metadata_) | 299 if (has_compositor_frame_metadata_) { |
287 InnerSwapCompositorFrame(); | 300 InnerSwapCompositorFrame(); |
288 else | 301 } else { |
289 host_->Send(new ViewMsg_ForceRedraw(host_->GetRoutingID(), 0)); | 302 widget_host->Send( |
| 303 new ViewMsg_ForceRedraw(widget_host->GetRoutingID(), 0)); |
| 304 } |
290 } | 305 } |
291 if (screencast_listener_) | 306 if (screencast_listener_) |
292 screencast_listener_->ScreencastEnabledChanged(); | 307 screencast_listener_->ScreencastEnabledChanged(); |
293 return Response::FallThrough(); | 308 return Response::FallThrough(); |
294 } | 309 } |
295 | 310 |
296 Response PageHandler::StopScreencast() { | 311 Response PageHandler::StopScreencast() { |
297 screencast_enabled_ = false; | 312 screencast_enabled_ = false; |
298 if (screencast_listener_) | 313 if (screencast_listener_) |
299 screencast_listener_->ScreencastEnabledChanged(); | 314 screencast_listener_->ScreencastEnabledChanged(); |
300 return Response::FallThrough(); | 315 return Response::FallThrough(); |
301 } | 316 } |
302 | 317 |
303 Response PageHandler::ScreencastFrameAck(int frame_number) { | 318 Response PageHandler::ScreencastFrameAck(int frame_number) { |
304 screencast_frame_acked_ = frame_number; | 319 screencast_frame_acked_ = frame_number; |
305 return Response::OK(); | 320 return Response::OK(); |
306 } | 321 } |
307 | 322 |
308 Response PageHandler::HandleJavaScriptDialog(bool accept, | 323 Response PageHandler::HandleJavaScriptDialog(bool accept, |
309 const std::string* prompt_text) { | 324 const std::string* prompt_text) { |
310 base::string16 prompt_override; | 325 base::string16 prompt_override; |
311 if (prompt_text) | 326 if (prompt_text) |
312 prompt_override = base::UTF8ToUTF16(*prompt_text); | 327 prompt_override = base::UTF8ToUTF16(*prompt_text); |
313 | 328 |
314 if (!host_) | 329 WebContentsImpl* web_contents = GetWebContents(); |
| 330 if (!web_contents) |
315 return Response::InternalError("Could not connect to view"); | 331 return Response::InternalError("Could not connect to view"); |
316 | 332 |
317 WebContents* web_contents = WebContents::FromRenderViewHost(host_); | |
318 if (!web_contents) | |
319 return Response::InternalError("No JavaScript dialog to handle"); | |
320 | |
321 JavaScriptDialogManager* manager = | 333 JavaScriptDialogManager* manager = |
322 web_contents->GetDelegate()->GetJavaScriptDialogManager(web_contents); | 334 web_contents->GetDelegate()->GetJavaScriptDialogManager(web_contents); |
323 if (manager && manager->HandleJavaScriptDialog( | 335 if (manager && manager->HandleJavaScriptDialog( |
324 web_contents, accept, prompt_text ? &prompt_override : nullptr)) { | 336 web_contents, accept, prompt_text ? &prompt_override : nullptr)) { |
325 return Response::OK(); | 337 return Response::OK(); |
326 } | 338 } |
327 | 339 |
328 return Response::InternalError("Could not handle JavaScript dialog"); | 340 return Response::InternalError("Could not handle JavaScript dialog"); |
329 } | 341 } |
330 | 342 |
331 Response PageHandler::QueryUsageAndQuota(DevToolsCommandId command_id, | 343 Response PageHandler::QueryUsageAndQuota(DevToolsCommandId command_id, |
332 const std::string& security_origin) { | 344 const std::string& security_origin) { |
333 return Response::OK(); | 345 return Response::OK(); |
334 } | 346 } |
335 | 347 |
336 Response PageHandler::SetColorPickerEnabled(bool enabled) { | 348 Response PageHandler::SetColorPickerEnabled(bool enabled) { |
337 if (!host_) | 349 if (!host_) |
338 return Response::InternalError("Could not connect to view"); | 350 return Response::InternalError("Could not connect to view"); |
339 | 351 |
340 color_picker_->SetEnabled(enabled); | 352 color_picker_->SetEnabled(enabled); |
341 return Response::OK(); | 353 return Response::OK(); |
342 } | 354 } |
343 | 355 |
| 356 WebContentsImpl* PageHandler::GetWebContents() { |
| 357 return host_ ? |
| 358 static_cast<WebContentsImpl*>(WebContents::FromRenderFrameHost(host_)) : |
| 359 nullptr; |
| 360 } |
| 361 |
344 void PageHandler::NotifyScreencastVisibility(bool visible) { | 362 void PageHandler::NotifyScreencastVisibility(bool visible) { |
345 if (visible) | 363 if (visible) |
346 capture_retry_count_ = kCaptureRetryLimit; | 364 capture_retry_count_ = kCaptureRetryLimit; |
347 client_->ScreencastVisibilityChanged( | 365 client_->ScreencastVisibilityChanged( |
348 ScreencastVisibilityChangedParams::Create()->set_visible(visible)); | 366 ScreencastVisibilityChangedParams::Create()->set_visible(visible)); |
349 } | 367 } |
350 | 368 |
351 void PageHandler::InnerSwapCompositorFrame() { | 369 void PageHandler::InnerSwapCompositorFrame() { |
352 if (screencast_frame_sent_ - screencast_frame_acked_ > | 370 if (screencast_frame_sent_ - screencast_frame_acked_ > |
353 kMaxScreencastFramesInFlight || processing_screencast_frame_) { | 371 kMaxScreencastFramesInFlight || processing_screencast_frame_) { |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 | 495 |
478 void PageHandler::OnColorPicked(int r, int g, int b, int a) { | 496 void PageHandler::OnColorPicked(int r, int g, int b, int a) { |
479 scoped_refptr<dom::RGBA> color = | 497 scoped_refptr<dom::RGBA> color = |
480 dom::RGBA::Create()->set_r(r)->set_g(g)->set_b(b)->set_a(a); | 498 dom::RGBA::Create()->set_r(r)->set_g(g)->set_b(b)->set_a(a); |
481 client_->ColorPicked(ColorPickedParams::Create()->set_color(color)); | 499 client_->ColorPicked(ColorPickedParams::Create()->set_color(color)); |
482 } | 500 } |
483 | 501 |
484 } // namespace page | 502 } // namespace page |
485 } // namespace devtools | 503 } // namespace devtools |
486 } // namespace content | 504 } // namespace content |
OLD | NEW |