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" |
34 #include "content/public/browser/devtools_http_handler.h" | 35 #include "content/public/browser/devtools_http_handler.h" |
| 36 #include "content/public/browser/devtools_manager.h" |
35 #include "content/public/browser/notification_service.h" | 37 #include "content/public/browser/notification_service.h" |
36 #include "content/public/browser/notification_source.h" | 38 #include "content/public/browser/notification_source.h" |
37 #include "content/public/browser/render_process_host.h" | 39 #include "content/public/browser/render_process_host.h" |
38 #include "content/public/browser/render_view_host.h" | 40 #include "content/public/browser/render_view_host.h" |
39 #include "content/public/browser/render_widget_host.h" | 41 #include "content/public/browser/render_widget_host.h" |
40 #include "content/public/browser/web_contents.h" | 42 #include "content/public/browser/web_contents.h" |
41 #include "content/public/common/content_client.h" | 43 #include "content/public/common/content_client.h" |
42 #include "content/public/common/url_utils.h" | 44 #include "content/public/common/url_utils.h" |
43 #include "extensions/browser/event_router.h" | 45 #include "extensions/browser/event_router.h" |
44 #include "extensions/browser/extension_host.h" | 46 #include "extensions/browser/extension_host.h" |
45 #include "extensions/browser/extension_registry.h" | 47 #include "extensions/browser/extension_registry.h" |
46 #include "extensions/browser/extension_registry_observer.h" | 48 #include "extensions/browser/extension_registry_observer.h" |
47 #include "extensions/browser/extension_system.h" | 49 #include "extensions/browser/extension_system.h" |
48 #include "extensions/common/constants.h" | 50 #include "extensions/common/constants.h" |
49 #include "extensions/common/error_utils.h" | 51 #include "extensions/common/error_utils.h" |
50 #include "extensions/common/extension.h" | 52 #include "extensions/common/extension.h" |
51 #include "extensions/common/manifest_constants.h" | 53 #include "extensions/common/manifest_constants.h" |
52 #include "extensions/common/permissions/permissions_data.h" | 54 #include "extensions/common/permissions/permissions_data.h" |
53 #include "extensions/common/switches.h" | 55 #include "extensions/common/switches.h" |
54 #include "grit/generated_resources.h" | 56 #include "grit/generated_resources.h" |
55 #include "ui/base/l10n/l10n_util.h" | 57 #include "ui/base/l10n/l10n_util.h" |
56 | 58 |
57 using content::DevToolsAgentHost; | 59 using content::DevToolsAgentHost; |
| 60 using content::DevToolsClientHost; |
58 using content::DevToolsHttpHandler; | 61 using content::DevToolsHttpHandler; |
| 62 using content::DevToolsManager; |
59 using content::RenderProcessHost; | 63 using content::RenderProcessHost; |
60 using content::RenderViewHost; | 64 using content::RenderViewHost; |
61 using content::RenderWidgetHost; | 65 using content::RenderWidgetHost; |
62 using content::WebContents; | 66 using content::WebContents; |
63 | 67 |
64 namespace keys = debugger_api_constants; | 68 namespace keys = debugger_api_constants; |
65 namespace Attach = extensions::api::debugger::Attach; | 69 namespace Attach = extensions::api::debugger::Attach; |
66 namespace Detach = extensions::api::debugger::Detach; | 70 namespace Detach = extensions::api::debugger::Detach; |
67 namespace OnDetach = extensions::api::debugger::OnDetach; | 71 namespace OnDetach = extensions::api::debugger::OnDetach; |
68 namespace OnEvent = extensions::api::debugger::OnEvent; | 72 namespace OnEvent = extensions::api::debugger::OnEvent; |
69 namespace SendCommand = extensions::api::debugger::SendCommand; | 73 namespace SendCommand = extensions::api::debugger::SendCommand; |
70 | 74 |
71 namespace extensions { | 75 namespace extensions { |
72 class ExtensionRegistry; | 76 class ExtensionRegistry; |
73 | 77 |
74 // ExtensionDevToolsClientHost ------------------------------------------------ | 78 // ExtensionDevToolsClientHost ------------------------------------------------ |
75 | 79 |
76 class ExtensionDevToolsClientHost : public content::DevToolsAgentHostClient, | 80 class ExtensionDevToolsClientHost : public DevToolsClientHost, |
77 public content::NotificationObserver, | 81 public content::NotificationObserver, |
78 public ExtensionRegistryObserver { | 82 public ExtensionRegistryObserver { |
79 public: | 83 public: |
80 ExtensionDevToolsClientHost(Profile* profile, | 84 ExtensionDevToolsClientHost(Profile* profile, |
81 DevToolsAgentHost* agent_host, | 85 DevToolsAgentHost* agent_host, |
82 const std::string& extension_id, | 86 const std::string& extension_id, |
83 const std::string& extension_name, | 87 const std::string& extension_name, |
84 const Debuggee& debuggee, | 88 const Debuggee& debuggee, |
85 infobars::InfoBar* infobar); | 89 infobars::InfoBar* infobar); |
86 | 90 |
87 virtual ~ExtensionDevToolsClientHost(); | 91 virtual ~ExtensionDevToolsClientHost(); |
88 | 92 |
89 const std::string& extension_id() { return extension_id_; } | 93 const std::string& extension_id() { return extension_id_; } |
90 DevToolsAgentHost* agent_host() { return agent_host_.get(); } | |
91 void Close(); | 94 void Close(); |
92 void SendMessageToBackend(DebuggerSendCommandFunction* function, | 95 void SendMessageToBackend(DebuggerSendCommandFunction* function, |
93 const std::string& method, | 96 const std::string& method, |
94 SendCommand::Params::CommandParams* command_params); | 97 SendCommand::Params::CommandParams* command_params); |
95 | 98 |
96 // Marks connection as to-be-terminated by the user. | 99 // Marks connection as to-be-terminated by the user. |
97 void MarkAsDismissed(); | 100 void MarkAsDismissed(); |
98 | 101 |
99 // DevToolsAgentHostClient interface. | 102 // DevToolsClientHost interface |
100 virtual void AgentHostClosed( | 103 virtual void InspectedContentsClosing() OVERRIDE; |
101 DevToolsAgentHost* agent_host, | 104 virtual void DispatchOnInspectorFrontend(const std::string& message) OVERRIDE; |
102 bool replaced_with_another_client) OVERRIDE; | 105 virtual void ReplacedWithAnotherClient() 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(); |
292 for (ClientHosts::iterator it = client_hosts_.begin(); | 293 for (ClientHosts::iterator it = client_hosts_.begin(); |
293 it != client_hosts_.end(); ++it) { | 294 it != client_hosts_.end(); ++it) { |
294 ExtensionDevToolsClientHost* client_host = *it; | 295 ExtensionDevToolsClientHost* client_host = *it; |
295 if (client_host->agent_host() == agent_host && | 296 if (manager->GetDevToolsAgentHostFor(client_host) == agent_host && |
296 client_host->extension_id() == extension_id) | 297 client_host->extension_id() == extension_id) |
297 return client_host; | 298 return client_host; |
298 } | 299 } |
299 return NULL; | 300 return NULL; |
300 } | 301 } |
301 | 302 |
302 } // namespace | 303 } // namespace |
303 | 304 |
304 | 305 |
305 // ExtensionDevToolsClientHost ------------------------------------------------ | 306 // ExtensionDevToolsClientHost ------------------------------------------------ |
(...skipping 20 matching lines...) Expand all Loading... |
326 // from there. | 327 // from there. |
327 extension_registry_observer_.Add(ExtensionRegistry::Get(profile_)); | 328 extension_registry_observer_.Add(ExtensionRegistry::Get(profile_)); |
328 | 329 |
329 // RVH-based agents disconnect from their clients when the app is terminating | 330 // RVH-based agents disconnect from their clients when the app is terminating |
330 // but shared worker-based agents do not. | 331 // but shared worker-based agents do not. |
331 // Disconnect explicitly to make sure that |this| observer is not leaked. | 332 // Disconnect explicitly to make sure that |this| observer is not leaked. |
332 registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, | 333 registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, |
333 content::NotificationService::AllSources()); | 334 content::NotificationService::AllSources()); |
334 | 335 |
335 // Attach to debugger and tell it we are ready. | 336 // Attach to debugger and tell it we are ready. |
336 agent_host_->AttachClient(this); | 337 DevToolsManager::GetInstance()->RegisterDevToolsClientHostFor( |
| 338 agent_host_.get(), this); |
337 | 339 |
338 if (infobar_) { | 340 if (infobar_) { |
339 static_cast<ExtensionDevToolsInfoBarDelegate*>( | 341 static_cast<ExtensionDevToolsInfoBarDelegate*>( |
340 infobar_->delegate())->set_client_host(this); | 342 infobar_->delegate())->set_client_host(this); |
341 registrar_.Add( | 343 registrar_.Add( |
342 this, | 344 this, |
343 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, | 345 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, |
344 content::Source<InfoBarService>( | 346 content::Source<InfoBarService>( |
345 InfoBarService::FromWebContents(agent_host_->GetWebContents()))); | 347 InfoBarService::FromWebContents(agent_host_->GetWebContents()))); |
346 } | 348 } |
347 } | 349 } |
348 | 350 |
349 ExtensionDevToolsClientHost::~ExtensionDevToolsClientHost() { | 351 ExtensionDevToolsClientHost::~ExtensionDevToolsClientHost() { |
350 // Ensure calling RemoveInfoBar() below won't result in Observe() trying to | 352 // Ensure calling RemoveInfoBar() below won't result in Observe() trying to |
351 // Close() us. | 353 // Close() us. |
352 registrar_.RemoveAll(); | 354 registrar_.RemoveAll(); |
353 | 355 |
354 if (infobar_) { | 356 if (infobar_) { |
355 static_cast<ExtensionDevToolsInfoBarDelegate*>( | 357 static_cast<ExtensionDevToolsInfoBarDelegate*>( |
356 infobar_->delegate())->set_client_host(NULL); | 358 infobar_->delegate())->set_client_host(NULL); |
357 InfoBarService* infobar_service = | 359 InfoBarService* infobar_service = |
358 InfoBarService::FromWebContents(agent_host_->GetWebContents()); | 360 InfoBarService::FromWebContents(agent_host_->GetWebContents()); |
359 infobar_service->RemoveInfoBar(infobar_); | 361 infobar_service->RemoveInfoBar(infobar_); |
360 } | 362 } |
361 AttachedClientHosts::GetInstance()->Remove(this); | 363 AttachedClientHosts::GetInstance()->Remove(this); |
362 } | 364 } |
363 | 365 |
364 // DevToolsAgentHostClient implementation. | 366 // DevToolsClientHost interface |
365 void ExtensionDevToolsClientHost::AgentHostClosed( | 367 void ExtensionDevToolsClientHost::InspectedContentsClosing() { |
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; | |
370 SendDetachedEvent(); | 368 SendDetachedEvent(); |
371 delete this; | 369 delete this; |
372 } | 370 } |
373 | 371 |
| 372 void ExtensionDevToolsClientHost::ReplacedWithAnotherClient() { |
| 373 detach_reason_ = OnDetach::REASON_REPLACED_WITH_DEVTOOLS; |
| 374 } |
| 375 |
374 void ExtensionDevToolsClientHost::Close() { | 376 void ExtensionDevToolsClientHost::Close() { |
375 agent_host_->DetachClient(); | 377 DevToolsManager::GetInstance()->ClientHostClosing(this); |
376 delete this; | 378 delete this; |
377 } | 379 } |
378 | 380 |
379 void ExtensionDevToolsClientHost::SendMessageToBackend( | 381 void ExtensionDevToolsClientHost::SendMessageToBackend( |
380 DebuggerSendCommandFunction* function, | 382 DebuggerSendCommandFunction* function, |
381 const std::string& method, | 383 const std::string& method, |
382 SendCommand::Params::CommandParams* command_params) { | 384 SendCommand::Params::CommandParams* command_params) { |
383 base::DictionaryValue protocol_request; | 385 base::DictionaryValue protocol_request; |
384 int request_id = ++last_request_id_; | 386 int request_id = ++last_request_id_; |
385 pending_requests_[request_id] = function; | 387 pending_requests_[request_id] = function; |
386 protocol_request.SetInteger("id", request_id); | 388 protocol_request.SetInteger("id", request_id); |
387 protocol_request.SetString("method", method); | 389 protocol_request.SetString("method", method); |
388 if (command_params) { | 390 if (command_params) { |
389 protocol_request.Set("params", | 391 protocol_request.Set("params", |
390 command_params->additional_properties.DeepCopy()); | 392 command_params->additional_properties.DeepCopy()); |
391 } | 393 } |
392 | 394 |
393 std::string json_args; | 395 std::string json_args; |
394 base::JSONWriter::Write(&protocol_request, &json_args); | 396 base::JSONWriter::Write(&protocol_request, &json_args); |
395 agent_host_->DispatchProtocolMessage(json_args); | 397 DevToolsManager::GetInstance()->DispatchOnInspectorBackend(this, json_args); |
396 } | 398 } |
397 | 399 |
398 void ExtensionDevToolsClientHost::MarkAsDismissed() { | 400 void ExtensionDevToolsClientHost::MarkAsDismissed() { |
399 detach_reason_ = OnDetach::REASON_CANCELED_BY_USER; | 401 detach_reason_ = OnDetach::REASON_CANCELED_BY_USER; |
400 } | 402 } |
401 | 403 |
402 void ExtensionDevToolsClientHost::SendDetachedEvent() { | 404 void ExtensionDevToolsClientHost::SendDetachedEvent() { |
403 if (!EventRouter::Get(profile_)) | 405 if (!EventRouter::Get(profile_)) |
404 return; | 406 return; |
405 | 407 |
(...skipping 27 matching lines...) Expand all Loading... |
433 infobar_ = NULL; | 435 infobar_ = NULL; |
434 SendDetachedEvent(); | 436 SendDetachedEvent(); |
435 Close(); | 437 Close(); |
436 } | 438 } |
437 break; | 439 break; |
438 default: | 440 default: |
439 NOTREACHED(); | 441 NOTREACHED(); |
440 } | 442 } |
441 } | 443 } |
442 | 444 |
443 void ExtensionDevToolsClientHost::DispatchProtocolMessage( | 445 void ExtensionDevToolsClientHost::DispatchOnInspectorFrontend( |
444 DevToolsAgentHost* agent_host, const std::string& message) { | 446 const std::string& message) { |
445 DCHECK(agent_host == agent_host_.get()); | |
446 if (!EventRouter::Get(profile_)) | 447 if (!EventRouter::Get(profile_)) |
447 return; | 448 return; |
448 | 449 |
449 scoped_ptr<base::Value> result(base::JSONReader::Read(message)); | 450 scoped_ptr<base::Value> result(base::JSONReader::Read(message)); |
450 if (!result->IsType(base::Value::TYPE_DICTIONARY)) | 451 if (!result->IsType(base::Value::TYPE_DICTIONARY)) |
451 return; | 452 return; |
452 base::DictionaryValue* dictionary = | 453 base::DictionaryValue* dictionary = |
453 static_cast<base::DictionaryValue*>(result.get()); | 454 static_cast<base::DictionaryValue*>(result.get()); |
454 | 455 |
455 int id; | 456 int id; |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
740 const std::vector<DevToolsTargetImpl*>& target_list) { | 741 const std::vector<DevToolsTargetImpl*>& target_list) { |
741 scoped_ptr<base::ListValue> result(new base::ListValue()); | 742 scoped_ptr<base::ListValue> result(new base::ListValue()); |
742 for (size_t i = 0; i < target_list.size(); ++i) | 743 for (size_t i = 0; i < target_list.size(); ++i) |
743 result->Append(SerializeTarget(*target_list[i])); | 744 result->Append(SerializeTarget(*target_list[i])); |
744 STLDeleteContainerPointers(target_list.begin(), target_list.end()); | 745 STLDeleteContainerPointers(target_list.begin(), target_list.end()); |
745 SetResult(result.release()); | 746 SetResult(result.release()); |
746 SendResponse(true); | 747 SendResponse(true); |
747 } | 748 } |
748 | 749 |
749 } // namespace extensions | 750 } // namespace extensions |
OLD | NEW |