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 "chrome/browser/devtools/devtools_ui_bindings.h" | 5 #include "chrome/browser/devtools/devtools_ui_bindings.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 #include <utility> | 10 #include <utility> |
11 | 11 |
12 #include "base/base64.h" | 12 #include "base/base64.h" |
13 #include "base/json/json_reader.h" | 13 #include "base/json/json_reader.h" |
14 #include "base/json/json_writer.h" | 14 #include "base/json/json_writer.h" |
15 #include "base/json/string_escape.h" | 15 #include "base/json/string_escape.h" |
16 #include "base/macros.h" | 16 #include "base/macros.h" |
17 #include "base/memory/ptr_util.h" | 17 #include "base/memory/ptr_util.h" |
18 #include "base/metrics/histogram_macros.h" | 18 #include "base/metrics/histogram_macros.h" |
19 #include "base/strings/string_number_conversions.h" | 19 #include "base/strings/string_number_conversions.h" |
| 20 #include "base/strings/string_split.h" |
20 #include "base/strings/string_util.h" | 21 #include "base/strings/string_util.h" |
21 #include "base/strings/stringprintf.h" | 22 #include "base/strings/stringprintf.h" |
22 #include "base/strings/utf_string_conversions.h" | 23 #include "base/strings/utf_string_conversions.h" |
23 #include "base/values.h" | 24 #include "base/values.h" |
24 #include "build/build_config.h" | 25 #include "build/build_config.h" |
25 #include "chrome/browser/chrome_notification_types.h" | 26 #include "chrome/browser/chrome_notification_types.h" |
26 #include "chrome/browser/devtools/devtools_file_watcher.h" | 27 #include "chrome/browser/devtools/devtools_file_watcher.h" |
27 #include "chrome/browser/devtools/devtools_protocol.h" | 28 #include "chrome/browser/devtools/devtools_protocol.h" |
28 #include "chrome/browser/devtools/global_confirm_info_bar.h" | 29 #include "chrome/browser/devtools/global_confirm_info_bar.h" |
| 30 #include "chrome/browser/devtools/url_constants.h" |
29 #include "chrome/browser/extensions/chrome_extension_web_contents_observer.h" | 31 #include "chrome/browser/extensions/chrome_extension_web_contents_observer.h" |
30 #include "chrome/browser/infobars/infobar_service.h" | 32 #include "chrome/browser/infobars/infobar_service.h" |
31 #include "chrome/browser/profiles/profile.h" | 33 #include "chrome/browser/profiles/profile.h" |
32 #include "chrome/browser/ui/browser.h" | 34 #include "chrome/browser/ui/browser.h" |
33 #include "chrome/browser/ui/browser_list.h" | 35 #include "chrome/browser/ui/browser_list.h" |
34 #include "chrome/browser/ui/browser_window.h" | 36 #include "chrome/browser/ui/browser_window.h" |
35 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 37 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
36 #include "chrome/common/chrome_switches.h" | 38 #include "chrome/common/chrome_switches.h" |
37 #include "chrome/common/extensions/chrome_manifest_url_handlers.h" | 39 #include "chrome/common/extensions/chrome_manifest_url_handlers.h" |
38 #include "chrome/common/pref_names.h" | 40 #include "chrome/common/pref_names.h" |
39 #include "chrome/common/url_constants.h" | 41 #include "chrome/common/url_constants.h" |
40 #include "chrome/grit/generated_resources.h" | 42 #include "chrome/grit/generated_resources.h" |
41 #include "components/infobars/core/confirm_infobar_delegate.h" | 43 #include "components/infobars/core/confirm_infobar_delegate.h" |
42 #include "components/infobars/core/infobar.h" | 44 #include "components/infobars/core/infobar.h" |
43 #include "components/prefs/scoped_user_pref_update.h" | 45 #include "components/prefs/scoped_user_pref_update.h" |
44 #include "components/sync_preferences/pref_service_syncable.h" | 46 #include "components/sync_preferences/pref_service_syncable.h" |
45 #include "components/zoom/page_zoom.h" | 47 #include "components/zoom/page_zoom.h" |
46 #include "content/public/browser/child_process_security_policy.h" | 48 #include "content/public/browser/child_process_security_policy.h" |
47 #include "content/public/browser/devtools_external_agent_proxy.h" | 49 #include "content/public/browser/devtools_external_agent_proxy.h" |
48 #include "content/public/browser/devtools_external_agent_proxy_delegate.h" | 50 #include "content/public/browser/devtools_external_agent_proxy_delegate.h" |
49 #include "content/public/browser/navigation_controller.h" | 51 #include "content/public/browser/navigation_controller.h" |
50 #include "content/public/browser/navigation_entry.h" | 52 #include "content/public/browser/navigation_entry.h" |
| 53 #include "content/public/browser/navigation_handle.h" |
51 #include "content/public/browser/notification_source.h" | 54 #include "content/public/browser/notification_source.h" |
52 #include "content/public/browser/reload_type.h" | 55 #include "content/public/browser/reload_type.h" |
53 #include "content/public/browser/render_frame_host.h" | 56 #include "content/public/browser/render_frame_host.h" |
54 #include "content/public/browser/render_process_host.h" | 57 #include "content/public/browser/render_process_host.h" |
55 #include "content/public/browser/render_view_host.h" | 58 #include "content/public/browser/render_view_host.h" |
56 #include "content/public/browser/user_metrics.h" | 59 #include "content/public/browser/user_metrics.h" |
57 #include "content/public/browser/web_contents.h" | 60 #include "content/public/browser/web_contents.h" |
58 #include "content/public/browser/web_contents_observer.h" | 61 #include "content/public/browser/web_contents_observer.h" |
59 #include "content/public/common/renderer_preferences.h" | 62 #include "content/public/common/renderer_preferences.h" |
60 #include "content/public/common/url_constants.h" | 63 #include "content/public/common/url_constants.h" |
61 #include "extensions/browser/extension_registry.h" | 64 #include "extensions/browser/extension_registry.h" |
62 #include "extensions/common/constants.h" | 65 #include "extensions/common/constants.h" |
63 #include "extensions/common/permissions/permissions_data.h" | 66 #include "extensions/common/permissions/permissions_data.h" |
64 #include "ipc/ipc_channel.h" | 67 #include "ipc/ipc_channel.h" |
| 68 #include "net/base/escape.h" |
65 #include "net/base/io_buffer.h" | 69 #include "net/base/io_buffer.h" |
66 #include "net/base/net_errors.h" | 70 #include "net/base/net_errors.h" |
| 71 #include "net/base/url_util.h" |
67 #include "net/cert/x509_certificate.h" | 72 #include "net/cert/x509_certificate.h" |
68 #include "net/http/http_response_headers.h" | 73 #include "net/http/http_response_headers.h" |
69 #include "net/url_request/url_fetcher.h" | 74 #include "net/url_request/url_fetcher.h" |
70 #include "net/url_request/url_fetcher_response_writer.h" | 75 #include "net/url_request/url_fetcher_response_writer.h" |
71 #include "third_party/WebKit/public/public_features.h" | 76 #include "third_party/WebKit/public/public_features.h" |
72 #include "ui/base/l10n/l10n_util.h" | 77 #include "ui/base/l10n/l10n_util.h" |
73 #include "ui/base/page_transition_types.h" | 78 #include "ui/base/page_transition_types.h" |
74 | 79 |
75 using base::DictionaryValue; | 80 using base::DictionaryValue; |
76 using content::BrowserThread; | 81 using content::BrowserThread; |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 "DevToolsAPI.streamWrite", base::Owned(id), | 297 "DevToolsAPI.streamWrite", base::Owned(id), |
293 base::Owned(chunkValue), base::Owned(encodedValue))); | 298 base::Owned(chunkValue), base::Owned(encodedValue))); |
294 return num_bytes; | 299 return num_bytes; |
295 } | 300 } |
296 | 301 |
297 int ResponseWriter::Finish(int net_error, | 302 int ResponseWriter::Finish(int net_error, |
298 const net::CompletionCallback& callback) { | 303 const net::CompletionCallback& callback) { |
299 return net::OK; | 304 return net::OK; |
300 } | 305 } |
301 | 306 |
| 307 GURL SanitizeFrontendURL( |
| 308 const GURL& url, |
| 309 const std::string& scheme, |
| 310 const std::string& host, |
| 311 const std::string& path, |
| 312 bool allow_query); |
| 313 |
| 314 std::string SanitizeRevision(const std::string& revision) { |
| 315 for (size_t i = 0; i < revision.length(); i++) { |
| 316 if (!(revision[i] == '@' && i == 0) |
| 317 && !(revision[i] >= '0' && revision[i] <= '9') |
| 318 && !(revision[i] >= 'a' && revision[i] <= 'z') |
| 319 && !(revision[i] >= 'A' && revision[i] <= 'Z')) { |
| 320 return std::string(); |
| 321 } |
| 322 } |
| 323 return revision; |
| 324 } |
| 325 |
| 326 std::string SanitizeFrontendPath(const std::string& path) { |
| 327 for (size_t i = 0; i < path.length(); i++) { |
| 328 if (path[i] != '/' && path[i] != '-' && path[i] != '_' |
| 329 && path[i] != '.' && path[i] != '@' |
| 330 && !(path[i] >= '0' && path[i] <= '9') |
| 331 && !(path[i] >= 'a' && path[i] <= 'z') |
| 332 && !(path[i] >= 'A' && path[i] <= 'Z')) { |
| 333 return std::string(); |
| 334 } |
| 335 } |
| 336 return path; |
| 337 } |
| 338 |
| 339 std::string SanitizeEndpoint(const std::string& value) { |
| 340 if (value.find('&') != std::string::npos |
| 341 || value.find('?') != std::string::npos) |
| 342 return std::string(); |
| 343 return value; |
| 344 } |
| 345 |
| 346 std::string SanitizeRemoteBase(const std::string& value) { |
| 347 GURL url(value); |
| 348 std::string path = url.path(); |
| 349 std::vector<std::string> parts = base::SplitString( |
| 350 path, "/", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); |
| 351 std::string revision = parts.size() > 2 ? parts[2] : ""; |
| 352 revision = SanitizeRevision(revision); |
| 353 path = base::StringPrintf("/%s/%s/", kRemoteFrontendPath, revision.c_str()); |
| 354 return SanitizeFrontendURL(url, url::kHttpsScheme, |
| 355 kRemoteFrontendDomain, path, false).spec(); |
| 356 } |
| 357 |
| 358 std::string SanitizeRemoteFrontendURL(const std::string& value) { |
| 359 GURL url(net::UnescapeURLComponent(value, |
| 360 net::UnescapeRule::SPACES | net::UnescapeRule::PATH_SEPARATORS | |
| 361 net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS | |
| 362 net::UnescapeRule::REPLACE_PLUS_WITH_SPACE)); |
| 363 std::string path = url.path(); |
| 364 std::vector<std::string> parts = base::SplitString( |
| 365 path, "/", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); |
| 366 std::string revision = parts.size() > 2 ? parts[2] : ""; |
| 367 revision = SanitizeRevision(revision); |
| 368 std::string filename = parts.size() ? parts[parts.size() - 1] : ""; |
| 369 if (filename != "devtools.html") |
| 370 filename = "inspector.html"; |
| 371 path = base::StringPrintf("/serve_rev/%s/%s", |
| 372 revision.c_str(), filename.c_str()); |
| 373 std::string sanitized = SanitizeFrontendURL(url, url::kHttpsScheme, |
| 374 kRemoteFrontendDomain, path, true).spec(); |
| 375 return net::EscapeQueryParamValue(sanitized, false); |
| 376 } |
| 377 |
| 378 std::string SanitizeFrontendQueryParam( |
| 379 const std::string& key, |
| 380 const std::string& value) { |
| 381 // Convert boolean flags to true. |
| 382 if (key == "can_dock" || key == "debugFrontend" || key == "experiments" || |
| 383 key == "isSharedWorker" || key == "v8only" || key == "remoteFrontend") |
| 384 return "true"; |
| 385 |
| 386 // Pass connection endpoints as is. |
| 387 if (key == "ws" || key == "service-backend") |
| 388 return SanitizeEndpoint(value); |
| 389 |
| 390 // Only support undocked for old frontends. |
| 391 if (key == "dockSide" && value == "undocked") |
| 392 return value; |
| 393 |
| 394 if (key == "panel" && (value == "elements" || value == "console")) |
| 395 return value; |
| 396 |
| 397 if (key == "remoteBase") |
| 398 return SanitizeRemoteBase(value); |
| 399 |
| 400 if (key == "remoteFrontendUrl") |
| 401 return SanitizeRemoteFrontendURL(value); |
| 402 |
| 403 return std::string(); |
| 404 } |
| 405 |
| 406 GURL SanitizeFrontendURL( |
| 407 const GURL& url, |
| 408 const std::string& scheme, |
| 409 const std::string& host, |
| 410 const std::string& path, |
| 411 bool allow_query) { |
| 412 std::vector<std::string> query_parts; |
| 413 if (allow_query) { |
| 414 for (net::QueryIterator it(url); !it.IsAtEnd(); it.Advance()) { |
| 415 std::string value = SanitizeFrontendQueryParam(it.GetKey(), |
| 416 it.GetValue()); |
| 417 if (!value.empty()) { |
| 418 query_parts.push_back( |
| 419 base::StringPrintf("%s=%s", it.GetKey().c_str(), value.c_str())); |
| 420 } |
| 421 } |
| 422 } |
| 423 std::string query = |
| 424 query_parts.empty() ? "" : "?" + base::JoinString(query_parts, "&"); |
| 425 std::string constructed = base::StringPrintf("%s://%s%s%s", |
| 426 scheme.c_str(), host.c_str(), path.c_str(), query.c_str()); |
| 427 GURL result = GURL(constructed); |
| 428 if (!result.is_valid()) |
| 429 return GURL(); |
| 430 return result; |
| 431 } |
| 432 |
302 } // namespace | 433 } // namespace |
303 | 434 |
304 // DevToolsUIBindings::FrontendWebContentsObserver ---------------------------- | 435 // DevToolsUIBindings::FrontendWebContentsObserver ---------------------------- |
305 | 436 |
306 class DevToolsUIBindings::FrontendWebContentsObserver | 437 class DevToolsUIBindings::FrontendWebContentsObserver |
307 : public content::WebContentsObserver { | 438 : public content::WebContentsObserver { |
308 public: | 439 public: |
309 explicit FrontendWebContentsObserver(DevToolsUIBindings* ui_bindings); | 440 explicit FrontendWebContentsObserver(DevToolsUIBindings* ui_bindings); |
310 ~FrontendWebContentsObserver() override; | 441 ~FrontendWebContentsObserver() override; |
311 | 442 |
312 private: | 443 private: |
313 // contents::WebContentsObserver: | 444 // contents::WebContentsObserver: |
314 void RenderProcessGone(base::TerminationStatus status) override; | 445 void RenderProcessGone(base::TerminationStatus status) override; |
315 void DidStartNavigationToPendingEntry( | 446 void ReadyToCommitNavigation( |
316 const GURL& url, | 447 content::NavigationHandle* navigation_handle) override; |
317 content::ReloadType reload_type) override; | |
318 void DocumentAvailableInMainFrame() override; | 448 void DocumentAvailableInMainFrame() override; |
319 void DocumentOnLoadCompletedInMainFrame() override; | 449 void DocumentOnLoadCompletedInMainFrame() override; |
320 void DidNavigateMainFrame( | 450 void DidNavigateMainFrame( |
321 const content::LoadCommittedDetails& details, | 451 const content::LoadCommittedDetails& details, |
322 const content::FrameNavigateParams& params) override; | 452 const content::FrameNavigateParams& params) override; |
323 | 453 |
324 DevToolsUIBindings* devtools_bindings_; | 454 DevToolsUIBindings* devtools_bindings_; |
325 DISALLOW_COPY_AND_ASSIGN(FrontendWebContentsObserver); | 455 DISALLOW_COPY_AND_ASSIGN(FrontendWebContentsObserver); |
326 }; | 456 }; |
327 | 457 |
328 DevToolsUIBindings::FrontendWebContentsObserver::FrontendWebContentsObserver( | 458 DevToolsUIBindings::FrontendWebContentsObserver::FrontendWebContentsObserver( |
329 DevToolsUIBindings* devtools_ui_bindings) | 459 DevToolsUIBindings* devtools_ui_bindings) |
330 : WebContentsObserver(devtools_ui_bindings->web_contents()), | 460 : WebContentsObserver(devtools_ui_bindings->web_contents()), |
331 devtools_bindings_(devtools_ui_bindings) { | 461 devtools_bindings_(devtools_ui_bindings) { |
332 } | 462 } |
333 | 463 |
334 DevToolsUIBindings::FrontendWebContentsObserver:: | 464 DevToolsUIBindings::FrontendWebContentsObserver:: |
335 ~FrontendWebContentsObserver() { | 465 ~FrontendWebContentsObserver() { |
336 } | 466 } |
337 | 467 |
| 468 // static |
| 469 GURL DevToolsUIBindings::SanitizeFrontendURL(const GURL& url) { |
| 470 return ::SanitizeFrontendURL(url, content::kChromeDevToolsScheme, |
| 471 chrome::kChromeUIDevToolsHost, SanitizeFrontendPath(url.path()), true); |
| 472 } |
| 473 |
| 474 bool DevToolsUIBindings::IsValidFrontendURL(const GURL& url) { |
| 475 return SanitizeFrontendURL(url).spec() == url.spec(); |
| 476 } |
| 477 |
338 void DevToolsUIBindings::FrontendWebContentsObserver::RenderProcessGone( | 478 void DevToolsUIBindings::FrontendWebContentsObserver::RenderProcessGone( |
339 base::TerminationStatus status) { | 479 base::TerminationStatus status) { |
340 bool crashed = true; | 480 bool crashed = true; |
341 switch (status) { | 481 switch (status) { |
342 case base::TERMINATION_STATUS_ABNORMAL_TERMINATION: | 482 case base::TERMINATION_STATUS_ABNORMAL_TERMINATION: |
343 case base::TERMINATION_STATUS_PROCESS_WAS_KILLED: | 483 case base::TERMINATION_STATUS_PROCESS_WAS_KILLED: |
344 #if defined(OS_CHROMEOS) | 484 #if defined(OS_CHROMEOS) |
345 case base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM: | 485 case base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM: |
346 #endif | 486 #endif |
347 case base::TERMINATION_STATUS_PROCESS_CRASHED: | 487 case base::TERMINATION_STATUS_PROCESS_CRASHED: |
348 case base::TERMINATION_STATUS_LAUNCH_FAILED: | 488 case base::TERMINATION_STATUS_LAUNCH_FAILED: |
349 if (devtools_bindings_->agent_host_.get()) | 489 if (devtools_bindings_->agent_host_.get()) |
350 devtools_bindings_->Detach(); | 490 devtools_bindings_->Detach(); |
351 break; | 491 break; |
352 default: | 492 default: |
353 crashed = false; | 493 crashed = false; |
354 break; | 494 break; |
355 } | 495 } |
356 devtools_bindings_->delegate_->RenderProcessGone(crashed); | 496 devtools_bindings_->delegate_->RenderProcessGone(crashed); |
357 } | 497 } |
358 | 498 |
359 void DevToolsUIBindings::FrontendWebContentsObserver:: | 499 void DevToolsUIBindings::FrontendWebContentsObserver::ReadyToCommitNavigation( |
360 DidStartNavigationToPendingEntry(const GURL& url, | 500 content::NavigationHandle* navigation_handle) { |
361 content::ReloadType reload_type) { | 501 if (!navigation_handle->IsInMainFrame()) |
362 devtools_bindings_->frontend_host_.reset( | 502 return; |
363 content::DevToolsFrontendHost::Create( | 503 devtools_bindings_->UpdateFrontendHost(navigation_handle); |
364 web_contents()->GetMainFrame(), | |
365 base::Bind(&DevToolsUIBindings::HandleMessageFromDevToolsFrontend, | |
366 base::Unretained(devtools_bindings_)))); | |
367 } | 504 } |
368 | 505 |
369 void DevToolsUIBindings::FrontendWebContentsObserver:: | 506 void DevToolsUIBindings::FrontendWebContentsObserver:: |
370 DocumentAvailableInMainFrame() { | 507 DocumentAvailableInMainFrame() { |
371 devtools_bindings_->DocumentAvailableInMainFrame(); | 508 devtools_bindings_->DocumentAvailableInMainFrame(); |
372 } | 509 } |
373 | 510 |
374 void DevToolsUIBindings::FrontendWebContentsObserver:: | 511 void DevToolsUIBindings::FrontendWebContentsObserver:: |
375 DocumentOnLoadCompletedInMainFrame() { | 512 DocumentOnLoadCompletedInMainFrame() { |
376 devtools_bindings_->DocumentOnLoadCompletedInMainFrame(); | 513 devtools_bindings_->DocumentOnLoadCompletedInMainFrame(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 web_contents_->GetMutableRendererPrefs()->can_accept_load_drops = false; | 548 web_contents_->GetMutableRendererPrefs()->can_accept_load_drops = false; |
412 | 549 |
413 file_helper_.reset(new DevToolsFileHelper(web_contents_, profile_, this)); | 550 file_helper_.reset(new DevToolsFileHelper(web_contents_, profile_, this)); |
414 file_system_indexer_ = new DevToolsFileSystemIndexer(); | 551 file_system_indexer_ = new DevToolsFileSystemIndexer(); |
415 extensions::ChromeExtensionWebContentsObserver::CreateForWebContents( | 552 extensions::ChromeExtensionWebContentsObserver::CreateForWebContents( |
416 web_contents_); | 553 web_contents_); |
417 | 554 |
418 // Register on-load actions. | 555 // Register on-load actions. |
419 embedder_message_dispatcher_.reset( | 556 embedder_message_dispatcher_.reset( |
420 DevToolsEmbedderMessageDispatcher::CreateForDevToolsFrontend(this)); | 557 DevToolsEmbedderMessageDispatcher::CreateForDevToolsFrontend(this)); |
421 | |
422 frontend_host_.reset(content::DevToolsFrontendHost::Create( | |
423 web_contents_->GetMainFrame(), | |
424 base::Bind(&DevToolsUIBindings::HandleMessageFromDevToolsFrontend, | |
425 base::Unretained(this)))); | |
426 } | 558 } |
427 | 559 |
428 DevToolsUIBindings::~DevToolsUIBindings() { | 560 DevToolsUIBindings::~DevToolsUIBindings() { |
429 for (const auto& pair : pending_requests_) | 561 for (const auto& pair : pending_requests_) |
430 delete pair.first; | 562 delete pair.first; |
431 | 563 |
432 if (agent_host_.get()) | 564 if (agent_host_.get()) |
433 agent_host_->DetachClient(this); | 565 agent_host_->DetachClient(this); |
434 | 566 |
435 for (IndexingJobsMap::const_iterator jobs_it(indexing_jobs_.begin()); | 567 for (IndexingJobsMap::const_iterator jobs_it(indexing_jobs_.begin()); |
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
872 | 1004 |
873 void DevToolsUIBindings::DispatchProtocolMessageFromDevToolsFrontend( | 1005 void DevToolsUIBindings::DispatchProtocolMessageFromDevToolsFrontend( |
874 const std::string& message) { | 1006 const std::string& message) { |
875 if (agent_host_.get()) | 1007 if (agent_host_.get()) |
876 agent_host_->DispatchProtocolMessage(this, message); | 1008 agent_host_->DispatchProtocolMessage(this, message); |
877 } | 1009 } |
878 | 1010 |
879 void DevToolsUIBindings::RecordEnumeratedHistogram(const std::string& name, | 1011 void DevToolsUIBindings::RecordEnumeratedHistogram(const std::string& name, |
880 int sample, | 1012 int sample, |
881 int boundary_value) { | 1013 int boundary_value) { |
| 1014 if (!frontend_host_) |
| 1015 return; |
882 if (!(boundary_value >= 0 && boundary_value <= 100 && sample >= 0 && | 1016 if (!(boundary_value >= 0 && boundary_value <= 100 && sample >= 0 && |
883 sample < boundary_value)) { | 1017 sample < boundary_value)) { |
884 // TODO(nick): Replace with chrome::bad_message::ReceivedBadMessage(). | 1018 // TODO(nick): Replace with chrome::bad_message::ReceivedBadMessage(). |
885 frontend_host_->BadMessageRecieved(); | 1019 frontend_host_->BadMessageRecieved(); |
886 return; | 1020 return; |
887 } | 1021 } |
888 // Each histogram name must follow a different code path in | 1022 // Each histogram name must follow a different code path in |
889 // order to UMA_HISTOGRAM_ENUMERATION work correctly. | 1023 // order to UMA_HISTOGRAM_ENUMERATION work correctly. |
890 if (name == kDevToolsActionTakenHistogram) | 1024 if (name == kDevToolsActionTakenHistogram) |
891 UMA_HISTOGRAM_ENUMERATION(name, sample, boundary_value); | 1025 UMA_HISTOGRAM_ENUMERATION(name, sample, boundary_value); |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1057 const InfoBarCallback& callback) { | 1191 const InfoBarCallback& callback) { |
1058 if (!delegate_->GetInfoBarService()) { | 1192 if (!delegate_->GetInfoBarService()) { |
1059 callback.Run(false); | 1193 callback.Run(false); |
1060 return; | 1194 return; |
1061 } | 1195 } |
1062 std::unique_ptr<DevToolsConfirmInfoBarDelegate> delegate( | 1196 std::unique_ptr<DevToolsConfirmInfoBarDelegate> delegate( |
1063 new DevToolsConfirmInfoBarDelegate(callback, message)); | 1197 new DevToolsConfirmInfoBarDelegate(callback, message)); |
1064 GlobalConfirmInfoBar::Show(std::move(delegate)); | 1198 GlobalConfirmInfoBar::Show(std::move(delegate)); |
1065 } | 1199 } |
1066 | 1200 |
| 1201 void DevToolsUIBindings::UpdateFrontendHost( |
| 1202 content::NavigationHandle* navigation_handle) { |
| 1203 if (!IsValidFrontendURL(navigation_handle->GetURL())) { |
| 1204 LOG(ERROR) << "Attempt to navigate to an invalid DevTools front-end URL: " |
| 1205 << navigation_handle->GetURL().spec(); |
| 1206 frontend_host_.reset(); |
| 1207 return; |
| 1208 } |
| 1209 frontend_host_.reset(content::DevToolsFrontendHost::Create( |
| 1210 navigation_handle->GetRenderFrameHost(), |
| 1211 base::Bind(&DevToolsUIBindings::HandleMessageFromDevToolsFrontend, |
| 1212 base::Unretained(this)))); |
| 1213 } |
| 1214 |
1067 void DevToolsUIBindings::AddDevToolsExtensionsToClient() { | 1215 void DevToolsUIBindings::AddDevToolsExtensionsToClient() { |
1068 const extensions::ExtensionRegistry* registry = | 1216 const extensions::ExtensionRegistry* registry = |
1069 extensions::ExtensionRegistry::Get(profile_->GetOriginalProfile()); | 1217 extensions::ExtensionRegistry::Get(profile_->GetOriginalProfile()); |
1070 if (!registry) | 1218 if (!registry) |
1071 return; | 1219 return; |
1072 | 1220 |
1073 base::ListValue results; | 1221 base::ListValue results; |
1074 for (const scoped_refptr<const extensions::Extension>& extension : | 1222 for (const scoped_refptr<const extensions::Extension>& extension : |
1075 registry->enabled_extensions()) { | 1223 registry->enabled_extensions()) { |
1076 if (extensions::chrome_manifest_urls::GetDevToolsPage(extension.get()) | 1224 if (extensions::chrome_manifest_urls::GetDevToolsPage(extension.get()) |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1128 } | 1276 } |
1129 | 1277 |
1130 bool DevToolsUIBindings::IsAttachedTo(content::DevToolsAgentHost* agent_host) { | 1278 bool DevToolsUIBindings::IsAttachedTo(content::DevToolsAgentHost* agent_host) { |
1131 return agent_host_.get() == agent_host; | 1279 return agent_host_.get() == agent_host; |
1132 } | 1280 } |
1133 | 1281 |
1134 void DevToolsUIBindings::CallClientFunction(const std::string& function_name, | 1282 void DevToolsUIBindings::CallClientFunction(const std::string& function_name, |
1135 const base::Value* arg1, | 1283 const base::Value* arg1, |
1136 const base::Value* arg2, | 1284 const base::Value* arg2, |
1137 const base::Value* arg3) { | 1285 const base::Value* arg3) { |
| 1286 if (!web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme)) |
| 1287 return; |
| 1288 // If we're not exposing bindings, we shouldn't call functions either. |
| 1289 if (!frontend_host_) |
| 1290 return; |
1138 std::string javascript = function_name + "("; | 1291 std::string javascript = function_name + "("; |
1139 if (arg1) { | 1292 if (arg1) { |
1140 std::string json; | 1293 std::string json; |
1141 base::JSONWriter::Write(*arg1, &json); | 1294 base::JSONWriter::Write(*arg1, &json); |
1142 javascript.append(json); | 1295 javascript.append(json); |
1143 if (arg2) { | 1296 if (arg2) { |
1144 base::JSONWriter::Write(*arg2, &json); | 1297 base::JSONWriter::Write(*arg2, &json); |
1145 javascript.append(", ").append(json); | 1298 javascript.append(", ").append(json); |
1146 if (arg3) { | 1299 if (arg3) { |
1147 base::JSONWriter::Write(*arg3, &json); | 1300 base::JSONWriter::Write(*arg3, &json); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1180 void DevToolsUIBindings::FrontendLoaded() { | 1333 void DevToolsUIBindings::FrontendLoaded() { |
1181 if (frontend_loaded_) | 1334 if (frontend_loaded_) |
1182 return; | 1335 return; |
1183 frontend_loaded_ = true; | 1336 frontend_loaded_ = true; |
1184 | 1337 |
1185 // Call delegate first - it seeds importants bit of information. | 1338 // Call delegate first - it seeds importants bit of information. |
1186 delegate_->OnLoadCompleted(); | 1339 delegate_->OnLoadCompleted(); |
1187 | 1340 |
1188 AddDevToolsExtensionsToClient(); | 1341 AddDevToolsExtensionsToClient(); |
1189 } | 1342 } |
OLD | NEW |