Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 // Implements the Chrome Extensions Debugger API. | 5 // Implements the Chrome Extensions Debugger API. |
| 6 | 6 |
| 7 #include "chrome/browser/extensions/api/debugger/debugger_api.h" | 7 #include "chrome/browser/extensions/api/debugger/debugger_api.h" |
| 8 | 8 |
| 9 #include <map> | 9 #include <map> |
| 10 #include <set> | 10 #include <set> |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 24 #include "chrome/browser/extensions/api/debugger/debugger_api_constants.h" | 24 #include "chrome/browser/extensions/api/debugger/debugger_api_constants.h" |
| 25 #include "chrome/browser/extensions/extension_service.h" | 25 #include "chrome/browser/extensions/extension_service.h" |
| 26 #include "chrome/browser/extensions/extension_tab_util.h" | 26 #include "chrome/browser/extensions/extension_tab_util.h" |
| 27 #include "chrome/browser/infobars/infobar_service.h" | 27 #include "chrome/browser/infobars/infobar_service.h" |
| 28 #include "chrome/browser/profiles/profile.h" | 28 #include "chrome/browser/profiles/profile.h" |
| 29 #include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h" | 29 #include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h" |
| 30 #include "chrome/common/chrome_switches.h" | 30 #include "chrome/common/chrome_switches.h" |
| 31 #include "components/infobars/core/confirm_infobar_delegate.h" | 31 #include "components/infobars/core/confirm_infobar_delegate.h" |
| 32 #include "components/infobars/core/infobar.h" | 32 #include "components/infobars/core/infobar.h" |
| 33 #include "content/public/browser/devtools_agent_host.h" | 33 #include "content/public/browser/devtools_agent_host.h" |
| 34 #include "content/public/browser/devtools_client_host.h" | |
| 35 #include "content/public/browser/devtools_http_handler.h" | 34 #include "content/public/browser/devtools_http_handler.h" |
| 36 #include "content/public/browser/devtools_manager.h" | |
| 37 #include "content/public/browser/notification_service.h" | 35 #include "content/public/browser/notification_service.h" |
| 38 #include "content/public/browser/notification_source.h" | 36 #include "content/public/browser/notification_source.h" |
| 39 #include "content/public/browser/render_process_host.h" | 37 #include "content/public/browser/render_process_host.h" |
| 40 #include "content/public/browser/render_view_host.h" | 38 #include "content/public/browser/render_view_host.h" |
| 41 #include "content/public/browser/render_widget_host.h" | 39 #include "content/public/browser/render_widget_host.h" |
| 42 #include "content/public/browser/web_contents.h" | 40 #include "content/public/browser/web_contents.h" |
| 43 #include "content/public/common/content_client.h" | 41 #include "content/public/common/content_client.h" |
| 44 #include "content/public/common/url_utils.h" | 42 #include "content/public/common/url_utils.h" |
| 45 #include "extensions/browser/event_router.h" | 43 #include "extensions/browser/event_router.h" |
| 46 #include "extensions/browser/extension_host.h" | 44 #include "extensions/browser/extension_host.h" |
| 47 #include "extensions/browser/extension_registry.h" | 45 #include "extensions/browser/extension_registry.h" |
| 48 #include "extensions/browser/extension_registry_observer.h" | 46 #include "extensions/browser/extension_registry_observer.h" |
| 49 #include "extensions/browser/extension_system.h" | 47 #include "extensions/browser/extension_system.h" |
| 50 #include "extensions/common/constants.h" | 48 #include "extensions/common/constants.h" |
| 51 #include "extensions/common/error_utils.h" | 49 #include "extensions/common/error_utils.h" |
| 52 #include "extensions/common/extension.h" | 50 #include "extensions/common/extension.h" |
| 53 #include "extensions/common/manifest_constants.h" | 51 #include "extensions/common/manifest_constants.h" |
| 54 #include "extensions/common/permissions/permissions_data.h" | 52 #include "extensions/common/permissions/permissions_data.h" |
| 55 #include "extensions/common/switches.h" | 53 #include "extensions/common/switches.h" |
| 56 #include "grit/generated_resources.h" | 54 #include "grit/generated_resources.h" |
| 57 #include "ui/base/l10n/l10n_util.h" | 55 #include "ui/base/l10n/l10n_util.h" |
| 58 | 56 |
| 59 using content::DevToolsAgentHost; | 57 using content::DevToolsAgentHost; |
| 60 using content::DevToolsClientHost; | |
| 61 using content::DevToolsHttpHandler; | 58 using content::DevToolsHttpHandler; |
| 62 using content::DevToolsManager; | |
| 63 using content::RenderProcessHost; | 59 using content::RenderProcessHost; |
| 64 using content::RenderViewHost; | 60 using content::RenderViewHost; |
| 65 using content::RenderWidgetHost; | 61 using content::RenderWidgetHost; |
| 66 using content::WebContents; | 62 using content::WebContents; |
| 67 | 63 |
| 68 namespace keys = debugger_api_constants; | 64 namespace keys = debugger_api_constants; |
| 69 namespace Attach = extensions::api::debugger::Attach; | 65 namespace Attach = extensions::api::debugger::Attach; |
| 70 namespace Detach = extensions::api::debugger::Detach; | 66 namespace Detach = extensions::api::debugger::Detach; |
| 71 namespace OnDetach = extensions::api::debugger::OnDetach; | 67 namespace OnDetach = extensions::api::debugger::OnDetach; |
| 72 namespace OnEvent = extensions::api::debugger::OnEvent; | 68 namespace OnEvent = extensions::api::debugger::OnEvent; |
| 73 namespace SendCommand = extensions::api::debugger::SendCommand; | 69 namespace SendCommand = extensions::api::debugger::SendCommand; |
| 74 | 70 |
| 75 namespace extensions { | 71 namespace extensions { |
| 76 class ExtensionRegistry; | 72 class ExtensionRegistry; |
| 77 | 73 |
| 78 // ExtensionDevToolsClientHost ------------------------------------------------ | 74 // ExtensionDevToolsClientHost ------------------------------------------------ |
| 79 | 75 |
| 80 class ExtensionDevToolsClientHost : public DevToolsClientHost, | 76 class ExtensionDevToolsClientHost : public DevToolsAgentHost::Client, |
| 81 public content::NotificationObserver, | 77 public content::NotificationObserver, |
| 82 public ExtensionRegistryObserver { | 78 public ExtensionRegistryObserver { |
| 83 public: | 79 public: |
| 84 ExtensionDevToolsClientHost(Profile* profile, | 80 ExtensionDevToolsClientHost(Profile* profile, |
| 85 DevToolsAgentHost* agent_host, | 81 DevToolsAgentHost* agent_host, |
| 86 const std::string& extension_id, | 82 const std::string& extension_id, |
| 87 const std::string& extension_name, | 83 const std::string& extension_name, |
| 88 const Debuggee& debuggee, | 84 const Debuggee& debuggee, |
| 89 infobars::InfoBar* infobar); | 85 infobars::InfoBar* infobar); |
| 90 | 86 |
| 91 virtual ~ExtensionDevToolsClientHost(); | 87 virtual ~ExtensionDevToolsClientHost(); |
| 92 | 88 |
| 93 const std::string& extension_id() { return extension_id_; } | 89 const std::string& extension_id() { return extension_id_; } |
| 90 DevToolsAgentHost* agent_host() { return agent_host_.get(); } | |
| 94 void Close(); | 91 void Close(); |
| 95 void SendMessageToBackend(DebuggerSendCommandFunction* function, | 92 void SendMessageToBackend(DebuggerSendCommandFunction* function, |
| 96 const std::string& method, | 93 const std::string& method, |
| 97 SendCommand::Params::CommandParams* command_params); | 94 SendCommand::Params::CommandParams* command_params); |
| 98 | 95 |
| 99 // Marks connection as to-be-terminated by the user. | 96 // Marks connection as to-be-terminated by the user. |
| 100 void MarkAsDismissed(); | 97 void MarkAsDismissed(); |
| 101 | 98 |
| 102 // DevToolsClientHost interface | 99 // DevToolsAgentHost::Client interface. |
| 103 virtual void InspectedContentsClosing() OVERRIDE; | 100 virtual void AgentHostDetached( |
| 104 virtual void DispatchOnInspectorFrontend(const std::string& message) OVERRIDE; | 101 DevToolsAgentHost* agent_host, |
| 105 virtual void ReplacedWithAnotherClient() OVERRIDE; | 102 DevToolsAgentHost::DetachReason reason) OVERRIDE; |
| 103 virtual void SendMessageFromAgentHost( | |
| 104 DevToolsAgentHost* agent_host, | |
| 105 const std::string& message) OVERRIDE; | |
| 106 | 106 |
| 107 private: | 107 private: |
| 108 void SendDetachedEvent(); | 108 void SendDetachedEvent(); |
| 109 | 109 |
| 110 // content::NotificationObserver implementation. | 110 // content::NotificationObserver implementation. |
| 111 virtual void Observe(int type, | 111 virtual void Observe(int type, |
| 112 const content::NotificationSource& source, | 112 const content::NotificationSource& source, |
| 113 const content::NotificationDetails& details) OVERRIDE; | 113 const content::NotificationDetails& details) OVERRIDE; |
| 114 | 114 |
| 115 // ExtensionRegistryObserver implementation. | 115 // ExtensionRegistryObserver implementation. |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 286 client_hosts_.insert(client_host); | 286 client_hosts_.insert(client_host); |
| 287 } | 287 } |
| 288 | 288 |
| 289 void AttachedClientHosts::Remove(ExtensionDevToolsClientHost* client_host) { | 289 void AttachedClientHosts::Remove(ExtensionDevToolsClientHost* client_host) { |
| 290 client_hosts_.erase(client_host); | 290 client_hosts_.erase(client_host); |
| 291 } | 291 } |
| 292 | 292 |
| 293 ExtensionDevToolsClientHost* AttachedClientHosts::Lookup( | 293 ExtensionDevToolsClientHost* AttachedClientHosts::Lookup( |
| 294 DevToolsAgentHost* agent_host, | 294 DevToolsAgentHost* agent_host, |
| 295 const std::string& extension_id) { | 295 const std::string& extension_id) { |
| 296 DevToolsManager* manager = DevToolsManager::GetInstance(); | |
| 297 for (ClientHosts::iterator it = client_hosts_.begin(); | 296 for (ClientHosts::iterator it = client_hosts_.begin(); |
| 298 it != client_hosts_.end(); ++it) { | 297 it != client_hosts_.end(); ++it) { |
| 299 ExtensionDevToolsClientHost* client_host = *it; | 298 ExtensionDevToolsClientHost* client_host = *it; |
| 300 if (manager->GetDevToolsAgentHostFor(client_host) == agent_host && | 299 if (client_host->agent_host() == agent_host && |
| 301 client_host->extension_id() == extension_id) | 300 client_host->extension_id() == extension_id) |
| 302 return client_host; | 301 return client_host; |
| 303 } | 302 } |
| 304 return NULL; | 303 return NULL; |
| 305 } | 304 } |
| 306 | 305 |
| 307 } // namespace | 306 } // namespace |
| 308 | 307 |
| 309 | 308 |
| 310 // ExtensionDevToolsClientHost ------------------------------------------------ | 309 // ExtensionDevToolsClientHost ------------------------------------------------ |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 331 // from there. | 330 // from there. |
| 332 extension_registry_observer_.Add(ExtensionRegistry::Get(profile_)); | 331 extension_registry_observer_.Add(ExtensionRegistry::Get(profile_)); |
| 333 | 332 |
| 334 // RVH-based agents disconnect from their clients when the app is terminating | 333 // RVH-based agents disconnect from their clients when the app is terminating |
| 335 // but shared worker-based agents do not. | 334 // but shared worker-based agents do not. |
| 336 // Disconnect explicitly to make sure that |this| observer is not leaked. | 335 // Disconnect explicitly to make sure that |this| observer is not leaked. |
| 337 registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, | 336 registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, |
| 338 content::NotificationService::AllSources()); | 337 content::NotificationService::AllSources()); |
| 339 | 338 |
| 340 // Attach to debugger and tell it we are ready. | 339 // Attach to debugger and tell it we are ready. |
| 341 DevToolsManager::GetInstance()->RegisterDevToolsClientHostFor( | 340 agent_host_->AttachClient(this); |
| 342 agent_host_.get(), this); | |
| 343 | 341 |
| 344 if (infobar_) { | 342 if (infobar_) { |
| 345 static_cast<ExtensionDevToolsInfoBarDelegate*>( | 343 static_cast<ExtensionDevToolsInfoBarDelegate*>( |
| 346 infobar_->delegate())->set_client_host(this); | 344 infobar_->delegate())->set_client_host(this); |
| 347 registrar_.Add( | 345 registrar_.Add( |
| 348 this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, | 346 this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, |
| 349 content::Source<InfoBarService>(InfoBarService::FromWebContents( | 347 content::Source<InfoBarService>(InfoBarService::FromWebContents( |
| 350 WebContents::FromRenderViewHost( | 348 WebContents::FromRenderViewHost( |
| 351 agent_host_->GetRenderViewHost())))); | 349 agent_host_->GetRenderViewHost())))); |
| 352 } | 350 } |
| 353 } | 351 } |
| 354 | 352 |
| 355 ExtensionDevToolsClientHost::~ExtensionDevToolsClientHost() { | 353 ExtensionDevToolsClientHost::~ExtensionDevToolsClientHost() { |
| 356 // Ensure calling RemoveInfoBar() below won't result in Observe() trying to | 354 // Ensure calling RemoveInfoBar() below won't result in Observe() trying to |
| 357 // Close() us. | 355 // Close() us. |
| 358 registrar_.RemoveAll(); | 356 registrar_.RemoveAll(); |
| 359 | 357 |
| 360 if (infobar_) { | 358 if (infobar_) { |
| 361 static_cast<ExtensionDevToolsInfoBarDelegate*>( | 359 static_cast<ExtensionDevToolsInfoBarDelegate*>( |
| 362 infobar_->delegate())->set_client_host(NULL); | 360 infobar_->delegate())->set_client_host(NULL); |
| 363 InfoBarService* infobar_service = InfoBarService::FromWebContents( | 361 InfoBarService* infobar_service = InfoBarService::FromWebContents( |
| 364 WebContents::FromRenderViewHost(agent_host_->GetRenderViewHost())); | 362 WebContents::FromRenderViewHost(agent_host_->GetRenderViewHost())); |
| 365 infobar_service->RemoveInfoBar(infobar_); | 363 infobar_service->RemoveInfoBar(infobar_); |
| 366 } | 364 } |
| 367 AttachedClientHosts::GetInstance()->Remove(this); | 365 AttachedClientHosts::GetInstance()->Remove(this); |
| 368 } | 366 } |
| 369 | 367 |
| 370 // DevToolsClientHost interface | 368 // DevToolsAgentHost::Client implementation. |
| 371 void ExtensionDevToolsClientHost::InspectedContentsClosing() { | 369 void ExtensionDevToolsClientHost::AgentHostDetached( |
| 372 SendDetachedEvent(); | 370 DevToolsAgentHost* agent_host, DevToolsAgentHost::DetachReason reason) { |
| 371 DCHECK(agent_host == agent_host_.get()); | |
| 372 if (reason != DevToolsAgentHost::DETACHED_BY_CLIENT) { | |
| 373 if (reason == DevToolsAgentHost::REPLACED_WITH_ANOTHER_CLIENT) | |
| 374 detach_reason_ = OnDetach::REASON_REPLACED_WITH_DEVTOOLS; | |
| 375 SendDetachedEvent(); | |
| 376 } | |
| 377 agent_host_ = NULL; | |
| 373 delete this; | 378 delete this; |
|
pfeldman
2014/08/07 15:40:30
Are you now deleting things twice?
dgozman
2014/08/07 16:51:52
Yes, fixed.
| |
| 374 } | 379 } |
| 375 | 380 |
| 376 void ExtensionDevToolsClientHost::ReplacedWithAnotherClient() { | |
| 377 detach_reason_ = OnDetach::REASON_REPLACED_WITH_DEVTOOLS; | |
| 378 } | |
| 379 | |
| 380 void ExtensionDevToolsClientHost::Close() { | 381 void ExtensionDevToolsClientHost::Close() { |
| 381 DevToolsManager::GetInstance()->ClientHostClosing(this); | 382 agent_host_->DetachClient(); |
| 382 delete this; | 383 delete this; |
| 383 } | 384 } |
| 384 | 385 |
| 385 void ExtensionDevToolsClientHost::SendMessageToBackend( | 386 void ExtensionDevToolsClientHost::SendMessageToBackend( |
| 386 DebuggerSendCommandFunction* function, | 387 DebuggerSendCommandFunction* function, |
| 387 const std::string& method, | 388 const std::string& method, |
| 388 SendCommand::Params::CommandParams* command_params) { | 389 SendCommand::Params::CommandParams* command_params) { |
| 389 base::DictionaryValue protocol_request; | 390 base::DictionaryValue protocol_request; |
| 390 int request_id = ++last_request_id_; | 391 int request_id = ++last_request_id_; |
| 391 pending_requests_[request_id] = function; | 392 pending_requests_[request_id] = function; |
| 392 protocol_request.SetInteger("id", request_id); | 393 protocol_request.SetInteger("id", request_id); |
| 393 protocol_request.SetString("method", method); | 394 protocol_request.SetString("method", method); |
| 394 if (command_params) { | 395 if (command_params) { |
| 395 protocol_request.Set("params", | 396 protocol_request.Set("params", |
| 396 command_params->additional_properties.DeepCopy()); | 397 command_params->additional_properties.DeepCopy()); |
| 397 } | 398 } |
| 398 | 399 |
| 399 std::string json_args; | 400 std::string json_args; |
| 400 base::JSONWriter::Write(&protocol_request, &json_args); | 401 base::JSONWriter::Write(&protocol_request, &json_args); |
| 401 DevToolsManager::GetInstance()->DispatchOnInspectorBackend(this, json_args); | 402 agent_host_->DispatchOnInspectorBackend(json_args); |
| 402 } | 403 } |
| 403 | 404 |
| 404 void ExtensionDevToolsClientHost::MarkAsDismissed() { | 405 void ExtensionDevToolsClientHost::MarkAsDismissed() { |
| 405 detach_reason_ = OnDetach::REASON_CANCELED_BY_USER; | 406 detach_reason_ = OnDetach::REASON_CANCELED_BY_USER; |
| 406 } | 407 } |
| 407 | 408 |
| 408 void ExtensionDevToolsClientHost::SendDetachedEvent() { | 409 void ExtensionDevToolsClientHost::SendDetachedEvent() { |
| 409 if (!EventRouter::Get(profile_)) | 410 if (!EventRouter::Get(profile_)) |
| 410 return; | 411 return; |
| 411 | 412 |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 439 infobar_ = NULL; | 440 infobar_ = NULL; |
| 440 SendDetachedEvent(); | 441 SendDetachedEvent(); |
| 441 Close(); | 442 Close(); |
| 442 } | 443 } |
| 443 break; | 444 break; |
| 444 default: | 445 default: |
| 445 NOTREACHED(); | 446 NOTREACHED(); |
| 446 } | 447 } |
| 447 } | 448 } |
| 448 | 449 |
| 449 void ExtensionDevToolsClientHost::DispatchOnInspectorFrontend( | 450 void ExtensionDevToolsClientHost::SendMessageFromAgentHost( |
| 450 const std::string& message) { | 451 DevToolsAgentHost* agent_host, const std::string& message) { |
| 452 DCHECK(agent_host == agent_host_.get()); | |
| 451 if (!EventRouter::Get(profile_)) | 453 if (!EventRouter::Get(profile_)) |
| 452 return; | 454 return; |
| 453 | 455 |
| 454 scoped_ptr<base::Value> result(base::JSONReader::Read(message)); | 456 scoped_ptr<base::Value> result(base::JSONReader::Read(message)); |
| 455 if (!result->IsType(base::Value::TYPE_DICTIONARY)) | 457 if (!result->IsType(base::Value::TYPE_DICTIONARY)) |
| 456 return; | 458 return; |
| 457 base::DictionaryValue* dictionary = | 459 base::DictionaryValue* dictionary = |
| 458 static_cast<base::DictionaryValue*>(result.get()); | 460 static_cast<base::DictionaryValue*>(result.get()); |
| 459 | 461 |
| 460 int id; | 462 int id; |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 745 const std::vector<DevToolsTargetImpl*>& target_list) { | 747 const std::vector<DevToolsTargetImpl*>& target_list) { |
| 746 scoped_ptr<base::ListValue> result(new base::ListValue()); | 748 scoped_ptr<base::ListValue> result(new base::ListValue()); |
| 747 for (size_t i = 0; i < target_list.size(); ++i) | 749 for (size_t i = 0; i < target_list.size(); ++i) |
| 748 result->Append(SerializeTarget(*target_list[i])); | 750 result->Append(SerializeTarget(*target_list[i])); |
| 749 STLDeleteContainerPointers(target_list.begin(), target_list.end()); | 751 STLDeleteContainerPointers(target_list.begin(), target_list.end()); |
| 750 SetResult(result.release()); | 752 SetResult(result.release()); |
| 751 SendResponse(true); | 753 SendResponse(true); |
| 752 } | 754 } |
| 753 | 755 |
| 754 } // namespace extensions | 756 } // namespace extensions |
| OLD | NEW |