| 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 content::DevToolsAgentHostClient, |
| 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 // DevToolsAgentHostClient interface. |
| 103 virtual void InspectedContentsClosing() OVERRIDE; | 100 virtual void AgentHostClosed( |
| 104 virtual void DispatchOnInspectorFrontend(const std::string& message) OVERRIDE; | 101 DevToolsAgentHost* agent_host, |
| 105 virtual void ReplacedWithAnotherClient() OVERRIDE; | 102 bool replaced_with_another_client) OVERRIDE; |
| 103 virtual void DispatchProtocolMessage( |
| 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 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 client_hosts_.insert(client_host); | 282 client_hosts_.insert(client_host); |
| 283 } | 283 } |
| 284 | 284 |
| 285 void AttachedClientHosts::Remove(ExtensionDevToolsClientHost* client_host) { | 285 void AttachedClientHosts::Remove(ExtensionDevToolsClientHost* client_host) { |
| 286 client_hosts_.erase(client_host); | 286 client_hosts_.erase(client_host); |
| 287 } | 287 } |
| 288 | 288 |
| 289 ExtensionDevToolsClientHost* AttachedClientHosts::Lookup( | 289 ExtensionDevToolsClientHost* AttachedClientHosts::Lookup( |
| 290 DevToolsAgentHost* agent_host, | 290 DevToolsAgentHost* agent_host, |
| 291 const std::string& extension_id) { | 291 const std::string& extension_id) { |
| 292 DevToolsManager* manager = DevToolsManager::GetInstance(); | |
| 293 for (ClientHosts::iterator it = client_hosts_.begin(); | 292 for (ClientHosts::iterator it = client_hosts_.begin(); |
| 294 it != client_hosts_.end(); ++it) { | 293 it != client_hosts_.end(); ++it) { |
| 295 ExtensionDevToolsClientHost* client_host = *it; | 294 ExtensionDevToolsClientHost* client_host = *it; |
| 296 if (manager->GetDevToolsAgentHostFor(client_host) == agent_host && | 295 if (client_host->agent_host() == agent_host && |
| 297 client_host->extension_id() == extension_id) | 296 client_host->extension_id() == extension_id) |
| 298 return client_host; | 297 return client_host; |
| 299 } | 298 } |
| 300 return NULL; | 299 return NULL; |
| 301 } | 300 } |
| 302 | 301 |
| 303 } // namespace | 302 } // namespace |
| 304 | 303 |
| 305 | 304 |
| 306 // ExtensionDevToolsClientHost ------------------------------------------------ | 305 // ExtensionDevToolsClientHost ------------------------------------------------ |
| (...skipping 20 matching lines...) Expand all Loading... |
| 327 // from there. | 326 // from there. |
| 328 extension_registry_observer_.Add(ExtensionRegistry::Get(profile_)); | 327 extension_registry_observer_.Add(ExtensionRegistry::Get(profile_)); |
| 329 | 328 |
| 330 // RVH-based agents disconnect from their clients when the app is terminating | 329 // RVH-based agents disconnect from their clients when the app is terminating |
| 331 // but shared worker-based agents do not. | 330 // but shared worker-based agents do not. |
| 332 // Disconnect explicitly to make sure that |this| observer is not leaked. | 331 // Disconnect explicitly to make sure that |this| observer is not leaked. |
| 333 registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, | 332 registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, |
| 334 content::NotificationService::AllSources()); | 333 content::NotificationService::AllSources()); |
| 335 | 334 |
| 336 // Attach to debugger and tell it we are ready. | 335 // Attach to debugger and tell it we are ready. |
| 337 DevToolsManager::GetInstance()->RegisterDevToolsClientHostFor( | 336 agent_host_->AttachClient(this); |
| 338 agent_host_.get(), this); | |
| 339 | 337 |
| 340 if (infobar_) { | 338 if (infobar_) { |
| 341 static_cast<ExtensionDevToolsInfoBarDelegate*>( | 339 static_cast<ExtensionDevToolsInfoBarDelegate*>( |
| 342 infobar_->delegate())->set_client_host(this); | 340 infobar_->delegate())->set_client_host(this); |
| 343 registrar_.Add( | 341 registrar_.Add( |
| 344 this, | 342 this, |
| 345 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, | 343 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, |
| 346 content::Source<InfoBarService>( | 344 content::Source<InfoBarService>( |
| 347 InfoBarService::FromWebContents(agent_host_->GetWebContents()))); | 345 InfoBarService::FromWebContents(agent_host_->GetWebContents()))); |
| 348 } | 346 } |
| 349 } | 347 } |
| 350 | 348 |
| 351 ExtensionDevToolsClientHost::~ExtensionDevToolsClientHost() { | 349 ExtensionDevToolsClientHost::~ExtensionDevToolsClientHost() { |
| 352 // Ensure calling RemoveInfoBar() below won't result in Observe() trying to | 350 // Ensure calling RemoveInfoBar() below won't result in Observe() trying to |
| 353 // Close() us. | 351 // Close() us. |
| 354 registrar_.RemoveAll(); | 352 registrar_.RemoveAll(); |
| 355 | 353 |
| 356 if (infobar_) { | 354 if (infobar_) { |
| 357 static_cast<ExtensionDevToolsInfoBarDelegate*>( | 355 static_cast<ExtensionDevToolsInfoBarDelegate*>( |
| 358 infobar_->delegate())->set_client_host(NULL); | 356 infobar_->delegate())->set_client_host(NULL); |
| 359 InfoBarService* infobar_service = | 357 InfoBarService* infobar_service = |
| 360 InfoBarService::FromWebContents(agent_host_->GetWebContents()); | 358 InfoBarService::FromWebContents(agent_host_->GetWebContents()); |
| 361 infobar_service->RemoveInfoBar(infobar_); | 359 infobar_service->RemoveInfoBar(infobar_); |
| 362 } | 360 } |
| 363 AttachedClientHosts::GetInstance()->Remove(this); | 361 AttachedClientHosts::GetInstance()->Remove(this); |
| 364 } | 362 } |
| 365 | 363 |
| 366 // DevToolsClientHost interface | 364 // DevToolsAgentHostClient implementation. |
| 367 void ExtensionDevToolsClientHost::InspectedContentsClosing() { | 365 void ExtensionDevToolsClientHost::AgentHostClosed( |
| 366 DevToolsAgentHost* agent_host, bool replaced_with_another_client) { |
| 367 DCHECK(agent_host == agent_host_.get()); |
| 368 if (replaced_with_another_client) |
| 369 detach_reason_ = OnDetach::REASON_REPLACED_WITH_DEVTOOLS; |
| 368 SendDetachedEvent(); | 370 SendDetachedEvent(); |
| 369 delete this; | 371 delete this; |
| 370 } | 372 } |
| 371 | 373 |
| 372 void ExtensionDevToolsClientHost::ReplacedWithAnotherClient() { | |
| 373 detach_reason_ = OnDetach::REASON_REPLACED_WITH_DEVTOOLS; | |
| 374 } | |
| 375 | |
| 376 void ExtensionDevToolsClientHost::Close() { | 374 void ExtensionDevToolsClientHost::Close() { |
| 377 DevToolsManager::GetInstance()->ClientHostClosing(this); | 375 agent_host_->DetachClient(); |
| 378 delete this; | 376 delete this; |
| 379 } | 377 } |
| 380 | 378 |
| 381 void ExtensionDevToolsClientHost::SendMessageToBackend( | 379 void ExtensionDevToolsClientHost::SendMessageToBackend( |
| 382 DebuggerSendCommandFunction* function, | 380 DebuggerSendCommandFunction* function, |
| 383 const std::string& method, | 381 const std::string& method, |
| 384 SendCommand::Params::CommandParams* command_params) { | 382 SendCommand::Params::CommandParams* command_params) { |
| 385 base::DictionaryValue protocol_request; | 383 base::DictionaryValue protocol_request; |
| 386 int request_id = ++last_request_id_; | 384 int request_id = ++last_request_id_; |
| 387 pending_requests_[request_id] = function; | 385 pending_requests_[request_id] = function; |
| 388 protocol_request.SetInteger("id", request_id); | 386 protocol_request.SetInteger("id", request_id); |
| 389 protocol_request.SetString("method", method); | 387 protocol_request.SetString("method", method); |
| 390 if (command_params) { | 388 if (command_params) { |
| 391 protocol_request.Set("params", | 389 protocol_request.Set("params", |
| 392 command_params->additional_properties.DeepCopy()); | 390 command_params->additional_properties.DeepCopy()); |
| 393 } | 391 } |
| 394 | 392 |
| 395 std::string json_args; | 393 std::string json_args; |
| 396 base::JSONWriter::Write(&protocol_request, &json_args); | 394 base::JSONWriter::Write(&protocol_request, &json_args); |
| 397 DevToolsManager::GetInstance()->DispatchOnInspectorBackend(this, json_args); | 395 agent_host_->DispatchProtocolMessage(json_args); |
| 398 } | 396 } |
| 399 | 397 |
| 400 void ExtensionDevToolsClientHost::MarkAsDismissed() { | 398 void ExtensionDevToolsClientHost::MarkAsDismissed() { |
| 401 detach_reason_ = OnDetach::REASON_CANCELED_BY_USER; | 399 detach_reason_ = OnDetach::REASON_CANCELED_BY_USER; |
| 402 } | 400 } |
| 403 | 401 |
| 404 void ExtensionDevToolsClientHost::SendDetachedEvent() { | 402 void ExtensionDevToolsClientHost::SendDetachedEvent() { |
| 405 if (!EventRouter::Get(profile_)) | 403 if (!EventRouter::Get(profile_)) |
| 406 return; | 404 return; |
| 407 | 405 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 435 infobar_ = NULL; | 433 infobar_ = NULL; |
| 436 SendDetachedEvent(); | 434 SendDetachedEvent(); |
| 437 Close(); | 435 Close(); |
| 438 } | 436 } |
| 439 break; | 437 break; |
| 440 default: | 438 default: |
| 441 NOTREACHED(); | 439 NOTREACHED(); |
| 442 } | 440 } |
| 443 } | 441 } |
| 444 | 442 |
| 445 void ExtensionDevToolsClientHost::DispatchOnInspectorFrontend( | 443 void ExtensionDevToolsClientHost::DispatchProtocolMessage( |
| 446 const std::string& message) { | 444 DevToolsAgentHost* agent_host, const std::string& message) { |
| 445 DCHECK(agent_host == agent_host_.get()); |
| 447 if (!EventRouter::Get(profile_)) | 446 if (!EventRouter::Get(profile_)) |
| 448 return; | 447 return; |
| 449 | 448 |
| 450 scoped_ptr<base::Value> result(base::JSONReader::Read(message)); | 449 scoped_ptr<base::Value> result(base::JSONReader::Read(message)); |
| 451 if (!result->IsType(base::Value::TYPE_DICTIONARY)) | 450 if (!result->IsType(base::Value::TYPE_DICTIONARY)) |
| 452 return; | 451 return; |
| 453 base::DictionaryValue* dictionary = | 452 base::DictionaryValue* dictionary = |
| 454 static_cast<base::DictionaryValue*>(result.get()); | 453 static_cast<base::DictionaryValue*>(result.get()); |
| 455 | 454 |
| 456 int id; | 455 int id; |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 741 const std::vector<DevToolsTargetImpl*>& target_list) { | 740 const std::vector<DevToolsTargetImpl*>& target_list) { |
| 742 scoped_ptr<base::ListValue> result(new base::ListValue()); | 741 scoped_ptr<base::ListValue> result(new base::ListValue()); |
| 743 for (size_t i = 0; i < target_list.size(); ++i) | 742 for (size_t i = 0; i < target_list.size(); ++i) |
| 744 result->Append(SerializeTarget(*target_list[i])); | 743 result->Append(SerializeTarget(*target_list[i])); |
| 745 STLDeleteContainerPointers(target_list.begin(), target_list.end()); | 744 STLDeleteContainerPointers(target_list.begin(), target_list.end()); |
| 746 SetResult(result.release()); | 745 SetResult(result.release()); |
| 747 SendResponse(true); | 746 SendResponse(true); |
| 748 } | 747 } |
| 749 | 748 |
| 750 } // namespace extensions | 749 } // namespace extensions |
| OLD | NEW |