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 "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/json/json_reader.h" | 8 #include "base/json/json_reader.h" |
9 #include "base/json/json_writer.h" | 9 #include "base/json/json_writer.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
(...skipping 29 matching lines...) Expand all Loading... | |
40 #include "content/public/browser/notification_source.h" | 40 #include "content/public/browser/notification_source.h" |
41 #include "content/public/browser/render_frame_host.h" | 41 #include "content/public/browser/render_frame_host.h" |
42 #include "content/public/browser/render_view_host.h" | 42 #include "content/public/browser/render_view_host.h" |
43 #include "content/public/browser/user_metrics.h" | 43 #include "content/public/browser/user_metrics.h" |
44 #include "content/public/browser/web_contents.h" | 44 #include "content/public/browser/web_contents.h" |
45 #include "content/public/browser/web_contents_observer.h" | 45 #include "content/public/browser/web_contents_observer.h" |
46 #include "content/public/common/renderer_preferences.h" | 46 #include "content/public/common/renderer_preferences.h" |
47 #include "content/public/common/url_constants.h" | 47 #include "content/public/common/url_constants.h" |
48 #include "extensions/browser/extension_registry.h" | 48 #include "extensions/browser/extension_registry.h" |
49 #include "extensions/common/permissions/permissions_data.h" | 49 #include "extensions/common/permissions/permissions_data.h" |
50 #include "net/base/io_buffer.h" | |
51 #include "net/base/net_errors.h" | |
52 #include "net/http/http_response_headers.h" | |
53 #include "net/url_request/url_fetcher.h" | |
54 #include "net/url_request/url_fetcher_response_writer.h" | |
50 #include "ui/base/l10n/l10n_util.h" | 55 #include "ui/base/l10n/l10n_util.h" |
51 #include "ui/base/page_transition_types.h" | 56 #include "ui/base/page_transition_types.h" |
52 | 57 |
53 using base::DictionaryValue; | 58 using base::DictionaryValue; |
54 using content::BrowserThread; | 59 using content::BrowserThread; |
55 | 60 |
56 namespace content { | 61 namespace content { |
57 struct LoadCommittedDetails; | 62 struct LoadCommittedDetails; |
58 struct FrameNavigateParams; | 63 struct FrameNavigateParams; |
59 } | 64 } |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
226 } | 231 } |
227 | 232 |
228 void DefaultBindingsDelegate::InspectedContentsClosing() { | 233 void DefaultBindingsDelegate::InspectedContentsClosing() { |
229 web_contents_->GetRenderViewHost()->ClosePage(); | 234 web_contents_->GetRenderViewHost()->ClosePage(); |
230 } | 235 } |
231 | 236 |
232 InfoBarService* DefaultBindingsDelegate::GetInfoBarService() { | 237 InfoBarService* DefaultBindingsDelegate::GetInfoBarService() { |
233 return InfoBarService::FromWebContents(web_contents_); | 238 return InfoBarService::FromWebContents(web_contents_); |
234 } | 239 } |
235 | 240 |
241 // ResponseWriter ------------------------------------------------------------- | |
242 | |
243 class ResponseWriter : public net::URLFetcherResponseWriter { | |
244 public: | |
245 ResponseWriter(DevToolsUIBindings* bindings, int stream_id); | |
246 ~ResponseWriter() override; | |
247 | |
248 // URLFetcherResponseWriter overrides: | |
249 int Initialize(const net::CompletionCallback& callback) override; | |
250 int Write(net::IOBuffer* buffer, | |
251 int num_bytes, | |
252 const net::CompletionCallback& callback) override; | |
253 int Finish(const net::CompletionCallback& callback) override; | |
254 | |
255 private: | |
256 DevToolsUIBindings* bindings_; | |
257 int stream_id_; | |
258 | |
259 DISALLOW_COPY_AND_ASSIGN(ResponseWriter); | |
260 }; | |
261 | |
262 ResponseWriter::ResponseWriter(DevToolsUIBindings* bindings, | |
263 int stream_id) | |
264 : bindings_(bindings), | |
265 stream_id_(stream_id) { | |
266 } | |
267 | |
268 ResponseWriter::~ResponseWriter() { | |
269 } | |
270 | |
271 int ResponseWriter::Initialize(const net::CompletionCallback& callback) { | |
272 return net::OK; | |
273 } | |
274 | |
275 int ResponseWriter::Write(net::IOBuffer* buffer, | |
276 int num_bytes, | |
277 const net::CompletionCallback& callback) { | |
278 base::FundamentalValue id(stream_id_); | |
279 base::StringValue chunk(std::string(buffer->data(), num_bytes)); | |
280 bindings_->CallClientFunction( | |
281 "DevToolsAPI.streamWrite", &id, &chunk, nullptr); | |
282 return num_bytes; | |
283 } | |
284 | |
285 int ResponseWriter::Finish(const net::CompletionCallback& callback) { | |
286 base::FundamentalValue id(stream_id_); | |
287 bindings_->CallClientFunction( | |
288 "DevToolsAPI.streamFinish", &id, nullptr, nullptr); | |
289 return net::OK; | |
290 } | |
291 | |
236 } // namespace | 292 } // namespace |
237 | 293 |
238 // DevToolsUIBindings::FrontendWebContentsObserver ---------------------------- | 294 // DevToolsUIBindings::FrontendWebContentsObserver ---------------------------- |
239 | 295 |
240 class DevToolsUIBindings::FrontendWebContentsObserver | 296 class DevToolsUIBindings::FrontendWebContentsObserver |
241 : public content::WebContentsObserver { | 297 : public content::WebContentsObserver { |
242 public: | 298 public: |
243 explicit FrontendWebContentsObserver(DevToolsUIBindings* ui_bindings); | 299 explicit FrontendWebContentsObserver(DevToolsUIBindings* ui_bindings); |
244 ~FrontendWebContentsObserver() override; | 300 ~FrontendWebContentsObserver() override; |
245 | 301 |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
376 ThemeServiceFactory::GetForProfile(profile_))); | 432 ThemeServiceFactory::GetForProfile(profile_))); |
377 | 433 |
378 embedder_message_dispatcher_.reset( | 434 embedder_message_dispatcher_.reset( |
379 DevToolsEmbedderMessageDispatcher::CreateForDevToolsFrontend(this)); | 435 DevToolsEmbedderMessageDispatcher::CreateForDevToolsFrontend(this)); |
380 | 436 |
381 frontend_host_.reset(content::DevToolsFrontendHost::Create( | 437 frontend_host_.reset(content::DevToolsFrontendHost::Create( |
382 web_contents_->GetMainFrame(), this)); | 438 web_contents_->GetMainFrame(), this)); |
383 } | 439 } |
384 | 440 |
385 DevToolsUIBindings::~DevToolsUIBindings() { | 441 DevToolsUIBindings::~DevToolsUIBindings() { |
442 for (const auto& pair : pending_requests_) | |
443 delete pair.first; | |
444 | |
386 if (agent_host_.get()) | 445 if (agent_host_.get()) |
387 agent_host_->DetachClient(); | 446 agent_host_->DetachClient(); |
388 | 447 |
389 for (IndexingJobsMap::const_iterator jobs_it(indexing_jobs_.begin()); | 448 for (IndexingJobsMap::const_iterator jobs_it(indexing_jobs_.begin()); |
390 jobs_it != indexing_jobs_.end(); ++jobs_it) { | 449 jobs_it != indexing_jobs_.end(); ++jobs_it) { |
391 jobs_it->second->Stop(); | 450 jobs_it->second->Stop(); |
392 } | 451 } |
393 indexing_jobs_.clear(); | 452 indexing_jobs_.clear(); |
394 SetDeviceCountUpdatesEnabled(0, false); | 453 SetDeviceCountUpdatesEnabled(0, false); |
395 SetDevicesUpdatesEnabled(0, false); | 454 SetDevicesUpdatesEnabled(0, false); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
459 } | 518 } |
460 | 519 |
461 void DevToolsUIBindings::AgentHostClosed( | 520 void DevToolsUIBindings::AgentHostClosed( |
462 content::DevToolsAgentHost* agent_host, | 521 content::DevToolsAgentHost* agent_host, |
463 bool replaced_with_another_client) { | 522 bool replaced_with_another_client) { |
464 DCHECK(agent_host == agent_host_.get()); | 523 DCHECK(agent_host == agent_host_.get()); |
465 agent_host_ = NULL; | 524 agent_host_ = NULL; |
466 delegate_->InspectedContentsClosing(); | 525 delegate_->InspectedContentsClosing(); |
467 } | 526 } |
468 | 527 |
469 void DevToolsUIBindings::SendMessageAck(int request_id) { | 528 void DevToolsUIBindings::SendMessageAck(int request_id, |
529 const base::Value* arg) { | |
470 base::FundamentalValue id_value(request_id); | 530 base::FundamentalValue id_value(request_id); |
471 CallClientFunction("DevToolsAPI.embedderMessageAck", | 531 CallClientFunction("DevToolsAPI.embedderMessageAck", |
472 &id_value, nullptr, nullptr); | 532 &id_value, arg, nullptr); |
473 } | 533 } |
474 | 534 |
475 // DevToolsEmbedderMessageDispatcher::Delegate implementation ----------------- | 535 // DevToolsEmbedderMessageDispatcher::Delegate implementation ----------------- |
476 void DevToolsUIBindings::ActivateWindow(int request_id) { | 536 void DevToolsUIBindings::ActivateWindow(int request_id) { |
477 delegate_->ActivateWindow(); | 537 delegate_->ActivateWindow(); |
478 } | 538 } |
479 | 539 |
480 void DevToolsUIBindings::CloseWindow(int request_id) { | 540 void DevToolsUIBindings::CloseWindow(int request_id) { |
481 delegate_->CloseWindow(); | 541 delegate_->CloseWindow(); |
482 } | 542 } |
483 | 543 |
484 void DevToolsUIBindings::LoadCompleted(int request_id) { | 544 void DevToolsUIBindings::LoadCompleted(int request_id) { |
485 FrontendLoaded(); | 545 FrontendLoaded(); |
486 } | 546 } |
487 | 547 |
488 void DevToolsUIBindings::SetInspectedPageBounds(int request_id, | 548 void DevToolsUIBindings::SetInspectedPageBounds(int request_id, |
489 const gfx::Rect& rect) { | 549 const gfx::Rect& rect) { |
490 delegate_->SetInspectedPageBounds(rect); | 550 delegate_->SetInspectedPageBounds(rect); |
491 } | 551 } |
492 | 552 |
493 void DevToolsUIBindings::SetIsDocked(int request_id, bool dock_requested) { | 553 void DevToolsUIBindings::SetIsDocked(int request_id, bool dock_requested) { |
494 delegate_->SetIsDocked(dock_requested); | 554 delegate_->SetIsDocked(dock_requested); |
495 SendMessageAck(request_id); | 555 SendMessageAck(request_id, nullptr); |
496 } | 556 } |
497 | 557 |
498 void DevToolsUIBindings::InspectElementCompleted(int request_id) { | 558 void DevToolsUIBindings::InspectElementCompleted(int request_id) { |
499 delegate_->InspectElementCompleted(); | 559 delegate_->InspectElementCompleted(); |
500 } | 560 } |
501 | 561 |
502 void DevToolsUIBindings::InspectedURLChanged(int request_id, | 562 void DevToolsUIBindings::InspectedURLChanged(int request_id, |
503 const std::string& url) { | 563 const std::string& url) { |
504 content::NavigationController& controller = web_contents()->GetController(); | 564 content::NavigationController& controller = web_contents()->GetController(); |
505 content::NavigationEntry* entry = controller.GetActiveEntry(); | 565 content::NavigationEntry* entry = controller.GetActiveEntry(); |
506 // DevTools UI is not localized. | 566 // DevTools UI is not localized. |
507 entry->SetTitle( | 567 entry->SetTitle( |
508 base::UTF8ToUTF16(base::StringPrintf(kTitleFormat, url.c_str()))); | 568 base::UTF8ToUTF16(base::StringPrintf(kTitleFormat, url.c_str()))); |
509 web_contents()->NotifyNavigationStateChanged(content::INVALIDATE_TYPE_TITLE); | 569 web_contents()->NotifyNavigationStateChanged(content::INVALIDATE_TYPE_TITLE); |
510 } | 570 } |
511 | 571 |
572 void DevToolsUIBindings::LoadNetworkResource(int request_id, | |
573 const std::string& url, | |
574 const std::string& headers, | |
575 int stream_id) { | |
576 GURL gurl(url); | |
577 if (!gurl.is_valid()) { | |
578 base::DictionaryValue response; | |
579 response.SetInteger("statusCode", 404); | |
580 SendMessageAck(request_id, &response); | |
dgozman
2015/02/27 20:23:01
DevToolsAPI.streamFinish before ack?
pfeldman
2015/02/27 20:37:42
Lets make client responsible for this.
| |
581 return; | |
582 } | |
583 | |
584 net::URLFetcher* fetcher = | |
585 net::URLFetcher::Create(gurl, net::URLFetcher::GET, this); | |
586 pending_requests_[fetcher] = request_id; | |
587 fetcher->SetRequestContext(profile_->GetRequestContext()); | |
588 fetcher->SetExtraRequestHeaders(headers); | |
589 fetcher->SaveResponseWithWriter(scoped_ptr<net::URLFetcherResponseWriter>( | |
590 new ResponseWriter(this, stream_id))); | |
591 fetcher->Start(); | |
592 } | |
593 | |
512 void DevToolsUIBindings::OpenInNewTab(int request_id, const std::string& url) { | 594 void DevToolsUIBindings::OpenInNewTab(int request_id, const std::string& url) { |
513 delegate_->OpenInNewTab(url); | 595 delegate_->OpenInNewTab(url); |
514 } | 596 } |
515 | 597 |
516 void DevToolsUIBindings::SaveToFile(int request_id, | 598 void DevToolsUIBindings::SaveToFile(int request_id, |
517 const std::string& url, | 599 const std::string& url, |
518 const std::string& content, | 600 const std::string& content, |
519 bool save_as) { | 601 bool save_as) { |
520 file_helper_->Save(url, content, save_as, | 602 file_helper_->Save(url, content, save_as, |
521 base::Bind(&DevToolsUIBindings::FileSavedAs, | 603 base::Bind(&DevToolsUIBindings::FileSavedAs, |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
697 | 779 |
698 void DevToolsUIBindings::RecordActionUMA(int request_id, | 780 void DevToolsUIBindings::RecordActionUMA(int request_id, |
699 const std::string& name, | 781 const std::string& name, |
700 int action) { | 782 int action) { |
701 if (name == kDevToolsActionTakenHistogram) | 783 if (name == kDevToolsActionTakenHistogram) |
702 UMA_HISTOGRAM_ENUMERATION(name, action, kDevToolsActionTakenBoundary); | 784 UMA_HISTOGRAM_ENUMERATION(name, action, kDevToolsActionTakenBoundary); |
703 else if (name == kDevToolsPanelShownHistogram) | 785 else if (name == kDevToolsPanelShownHistogram) |
704 UMA_HISTOGRAM_ENUMERATION(name, action, kDevToolsPanelShownBoundary); | 786 UMA_HISTOGRAM_ENUMERATION(name, action, kDevToolsPanelShownBoundary); |
705 } | 787 } |
706 | 788 |
789 void DevToolsUIBindings::OnURLFetchComplete(const net::URLFetcher* source) { | |
790 DCHECK(source); | |
791 PendingRequestsMap::iterator it = pending_requests_.find(source); | |
792 DCHECK(it != pending_requests_.end()); | |
793 | |
794 base::DictionaryValue response; | |
795 base::DictionaryValue* headers = new base::DictionaryValue(); | |
796 net::HttpResponseHeaders* rh = source->GetResponseHeaders(); | |
797 response.SetInteger("statusCode", rh ? rh->response_code() : 200); | |
798 response.Set("headers", headers); | |
799 | |
800 void* iterator = NULL; | |
801 std::string name; | |
802 std::string value; | |
803 while (rh && rh->EnumerateHeaderLines(&iterator, &name, &value)) | |
804 headers->SetString(name, value); | |
805 | |
806 SendMessageAck(it->second, &response); | |
807 pending_requests_.erase(it); | |
808 delete source; | |
809 } | |
810 | |
707 void DevToolsUIBindings::DeviceCountChanged(int count) { | 811 void DevToolsUIBindings::DeviceCountChanged(int count) { |
708 base::FundamentalValue value(count); | 812 base::FundamentalValue value(count); |
709 CallClientFunction("DevToolsAPI.deviceCountUpdated", &value, NULL, | 813 CallClientFunction("DevToolsAPI.deviceCountUpdated", &value, NULL, |
710 NULL); | 814 NULL); |
711 } | 815 } |
712 | 816 |
713 void DevToolsUIBindings::DevicesUpdated( | 817 void DevToolsUIBindings::DevicesUpdated( |
714 const std::string& source, | 818 const std::string& source, |
715 const base::ListValue& targets) { | 819 const base::ListValue& targets) { |
716 CallClientFunction("DevToolsAPI.devicesUpdated", &targets, NULL, | 820 CallClientFunction("DevToolsAPI.devicesUpdated", &targets, NULL, |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
919 if (frontend_loaded_) | 1023 if (frontend_loaded_) |
920 return; | 1024 return; |
921 frontend_loaded_ = true; | 1025 frontend_loaded_ = true; |
922 | 1026 |
923 // Call delegate first - it seeds importants bit of information. | 1027 // Call delegate first - it seeds importants bit of information. |
924 delegate_->OnLoadCompleted(); | 1028 delegate_->OnLoadCompleted(); |
925 | 1029 |
926 UpdateTheme(); | 1030 UpdateTheme(); |
927 AddDevToolsExtensionsToClient(); | 1031 AddDevToolsExtensionsToClient(); |
928 } | 1032 } |
OLD | NEW |