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 |